From 306929b8d322a1490874f948117bfd8fe09d9b8e Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Tue, 13 Jan 2026 21:11:44 +0000 Subject: [PATCH] its all events LETS GO - I still need to make it be all events --- tui/internal/controllers/layout.go | 39 ++++++++ tui/internal/controllers/mainc.go | 38 +++++++ tui/internal/controllers/windowing.go | 55 ----------- tui/internal/events/events.go | 13 --- tui/internal/models/devices.go | 7 ++ tui/internal/tui/tui.go | 61 +++--------- tui/internal/ui/events.go | 43 ++++++++ tui/internal/views/aux.go | 5 +- tui/internal/views/layoutTool.go | 137 +++++++++++++++++--------- tui/internal/views/mainFlex.go | 29 +++--- tui/internal/views/outputWin.go | 20 +++- tui/tui.go | 5 +- 12 files changed, 263 insertions(+), 189 deletions(-) create mode 100644 tui/internal/controllers/layout.go delete mode 100644 tui/internal/controllers/windowing.go delete mode 100644 tui/internal/events/events.go create mode 100644 tui/internal/models/devices.go create mode 100644 tui/internal/ui/events.go diff --git a/tui/internal/controllers/layout.go b/tui/internal/controllers/layout.go new file mode 100644 index 0000000..867079c --- /dev/null +++ b/tui/internal/controllers/layout.go @@ -0,0 +1,39 @@ +// Package controllers +package controllers + +import ( + "fmt" + + "esdi/tui/internal/events" + "esdi/tui/internal/models" + "esdi/tui/internal/ui" +) + +type LayoutController struct { + EvBus *events.Bus +} + +func NewLayoutController(bus *events.Bus) *LayoutController { + lc := &LayoutController{ + EvBus: bus, + } + + bus.On(ui.CreateWindowEv{}, func(e any) { + ev := e.(ui.CreateWindowEv) + lc.createWindow(ev.Window) + }) + + return lc +} + +func (lc *LayoutController) createWindow(win models.Window) { + lc.EvBus.Emit(ui.LogEv{ + Log: fmt.Sprintf("x : %d\n"+ + "y : %d\n"+ + "width : %d\n"+ + "height: %d\n"+ + "title : %s\n", win.X, win.Y, win.Width, win.Height, win.Title), + }) + + lc.EvBus.Emit(ui.WindowCreatedEv{Window: win}) +} diff --git a/tui/internal/controllers/mainc.go b/tui/internal/controllers/mainc.go index 097da54..4d33012 100644 --- a/tui/internal/controllers/mainc.go +++ b/tui/internal/controllers/mainc.go @@ -1,5 +1,43 @@ // Package controllers defines our controller layer package controllers +import ( + "esdi/tui/internal/dom" + "esdi/tui/internal/events" + "esdi/tui/internal/ui" + + "github.com/rivo/tview" +) + +type Ctrls struct { + MC *MainController + WindowingController *LayoutController +} + type MainController struct { + App *tview.Application + Dom *dom.DOM + EvBus *events.Bus +} + +func NewMainController() *MainController { + mc := &MainController{ + App: tview.NewApplication(), + Dom: dom.NewDOM(), + EvBus: events.NewBus(), + } + + mc.EvBus.On(ui.RedrawEv{}, func(e any) { + mc.App.QueueUpdateDraw(func() {}) + }) + + mc.EvBus.On(ui.ChangeFocusEv{}, func(e any) { + mc.App.SetFocus(e.(ui.ChangeFocusEv).Target) + }) + + mc.EvBus.On(ui.LogEv{}, func(e any) { + mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log}) + }) + + return mc } diff --git a/tui/internal/controllers/windowing.go b/tui/internal/controllers/windowing.go deleted file mode 100644 index e76a464..0000000 --- a/tui/internal/controllers/windowing.go +++ /dev/null @@ -1,55 +0,0 @@ -// Package controllers -package controllers - -import ( - "esdi/tui/internal/events" - "esdi/tui/internal/models" - "esdi/tui/internal/ui" - "strconv" -) - -type WindowingController struct { - Ctx *ui.UIContext - Events *events.Bus -} - -func (wc *WindowingController) CreateWindow(x, y, - width, height, title string) { - wc.Ctx.Log("x : %s\n", x) - wc.Ctx.Log("y : %s\n", y) - wc.Ctx.Log("width : %s\n", width) - wc.Ctx.Log("height: %s\n", height) - wc.Ctx.Log("title : %s\n", title) - // newWindow := tview.NewTreeNode(title) - - xValue, err := strconv.ParseUint(x, 10, 64) - if err != nil { - wc.Events.Emit(events.Error{Error: err}) - return - } - yValue, err := strconv.ParseUint(y, 10, 64) - if err != nil { - wc.Events.Emit(events.Error{Error: err}) - return - } - widthValue, err := strconv.ParseUint(width, 10, 64) - if err != nil { - wc.Events.Emit(events.Error{Error: err}) - return - } - heightValue, err := strconv.ParseUint(height, 10, 64) - if err != nil { - wc.Events.Emit(events.Error{Error: err}) - return - } - - window := models.Window{ - X: uint16(xValue), - Y: uint16(yValue), - Width: uint16(widthValue), - Height: uint16(heightValue), - Title: title, - } - - wc.Events.Emit(events.WindowCreated{Window: window}) -} diff --git a/tui/internal/events/events.go b/tui/internal/events/events.go deleted file mode 100644 index 3e78b95..0000000 --- a/tui/internal/events/events.go +++ /dev/null @@ -1,13 +0,0 @@ -package events - -import ( - "esdi/tui/internal/models" -) - -type Error struct { - Error error -} - -type WindowCreated struct { - Window models.Window -} diff --git a/tui/internal/models/devices.go b/tui/internal/models/devices.go new file mode 100644 index 0000000..c1a5f7a --- /dev/null +++ b/tui/internal/models/devices.go @@ -0,0 +1,7 @@ +package models + +import "esdi/peripheral" + +type DevicesTUI struct { + Serial *peripheral.PeripheralDeviceClerk +} diff --git a/tui/internal/tui/tui.go b/tui/internal/tui/tui.go index f4ca56f..f4da818 100644 --- a/tui/internal/tui/tui.go +++ b/tui/internal/tui/tui.go @@ -3,91 +3,54 @@ package tui import ( "esdi/tui/internal/controllers" - "esdi/tui/internal/dom" - "esdi/tui/internal/events" - "esdi/tui/internal/ui" "esdi/tui/internal/views" "fmt" "github.com/gdamore/tcell/v2" - "github.com/rivo/tview" ) -type TUI struct { - App *tview.Application - Dom *dom.DOM - Events *events.Bus -} - -func NewTUI() *TUI { - return &TUI{ - App: tview.NewApplication(), - Dom: dom.NewDOM(), - Events: events.NewBus(), - } -} - -func (t *TUI) log(formatter string, args ...any) { - outputWin := t.Dom.GetElemByID("output-window").(*tview.TextView) - fmt.Fprintf(outputWin, formatter, args...) -} - -func (t *TUI) Start() error { +func Start() error { // The app starts running here! // // Set the event capture for the global app itself here - t.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + mc := controllers.NewMainController() + + mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' { - t.App.Stop() + mc.App.Stop() return nil } return event }) - ctx := &ui.UIContext{ - Redraw: func() { - t.App.QueueUpdateDraw(func() {}) - }, - Log: func(formatter string, args ...any) { - t.log(formatter, args...) - }, - ChangeFocus: func(p tview.Primitive) { - t.App.SetFocus(p) - }, - } - - // Create the controllers - windowingController := &controllers.WindowingController{ - Events: t.Events, - Ctx: ctx, - } + controllers.NewLayoutController(mc.EvBus) // Make the output window - err := views.BuildOutputWindow(t.Dom, ctx) + err := views.BuildOutputWindow(mc.EvBus, mc.Dom) if err != nil { panic("failed to create output window") } // Set the main view - mainUINode, err := views.BuildMainFlex(t.Dom, ctx, windowingController) + mainUINode, err := views.BuildMainFlex(mc.EvBus, mc.Dom) if err != nil { panic(fmt.Errorf("failed to build main flex - %s", err.Error())) } - rootNode, err := t.Dom.NewUINode("root", nil, mainUINode) + rootNode, err := mc.Dom.NewUINode("root", nil, mainUINode) if err != nil { panic(fmt.Errorf("failed to create root node - %s", err.Error())) } - t.Dom.SetRoot(rootNode) - firstFocus := t.Dom.GetElemByID("device-api-list") + mc.Dom.SetRoot(rootNode) + firstFocus := mc.Dom.GetElemByID("device-api-list") if firstFocus == nil { panic(fmt.Errorf("`list-window` isn't registered")) } // Star the app - err = t.App.SetRoot(t.Dom.GetRootElem(), true).SetFocus(firstFocus).Run() + err = mc.App.SetRoot(mc.Dom.GetRootElem(), true).SetFocus(firstFocus).Run() if err != nil { return err } diff --git a/tui/internal/ui/events.go b/tui/internal/ui/events.go new file mode 100644 index 0000000..12dfb90 --- /dev/null +++ b/tui/internal/ui/events.go @@ -0,0 +1,43 @@ +package ui + +import ( + "esdi/tui/internal/models" + + "github.com/rivo/tview" +) + +// Main controller events + +type LogEv struct { + Log string +} + +type PrintLogEv struct { + Log string +} + +type RedrawEv struct{} + +type ChangeFocusEv struct { + Target tview.Primitive +} + +// ---------------------------------------------------------------------------- + +// Layout events + +type CreateWindowEv struct { + Window models.Window +} + +type WindowCreatedEv struct { + Window models.Window +} + +type ErrorCreateWindowEv struct { + Error error +} + +type ErrorFormParseEv struct { + Error error +} diff --git a/tui/internal/views/aux.go b/tui/internal/views/aux.go index 28f911e..135605e 100644 --- a/tui/internal/views/aux.go +++ b/tui/internal/views/aux.go @@ -2,13 +2,14 @@ package views import ( "esdi/tui/internal/dom" + "esdi/tui/internal/events" "esdi/tui/internal/ui" "slices" "github.com/rivo/tview" ) -func AddAndShowPage(root *dom.DOM, ctx *ui.UIContext, +func AddAndShowPage(bus *events.Bus, doc *dom.DOM, pages *tview.Pages, page *dom.UINode) error { if !slices.Contains(pages.GetPageNames(false), page.ID) { pages.AddAndSwitchToPage(page.ID, page.Self, true) @@ -18,7 +19,7 @@ func AddAndShowPage(root *dom.DOM, ctx *ui.UIContext, } // Set focus to our new tool - ctx.ChangeFocus(page.Self) + bus.Emit(ui.ChangeFocusEv{Target: page.Self}) return nil } diff --git a/tui/internal/views/layoutTool.go b/tui/internal/views/layoutTool.go index 220790c..d368408 100644 --- a/tui/internal/views/layoutTool.go +++ b/tui/internal/views/layoutTool.go @@ -1,10 +1,12 @@ package views import ( - "esdi/tui/internal/controllers" "esdi/tui/internal/dom" "esdi/tui/internal/events" + "esdi/tui/internal/models" "esdi/tui/internal/ui" + "fmt" + "strconv" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" @@ -17,40 +19,42 @@ const ( ) func BindWindowEvents( - ctx *ui.UIContext, bus *events.Bus, + doc *dom.DOM, tree *tview.TreeView, ) { // I recon I have to change this for some type os event system that // triggers directly on the UINodes I want them to be triggered on - bus.On(events.WindowCreated{}, func(e any) { - ctx.Log("Received a window created event\n") + bus.On(ui.WindowCreatedEv{}, func(e any) { + bus.Emit(ui.LogEv{Log: "Received a window created event\n"}) if tree == nil { - ctx.Log("tree view is nil") + bus.Emit(ui.LogEv{Log: "tree view is nil"}) return } root := tree.GetRoot() if root == nil { - ctx.Log("unable to get root of tree view") + bus.Emit(ui.LogEv{Log: "unable to get root of tree view"}) return } - newWindow := tview.NewTreeNode(e.(events.WindowCreated).Window.Title) + newWindow := tview.NewTreeNode(e.(ui.WindowCreatedEv).Window.Title) root.AddChild(newWindow) }) - bus.On(events.Error{}, func(e any) { - ctx.Log("Error performing action: %s\n", e.(events.Error).Error.Error()) + bus.On(ui.ErrorCreateWindowEv{}, func(e any) { + bus.Emit(ui.LogEv{ + Log: fmt.Sprintf( + "Error performing action: %s\n", e.(ui.ErrorCreateWindowEv).Error.Error(), + )}) }) } -func layoutToolTreeViewEvents(root *dom.DOM, ctx *ui.UIContext, - tree *tview.TreeView, wc *controllers.WindowingController) func( - event *tcell.EventKey) *tcell.EventKey { +func layoutToolTreeViewEvents(bus *events.Bus, doc *dom.DOM, + tree *tview.TreeView) func(event *tcell.EventKey) *tcell.EventKey { return func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyEsc: - ctx.ChangeFocus(root.GetElemByID(deviceAPIListID)) + bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(deviceAPIListID)}) } switch event.Rune() { @@ -59,20 +63,20 @@ func layoutToolTreeViewEvents(root *dom.DOM, ctx *ui.UIContext, // I think I will leave this one for later case 'n': // Create a new window - ctx.Log("calling new window form\n") - createNewWindowForm(root, ctx, wc) + bus.Emit(ui.LogEv{Log: "calling new window form\n"}) + createNewWindowForm(bus, doc) case 'x': // Delete selected window - ctx.Log("calling delete window\n") + bus.Emit(ui.LogEv{Log: "calling delete window\n"}) curNode := tree.GetCurrentNode() if curNode == nil { - ctx.Log("unable to get current tree node") + bus.Emit(ui.LogEv{Log: "unable to get current tree node"}) break } root := tree.GetRoot() if root == nil { - ctx.Log("unable to get current tree node") + bus.Emit(ui.LogEv{Log: "unable to get current tree node"}) break } @@ -87,36 +91,38 @@ func layoutToolTreeViewEvents(root *dom.DOM, ctx *ui.UIContext, } } -func layoutToolUIOnSelect(root *dom.DOM, ctx *ui.UIContext, wc *controllers.WindowingController) { - ctx.Log("Opening layout tool UI\n") +func layoutToolUIOnSelect(bus *events.Bus, doc *dom.DOM) { + bus.Emit(ui.LogEv{Log: "Opening layout tool UI\n"}) var err error // Get the api pages - apiToolPages := root.GetElemByID(apiToolPagesID).(*tview.Pages) + apiToolPages := doc.GetElemByID(apiToolPagesID).(*tview.Pages) if apiToolPages == nil { - ctx.Log(" Failed to retrive apiToolPages UI\n") + bus.Emit(ui.LogEv{Log: " Failed to retrive apiToolPages UI\n"}) return } - ctx.Log(" Checking if `%s` UINode already exists\n", layoutToolFlexID) - layoutToolUINode := root.GetNodeByID(layoutToolFlexID) + bus.Emit(ui.LogEv{ + Log: fmt.Sprintf(" Checking if `%s` UINode already exists\n", layoutToolFlexID), + }) + layoutToolUINode := doc.GetNodeByID(layoutToolFlexID) if layoutToolUINode == nil { - layoutToolUINode, err = buildLayoutFlexComponent(root, ctx, wc) + layoutToolUINode, err = buildLayoutFlexComponent(bus, doc) if err != nil { - ctx.Log(" Failed to build layout tool UI: %s\n", err.Error()) + bus.Emit(ui.LogEv{ + Log: fmt.Sprintf(" Failed to build layout tool UI: %s\n", err.Error()), + }) } } - AddAndShowPage(root, ctx, apiToolPages, layoutToolUINode) + AddAndShowPage(bus, doc, apiToolPages, layoutToolUINode) } -func buildLayoutTreeComponent(doc *dom.DOM, ctx *ui.UIContext, - wc *controllers.WindowingController) (*dom.UINode, error) { - +func buildLayoutTreeComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) { layoutTree := tview.NewTreeView() layoutTree.SetBorder(true).SetTitle("Layout Tree"). - SetInputCapture(layoutToolTreeViewEvents(doc, ctx, layoutTree, wc)) + SetInputCapture(layoutToolTreeViewEvents(bus, doc, layoutTree)) layoutTreeUINode, err := doc.NewUINode(layoutToolTreeID, doc.GetElemByID(rightFlexID), layoutTree) @@ -125,7 +131,7 @@ func buildLayoutTreeComponent(doc *dom.DOM, ctx *ui.UIContext, } // Bind the events for the treeview - BindWindowEvents(ctx, wc.Events, layoutTreeUINode.Self.(*tview.TreeView)) + BindWindowEvents(bus, doc, layoutTreeUINode.Self.(*tview.TreeView)) // Create a root element rootElem := tview.NewTreeNode(".") @@ -134,9 +140,7 @@ func buildLayoutTreeComponent(doc *dom.DOM, ctx *ui.UIContext, return layoutTreeUINode, nil } -func buildLayoutActionPagesComponent(doc *dom.DOM, _ *ui.UIContext, - _ *controllers.WindowingController) (*dom.UINode, error) { - +func buildLayoutActionPagesComponent(_ *events.Bus, doc *dom.DOM) (*dom.UINode, error) { actionPages := tview.NewPages() actionPages.SetBorder(true).SetTitle("Action Page") @@ -150,23 +154,22 @@ func buildLayoutActionPagesComponent(doc *dom.DOM, _ *ui.UIContext, return actionPagesUINode, nil } -func buildLayoutFlexComponent(root *dom.DOM, ctx *ui.UIContext, - wc *controllers.WindowingController) (*dom.UINode, error) { +func buildLayoutFlexComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) { // Want a TreeView at the top - layoutTreeUINode, err := buildLayoutTreeComponent(root, ctx, wc) + layoutTreeUINode, err := buildLayoutTreeComponent(bus, doc) if err != nil { return nil, err } // Want pages below to run actions - actionPagesUINode, err := buildLayoutActionPagesComponent(root, ctx, wc) + actionPagesUINode, err := buildLayoutActionPagesComponent(bus, doc) if err != nil { return nil, err } layoutToolFlex := tview.NewFlex().SetDirection(tview.FlexRow) - layoutToolFlexNode, err := root.NewUINode(layoutToolFlexID, - root.GetElemByID(apiToolPagesID), layoutToolFlex) + layoutToolFlexNode, err := doc.NewUINode(layoutToolFlexID, + doc.GetElemByID(apiToolPagesID), layoutToolFlex) if err != nil { return nil, err } @@ -179,8 +182,36 @@ func buildLayoutFlexComponent(root *dom.DOM, ctx *ui.UIContext, } // Layout tool actions -func createNewWindowForm(root *dom.DOM, ctx *ui.UIContext, - wc *controllers.WindowingController) { + +// Validate the form inputs +func validateFormInputs(x, y, w, h, title string) (models.Window, error) { + xValue, err := strconv.ParseUint(x, 10, 64) + if err != nil { + return models.Window{}, err + } + yValue, err := strconv.ParseUint(y, 10, 64) + if err != nil { + return models.Window{}, err + } + widthValue, err := strconv.ParseUint(w, 10, 64) + if err != nil { + return models.Window{}, err + } + heightValue, err := strconv.ParseUint(h, 10, 64) + if err != nil { + return models.Window{}, err + } + + return models.Window{ + X: uint16(xValue), + Y: uint16(yValue), + Width: uint16(widthValue), + Height: uint16(heightValue), + Title: title, + }, nil +} + +func createNewWindowForm(bus *events.Bus, doc *dom.DOM) { var err error x0 := tview.NewInputField().SetLabel("x") @@ -196,13 +227,21 @@ func createNewWindowForm(root *dom.DOM, ctx *ui.UIContext, AddFormItem(height). AddFormItem(title). AddButton("Create", func() { - wc.CreateWindow( + // Validate the inputs + window, err := validateFormInputs( x0.GetText(), y0.GetText(), width.GetText(), height.GetText(), title.GetText(), ) + + if err != nil { + bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())}) + return + } + + bus.Emit(ui.CreateWindowEv{Window: window}) }) form.SetBorder(true). @@ -211,22 +250,22 @@ func createNewWindowForm(root *dom.DOM, ctx *ui.UIContext, SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { switch ev.Key() { case tcell.KeyEscape: - ctx.ChangeFocus(root.GetElemByID(layoutToolFlexID)) + bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(layoutToolFlexID)}) } return ev }) var formNode *dom.UINode - formNode = root.GetNodeByID("new-window-form") + formNode = doc.GetNodeByID("new-window-form") if formNode == nil { - formNode, err = root.NewUINode("new-window-form", - root.GetElemByID(layoutToolActionPagesID), form) + formNode, err = doc.NewUINode("new-window-form", + doc.GetElemByID(layoutToolActionPagesID), form) if err != nil { panic("failed to create UI node for the new window form: " + err.Error()) } } - AddAndShowPage(root, ctx, root.GetElemByID(layoutToolActionPagesID).(*tview.Pages), + AddAndShowPage(bus, doc, doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages), formNode) } diff --git a/tui/internal/views/mainFlex.go b/tui/internal/views/mainFlex.go index c015ee6..ce92222 100644 --- a/tui/internal/views/mainFlex.go +++ b/tui/internal/views/mainFlex.go @@ -4,8 +4,8 @@ package views import ( "fmt" - "esdi/tui/internal/controllers" "esdi/tui/internal/dom" + "esdi/tui/internal/events" "esdi/tui/internal/ui" "github.com/rivo/tview" @@ -23,12 +23,12 @@ const ( pageName = "empty-page" ) -func buildRightSidePages(root *dom.DOM, ctx *ui.UIContext) (*dom.UINode, error) { +func buildRightSidePages(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) { // We need to build a set of pages with an empty page emptyPage := tview.NewTextView(). SetTextAlign(tview.AlignCenter). SetChangedFunc(func() { - ctx.Redraw() + bus.Emit(ui.RedrawEv{}) }) emptyPage.SetBorder(true).SetTitle("-- Tool Area --") @@ -37,7 +37,7 @@ func buildRightSidePages(root *dom.DOM, ctx *ui.UIContext) (*dom.UINode, error) apiToolPages := tview.NewPages(). AddPage(pageName, emptyPage, true, true) - apiToolPagesNode, err := root.NewUINode(apiToolPagesID, root.GetElemByID(rightFlexID), + apiToolPagesNode, err := doc.NewUINode(apiToolPagesID, doc.GetElemByID(rightFlexID), apiToolPages) if err != nil { return nil, err @@ -46,20 +46,20 @@ func buildRightSidePages(root *dom.DOM, ctx *ui.UIContext) (*dom.UINode, error) return apiToolPagesNode, nil } -func buildRightSideFlex(root *dom.DOM, ctx *ui.UIContext) (*dom.UINode, error) { - apiToolPagesNode, err := buildRightSidePages(root, ctx) +func buildRightSideFlex(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) { + apiToolPagesNode, err := buildRightSidePages(bus, doc) if err != nil { return nil, err } // This will be the right side flex flex := tview.NewFlex().SetDirection(tview.FlexRow) - flexNode, err := root.NewUINode(rightFlexID, root.GetElemByID(mainFlexID), flex) + flexNode, err := doc.NewUINode(rightFlexID, doc.GetElemByID(mainFlexID), flex) if err != nil { return nil, err } - outputWin := root.GetElemByID(outputPaneID) + outputWin := doc.GetElemByID(outputPaneID) if outputWin == nil { panic("failed to attach output win to UI") } @@ -71,30 +71,29 @@ func buildRightSideFlex(root *dom.DOM, ctx *ui.UIContext) (*dom.UINode, error) { return flexNode, nil } -func BuildMainFlex(root *dom.DOM, ctx *ui.UIContext, - wc *controllers.WindowingController) (*tview.Flex, error) { +func BuildMainFlex(bus *events.Bus, doc *dom.DOM) (*tview.Flex, error) { // To build the main view we must set the DOM root mainFlex := tview.NewFlex().SetDirection(tview.FlexColumn) - mainFlexUINode, err := root.NewUINode(mainFlexID, nil, mainFlex) + mainFlexUINode, err := doc.NewUINode(mainFlexID, nil, mainFlex) if err != nil { return nil, err } - root.SetRoot(mainFlexUINode) + doc.SetRoot(mainFlexUINode) deviceAPIList := tview.NewList(). AddItem("layout", "build a layout for CDashDisplay", 0, func() { - layoutToolUIOnSelect(root, ctx, wc) + layoutToolUIOnSelect(bus, doc) }) deviceAPIList.SetBorder(true).SetTitle("list") - apiListWindowUINode, err := root.NewUINode(deviceAPIListID, root.GetRootElem(), + apiListWindowUINode, err := doc.NewUINode(deviceAPIListID, doc.GetRootElem(), deviceAPIList) if err != nil { return nil, err } - rightSideFlex, err := buildRightSideFlex(root, ctx) + rightSideFlex, err := buildRightSideFlex(bus, doc) if err != nil { return nil, err } diff --git a/tui/internal/views/outputWin.go b/tui/internal/views/outputWin.go index 6308b3c..4780b8f 100644 --- a/tui/internal/views/outputWin.go +++ b/tui/internal/views/outputWin.go @@ -2,23 +2,37 @@ package views import ( "esdi/tui/internal/dom" + "esdi/tui/internal/events" "esdi/tui/internal/ui" + "fmt" "github.com/rivo/tview" ) -func BuildOutputWindow(root *dom.DOM, ctx *ui.UIContext) error { +func bindOutputWindowEvents( + bus *events.Bus, + output *tview.TextView, +) { + bus.On(ui.PrintLogEv{}, func(e any) { + le, _ := e.(ui.PrintLogEv) + fmt.Fprintf(output, le.Log) + }) +} + +func BuildOutputWindow(bus *events.Bus, doc *dom.DOM) error { var outputWin *tview.TextView outputWin = tview.NewTextView().SetChangedFunc(func() { - ctx.Redraw() + bus.Emit(ui.RedrawEv{}) outputWin.ScrollToEnd() }) outputWin.SetBorder(true).SetTitle("DebugWindow") - _, err := root.NewUINode("output-window", nil, outputWin) + _, err := doc.NewUINode("output-window", nil, outputWin) if err != nil { return err } + bindOutputWindowEvents(bus, outputWin) + return nil } diff --git a/tui/tui.go b/tui/tui.go index 2dbc207..875640f 100644 --- a/tui/tui.go +++ b/tui/tui.go @@ -1,9 +1,8 @@ // Package tui package tui -import "esdi/tui/internal/tui" +import t "esdi/tui/internal/tui" func Run() error { - app := tui.NewTUI() - return app.Start() + return t.Start() }