From e64b1c31b92f3f3e2a7e1c30f4ef9ffb4a7f6d79 Mon Sep 17 00:00:00 2001 From: Eduardo Silva Date: Tue, 24 Feb 2026 23:22:19 +0000 Subject: [PATCH] chanding the architecure, removing the views ability to emit or listen to events I liked my idea better but I recon I will hit less obstacles this way --- tui/internal/controllers/layout.go | 30 --- tui/internal/controllers/layoutController.go | 5 + tui/internal/controllers/mainc.go | 180 ++++++++++++++---- tui/internal/tui/tui.go | 54 ------ tui/internal/views/aux.go | 9 - tui/internal/views/layoutTool.go | 54 ++---- tui/internal/views/layoutTool_NewWindow.go | 10 +- .../views/layoutTool_WindowManipulation.go | 6 +- tui/internal/views/mainFlex.go | 129 +++++++------ tui/internal/views/outputWin.go | 38 ++-- tui/internal/views/stream.go | 4 +- tui/tui.go | 17 +- 12 files changed, 274 insertions(+), 262 deletions(-) delete mode 100644 tui/internal/controllers/layout.go create mode 100644 tui/internal/controllers/layoutController.go delete mode 100644 tui/internal/tui/tui.go diff --git a/tui/internal/controllers/layout.go b/tui/internal/controllers/layout.go deleted file mode 100644 index 7d83e9a..0000000 --- a/tui/internal/controllers/layout.go +++ /dev/null @@ -1,30 +0,0 @@ -// Package controllers -package controllers - -import ( - "esdi/tui/internal/events" -) - -type LayoutController struct { - EvBus *events.Bus -} - -func NewLayoutController(bus *events.Bus) *LayoutController { - lc := &LayoutController{ - EvBus: bus, - } - - 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{}) -// } diff --git a/tui/internal/controllers/layoutController.go b/tui/internal/controllers/layoutController.go new file mode 100644 index 0000000..7dd6797 --- /dev/null +++ b/tui/internal/controllers/layoutController.go @@ -0,0 +1,5 @@ +package controllers + +type LayoutController struct { + LayoutToolView any +} diff --git a/tui/internal/controllers/mainc.go b/tui/internal/controllers/mainc.go index bb79d74..bc96d28 100644 --- a/tui/internal/controllers/mainc.go +++ b/tui/internal/controllers/mainc.go @@ -8,10 +8,12 @@ import ( "esdi/tui/internal/dom" "esdi/tui/internal/events" "esdi/tui/internal/ui" + "esdi/tui/internal/views" "fmt" "io" "log/slog" + "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) @@ -22,18 +24,18 @@ func mcLog(msg string, args ...any) { } type Ctrls struct { - MC *MainController - WindowingController *LayoutController + MC *MainController } type MainController struct { - Logger *slog.Logger - App *tview.Application - Dom *dom.DOM - EvBus *events.Bus - DevClerk *peripheral.PeripheralDeviceClerk - CDash *cdashdisplay.CDashDisplay - StreamStrl *StreamingCtrl + DeviceAPIView *views.DeviceAPIView + Logger *slog.Logger + App *tview.Application + Dom *dom.DOM + EvBus *events.Bus + DevClerk *peripheral.PeripheralDeviceClerk + CDash *cdashdisplay.CDashDisplay + StreamStrl *StreamingCtrl } func NewMainController(logger *slog.Logger) *MainController { @@ -48,10 +50,12 @@ func NewMainController(logger *slog.Logger) *MainController { } mc.EvBus.On(ui.RedrawEv{}, func(e any) { - rev := e.(ui.RedrawEv) - if rev.Fn != nil { - mc.App.QueueUpdateDraw(e.(ui.RedrawEv).Fn) - } + go func() { + rev := e.(ui.RedrawEv) + if rev.Fn != nil { + mc.App.QueueUpdateDraw(e.(ui.RedrawEv).Fn) + } + }() }) mc.EvBus.On(ui.ChangeFocusEv{}, func(e any) { @@ -59,7 +63,11 @@ func NewMainController(logger *slog.Logger) *MainController { }) mc.EvBus.On(ui.LogEv{}, func(e any) { - mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log}) + go func() { + mc.App.QueueUpdateDraw(func() { + mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log}) + }) + }() }) mc.EvBus.On(ui.CreateWindowEv{}, func(e any) { @@ -166,26 +174,6 @@ func NewMainController(logger *slog.Logger) *MainController { mc.EvBus.Emit(ui.RegisterLoadedLayout{*mc.CDash.State.Layout}) }) - mc.EvBus.On(ui.FindCDashDisplay{}, func(e any) { - go func() { - mc.EvBus.Emit(ui.PrintLogEv{Log: "looking for cdash display\n"}) - pLogger.Info("Looking for CDashDisplay") - - cdashdisplay.SetLogger(pLogger.With("[device]", "cdashdisplay")) - - display, err := cdashdisplay.NewCDashDisplay() - if err != nil { - pLogger.Info("didn't find cdashdisplay") - mc.EvBus.Emit(ui.PrintLogEv{Log: "didn't find cdash display\n"}) - return - } - - mc.CDash = display - pLogger.Info("found cdashdisplay on: " + display.WT.Cfg.Name) - mc.EvBus.Emit(ui.PrintLogEv{Log: "found cdashdisplay on: " + display.WT.Cfg.Name + "\n"}) - }() - }) - mc.EvBus.On(ui.ForceRedraw{}, func(e any) { // mc.App.QueueUpdateDraw(func() {}) mc.App.Draw() @@ -201,3 +189,127 @@ func NewMainController(logger *slog.Logger) *MainController { return mc } + +func (mc *MainController) PrintToOutputWindow(msg string) { + mc.App.QueueUpdateDraw(func() { + fmt.Fprintf(mc.DeviceAPIView.OutputWindow.TextArea, + "%s", msg) + }) +} + +func (mc *MainController) findCDashDisplay() { + mc.PrintToOutputWindow("looking for cdash display\n") + pLogger.Info("Looking for CDashDisplay") + + cdashdisplay.SetLogger(pLogger.With("[device]", "cdashdisplay")) + + display, err := cdashdisplay.NewCDashDisplay() + if err != nil { + pLogger.Info("didn't find cdashdisplay") + mc.PrintToOutputWindow("didn't find cdash display\n") + return + } + + mc.CDash = display + pLogger.Info("found cdashdisplay on: " + display.WT.Cfg.Name) + mc.PrintToOutputWindow("found cdashdisplay on: " + display.WT.Cfg.Name + "\n") +} + +func (mc *MainController) setAppEventCapture() { + mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { + if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' { + mc.App.Stop() + return nil + } + + return event + }) +} + +func (mc *MainController) setDeviceAPIViewEvents() { + mc.DeviceAPIView.MainFlex. + SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { + switch ev.Rune() { + case 'r': + go mc.findCDashDisplay() + } + return ev + }) + +} + +func (mc *MainController) AddDeviceAPIListItems() { + mc.DeviceAPIView.DevAPIList.AddItem("layout", "build a layout for CDashDisplay", + func() { + var err error + + // Get the api pages + apiToolPages := mc.DeviceAPIView.DevAPIToolView + + layoutToolUINode := doc.GetNodeByID(views.LayoutToolFlexID) + if layoutToolUINode == nil { + layoutToolUINode, err = buildLayoutFlexComponent(bus, doc) + if err != nil { + bus.Emit(ui.LogEv{ + Log: fmt.Sprintf(" Failed to build layout tool UI: %s\n", err.Error()), + }) + } + } + + err = views.AddAndShowPage(bus, doc, apiToolPages, layoutToolUINode, true) + if err == nil { + mc.App.SetFocus(e.(ui.ChangeFocusEv).Target) + } + + // Set focus to our new tool + // if changeFocus { + // bus.Emit(ui.ChangeFocusEv{Target: page.Self}) + // } + + }) +} + +func layoutToolUIOnSelect(bus *events.Bus, doc *dom.DOM) { +} + +func (mc *MainController) mainUI() error { + // Set the main view + deviceAPIView, err := views.NewDeviceAPIView(mc.Dom) + if err != nil { + return err + } + + mc.setDeviceAPIViewEvents() + + // Add the API things to the deviceAPIListView + mc.AddDeviceAPIListItems() + + rootNode, err := mc.Dom.NewUINode("root", nil, deviceAPIView.MainFlex) + if err != nil { + return err + } + + mc.DeviceAPIView = deviceAPIView + mc.Dom.SetRoot(rootNode) + + return nil +} + +func (mc *MainController) Main() error { + mc.setAppEventCapture() + err := mc.mainUI() + + // First focused element + firstFocus := mc.Dom.GetElemByID(views.DeviceAPIListID) + if firstFocus == nil { + return err + } + + // Star the app + err = mc.App.SetRoot(mc.Dom.GetRootElem(), true).SetFocus(firstFocus).Run() + if err != nil { + return err + } + + return err +} diff --git a/tui/internal/tui/tui.go b/tui/internal/tui/tui.go deleted file mode 100644 index 5944ef5..0000000 --- a/tui/internal/tui/tui.go +++ /dev/null @@ -1,54 +0,0 @@ -// Package tui -package tui - -import ( - "esdi/tui/internal/controllers" - "esdi/tui/internal/views" - "fmt" - "log/slog" - - "github.com/gdamore/tcell/v2" -) - -func Start(logger *slog.Logger) error { - // The app starts running here! - // - // Set the event capture for the global app itself here - mc := controllers.NewMainController(logger.With("[ctrl]", "main")) - - mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey { - if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' { - mc.App.Stop() - return nil - } - - return event - }) - - controllers.NewLayoutController(mc.EvBus) - - // Set the main view - mainUINode, err := views.BuildMainFlex(mc.EvBus, mc.Dom) - if err != nil { - panic(fmt.Errorf("failed to build main flex - %s", err.Error())) - } - - rootNode, err := mc.Dom.NewUINode("root", nil, mainUINode) - if err != nil { - panic(fmt.Errorf("failed to create root node - %s", err.Error())) - } - - 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 = mc.App.SetRoot(mc.Dom.GetRootElem(), true).SetFocus(firstFocus).Run() - if err != nil { - return err - } - - return nil -} diff --git a/tui/internal/views/aux.go b/tui/internal/views/aux.go index fa4e9fa..4186bd6 100644 --- a/tui/internal/views/aux.go +++ b/tui/internal/views/aux.go @@ -2,16 +2,12 @@ package views import ( "esdi/tui/internal/dom" - "esdi/tui/internal/events" - "esdi/tui/internal/ui" "slices" "github.com/rivo/tview" ) func AddAndShowPage( - bus *events.Bus, - doc *dom.DOM, pages *tview.Pages, page *dom.UINode, changeFocus bool, @@ -23,11 +19,6 @@ func AddAndShowPage( pages.SwitchToPage(page.ID) } - // Set focus to our new tool - if changeFocus { - bus.Emit(ui.ChangeFocusEv{Target: page.Self}) - } - return nil } diff --git a/tui/internal/views/layoutTool.go b/tui/internal/views/layoutTool.go index 2f94767..57e0f07 100644 --- a/tui/internal/views/layoutTool.go +++ b/tui/internal/views/layoutTool.go @@ -12,9 +12,9 @@ import ( ) const ( - layoutToolFlexID = "layout-tool-flex" - layoutToolTreeID = "layout-tool-tree" - layoutToolActionPagesID = "layout-tool-action-pages" + LayoutToolFlexID = "layout-tool-flex" + LayoutToolTreeID = "layout-tool-tree" + LayoutToolActionPagesID = "layout-tool-action-pages" ) type windowReference struct { @@ -155,7 +155,7 @@ func layoutToolTreeViewEvCapture(bus *events.Bus, doc *dom.DOM, return func(event *tcell.EventKey) *tcell.EventKey { switch event.Key() { case tcell.KeyEsc: - bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(deviceAPIListID)}) + bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(DeviceAPIListID)}) } switch event.Rune() { @@ -198,34 +198,12 @@ func layoutToolTreeViewEvCapture(bus *events.Bus, doc *dom.DOM, } } -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 := doc.GetElemByID(apiToolPagesID).(*tview.Pages) - if apiToolPages == nil { - bus.Emit(ui.LogEv{Log: " Failed to retrive apiToolPages UI\n"}) - return - } - - 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(bus, doc) - if err != nil { - bus.Emit(ui.LogEv{ - Log: fmt.Sprintf(" Failed to build layout tool UI: %s\n", err.Error()), - }) - } - } - - AddAndShowPage(bus, doc, apiToolPages, layoutToolUINode, true) -} - func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview.TreeNode) { + // Set focus to our new tool + // if changeFocus { + // bus.Emit(ui.ChangeFocusEv{Target: page.Self}) + // } + return func(node *tview.TreeNode) { // Here we want to change the current existing form on the action pages nodeRef := node.GetReference() @@ -240,7 +218,7 @@ func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview. Log: fmt.Sprintf("changing to -> %d | %s\n", nodeWinRef.ID, nodeWinRef.Form.ID), }) - pages := doc.GetElemByID(layoutToolActionPagesID) + pages := doc.GetElemByID(LayoutToolActionPagesID) AddAndShowPage(bus, doc, pages.(*tview.Pages), nodeWinRef.Form, false) } } @@ -270,8 +248,8 @@ func buildLayoutTreeComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error layoutTree.SetChangedFunc(layoutToolTreeViewOnChange(bus, doc)) layoutTree.SetSelectedFunc(layoutToolTreeViewOnSelect(bus)) - layoutTreeUINode, err := doc.NewUINode(layoutToolTreeID, - doc.GetElemByID(rightFlexID), layoutTree) + layoutTreeUINode, err := doc.NewUINode(LayoutToolTreeID, + doc.GetElemByID(RightFlexID), layoutTree) if err != nil { return nil, err } @@ -296,9 +274,9 @@ func buildLayoutActionPagesComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode emptyPage.SetBorder(true).SetTitle("-- Tool Area --") fmt.Fprintf(emptyPage, "No tool selected") - actionPages := tview.NewPages().AddPage(emptyPageName, emptyPage, true, true) + actionPages := tview.NewPages().AddPage(EmptyPageName, emptyPage, true, true) - actionPagesUINode, err := doc.NewUINode(layoutToolActionPagesID, + actionPagesUINode, err := doc.NewUINode(LayoutToolActionPagesID, doc.GetElemByID("right-flex"), actionPages) if err != nil { return nil, err @@ -321,8 +299,8 @@ func buildLayoutFlexComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error } layoutToolFlex := tview.NewFlex().SetDirection(tview.FlexRow) - layoutToolFlexNode, err := doc.NewUINode(layoutToolFlexID, - doc.GetElemByID(apiToolPagesID), layoutToolFlex) + layoutToolFlexNode, err := doc.NewUINode(LayoutToolFlexID, + doc.GetElemByID(APIToolPagesID), layoutToolFlex) if err != nil { return nil, err } diff --git a/tui/internal/views/layoutTool_NewWindow.go b/tui/internal/views/layoutTool_NewWindow.go index 89dea05..aa2a8df 100644 --- a/tui/internal/views/layoutTool_NewWindow.go +++ b/tui/internal/views/layoutTool_NewWindow.go @@ -128,7 +128,7 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) { SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { switch ev.Key() { case tcell.KeyEscape: - bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(layoutToolFlexID)}) + bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(LayoutToolFlexID)}) } return ev @@ -138,13 +138,13 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) { formNode = doc.GetNodeByID("new-window-form") if formNode == nil { formNode, err = doc.NewUINode("new-window-form", - doc.GetElemByID(layoutToolActionPagesID), form) + doc.GetElemByID(LayoutToolActionPagesID), form) if err != nil { panic("failed to create UI node for the new window form: " + err.Error()) } } - AddAndShowPage(bus, doc, doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages), + AddAndShowPage(bus, doc, doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages), formNode, true) } @@ -234,7 +234,7 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16, SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { switch ev.Key() { case tcell.KeyEscape: - bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(layoutToolTreeID)}) + bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(LayoutToolTreeID)}) } return ev @@ -264,7 +264,7 @@ func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16, var formNode *dom.UINode elemID := windowInfoPageID(idx) formNode = doc.GetNodeByID(elemID) - layoutToolActionPagesElem := doc.GetElemByID(layoutToolActionPagesID) + layoutToolActionPagesElem := doc.GetElemByID(LayoutToolActionPagesID) if formNode == nil { formNode, err = doc.NewUINode(elemID, layoutToolActionPagesElem, form) if err != nil { diff --git a/tui/internal/views/layoutTool_WindowManipulation.go b/tui/internal/views/layoutTool_WindowManipulation.go index 79ce896..9f52e8d 100644 --- a/tui/internal/views/layoutTool_WindowManipulation.go +++ b/tui/internal/views/layoutTool_WindowManipulation.go @@ -104,7 +104,7 @@ func windowManipulationEvCapture( switch ev.Key() { case tcell.KeyEscape: bus.Emit(ui.ChangeFocusEv{ - Target: doc.GetElemByID(layoutToolFlexID), + Target: doc.GetElemByID(LayoutToolFlexID), }) return ev } @@ -144,7 +144,7 @@ func windowManipulationTool(bus *events.Bus, doc *dom.DOM, idx int16) { var boxNode *dom.UINode // delete the currently existing move-window-box - actionPages := doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages) + actionPages := doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages) actionPages.RemovePage("move-window-box") boxNode = doc.GetNodeByID("move-window-box") @@ -154,7 +154,7 @@ func windowManipulationTool(bus *events.Bus, doc *dom.DOM, idx int16) { boxNode, err = doc.NewUINode( "move-window-box", - doc.GetElemByID(layoutToolActionPagesID), + doc.GetElemByID(LayoutToolActionPagesID), box, ) diff --git a/tui/internal/views/mainFlex.go b/tui/internal/views/mainFlex.go index e4dfe66..927c1f5 100644 --- a/tui/internal/views/mainFlex.go +++ b/tui/internal/views/mainFlex.go @@ -5,113 +5,111 @@ import ( "fmt" "esdi/tui/internal/dom" - "esdi/tui/internal/events" - "esdi/tui/internal/ui" "github.com/gdamore/tcell/v2" "github.com/rivo/tview" ) const ( - mainFlexID = "main-flex" - apiToolPagesID = "api-tool-pages" - rightFlexID = "right-flex" - outputPaneID = "output-window" - deviceAPIListID = "device-api-list" + MainFlexID = "main-flex" + APIToolPagesID = "api-tool-pages" + RightFlexID = "right-flex" + OutputPaneID = "output-window" + DeviceAPIListID = "device-api-list" ) const ( - emptyPageName = "empty-page" + EmptyPageName = "empty-page" ) -func buildRightSidePages(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) { +type DeviceAPIToolView struct { + Pages *tview.Pages + ChangedFn func() +} + +func NewDeviceAPIToolView() *DeviceAPIToolView { // We need to build a set of pages with an empty page emptyPage := tview.NewTextView(). SetTextAlign(tview.AlignCenter). SetChangedFunc(func() { - bus.Emit(ui.RedrawEv{}) + // bus.Emit(ui.RedrawEv{}) }) emptyPage.SetBorder(true).SetTitle("-- Tool Area --") fmt.Fprintf(emptyPage, "No Tool Selected") - apiToolPages := tview.NewPages().AddPage(emptyPageName, emptyPage, true, true) + apiToolPages := tview.NewPages().AddPage(EmptyPageName, emptyPage, true, true) - apiToolPagesNode, err := doc.NewUINode(apiToolPagesID, doc.GetElemByID(rightFlexID), - apiToolPages) - if err != nil { - return nil, err + return &DeviceAPIToolView{ + Pages: apiToolPages, + ChangedFn: func() {}, // blank function to be hooked on } - - return apiToolPagesNode, nil } -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 := doc.NewUINode(rightFlexID, doc.GetElemByID(mainFlexID), flex) - if err != nil { - return nil, err - } - - // outputWin := doc.GetElemByID(outputPaneID) - // if outputWin == nil { - // panic("failed to attach output win to UI") - // } - - flex. - AddItem(apiToolPagesNode.Self, 0, 5, false) - // AddItem(outputWin, 0, 2, false) - - return flexNode, nil +type DeviceAPIListView struct { + List *tview.List + InputCapture func(*tcell.EventKey) *tcell.EventKey + ItemOnSelect func() } -func BuildMainFlex(bus *events.Bus, doc *dom.DOM) (*tview.Flex, error) { +func NewDeviceAPIListView() *DeviceAPIListView { + deviceAPIList := tview.NewList(). + AddItem("layout", "build a layout for CDashDisplay", 0, func() { + // layoutToolUIOnSelect(bus, doc) + }) + deviceAPIList.SetBorder(true).SetTitle("list") + + return &DeviceAPIListView{ + List: deviceAPIList, + InputCapture: func(ev *tcell.EventKey) *tcell.EventKey { return ev }, + ItemOnSelect: func() {}, // blank functions, they have to be hooked on by the controller + } +} + +type DeviceAPIView struct { + MainFlex *tview.Flex + DevAPIList *DeviceAPIListView + DevAPIToolView *DeviceAPIToolView + OutputWindow *OutputWinView +} + +func (dl *DeviceAPIListView) AddItem(name, description string, onSelect func()) { + dl.List.AddItem(name, description, 0, onSelect) +} + +func NewDeviceAPIView(doc *dom.DOM) (*DeviceAPIView, error) { // To build the main view we must set the DOM root mainFlex := tview.NewFlex().SetDirection(tview.FlexColumn) - mainFlexUINode, err := doc.NewUINode(mainFlexID, nil, mainFlex) + mainFlexUINode, err := doc.NewUINode(MainFlexID, nil, mainFlex) if err != nil { return nil, err } doc.SetRoot(mainFlexUINode) - deviceAPIList := tview.NewList(). - AddItem("layout", "build a layout for CDashDisplay", 0, func() { - layoutToolUIOnSelect(bus, doc) - }) - deviceAPIList.SetBorder(true).SetTitle("list"). - SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey { - switch ev.Rune() { - case 'r': - bus.Emit(ui.FindCDashDisplay{}) - } - return ev - }) - - apiListWindowUINode, err := doc.NewUINode(deviceAPIListID, doc.GetRootElem(), - deviceAPIList) + deviceAPIList := NewDeviceAPIListView() + apiListWindowUINode, err := doc.NewUINode(DeviceAPIListID, doc.GetRootElem(), + deviceAPIList.List) if err != nil { return nil, err } - rightSideFlex, err := buildRightSideFlex(bus, doc) + apiToolPages := NewDeviceAPIToolView() + apiToolPagesNode, err := doc.NewUINode(APIToolPagesID, doc.GetElemByID(RightFlexID), + apiToolPages.Pages) if err != nil { return nil, err } mainFlex. AddItem(apiListWindowUINode.Self, 0, 1, false). - AddItem(rightSideFlex.Self, 0, 4, false) + AddItem(apiToolPagesNode.Self, 0, 4, false) // Output window - err = BuildOutputWindow(bus, doc) + + outputWin := NewOutputWinView() + _, err = doc.NewUINode("output-window", nil, outputWin.TextArea) if err != nil { - panic("failed to create output window") + return nil, err } // Flex with debug window @@ -119,8 +117,13 @@ func BuildMainFlex(bus *events.Bus, doc *dom.DOM) (*tview.Flex, error) { flexWithOutputWindow := tview.NewFlex().SetDirection(tview.FlexRow) flexWithOutputWindow. AddItem(mainFlex, 0, 5, true). - AddItem(doc.GetElemByID(outputPaneID), 0, 2, false) + AddItem(doc.GetElemByID(OutputPaneID), 0, 2, false) // -------------------------------------------------------------------------- - return flexWithOutputWindow, nil + return &DeviceAPIView{ + MainFlex: flexWithOutputWindow, + DevAPIList: deviceAPIList, + DevAPIToolView: apiToolPages, + OutputWindow: outputWin, + }, nil } diff --git a/tui/internal/views/outputWin.go b/tui/internal/views/outputWin.go index 4780b8f..04f37e4 100644 --- a/tui/internal/views/outputWin.go +++ b/tui/internal/views/outputWin.go @@ -1,38 +1,32 @@ package views import ( - "esdi/tui/internal/dom" - "esdi/tui/internal/events" - "esdi/tui/internal/ui" - "fmt" - "github.com/rivo/tview" ) -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 bindOutputWindowEvents( +// bus *events.Bus, +// output *tview.TextView, +// ) { +// bus.On(ui.PrintLogEv{}, func(e any) { +// le, _ := e.(ui.PrintLogEv) +// fmt.Fprintf(output, le.Log) +// }) +// } + +type OutputWinView struct { + TextArea *tview.TextView } -func BuildOutputWindow(bus *events.Bus, doc *dom.DOM) error { +func NewOutputWinView() *OutputWinView { var outputWin *tview.TextView outputWin = tview.NewTextView().SetChangedFunc(func() { - bus.Emit(ui.RedrawEv{}) outputWin.ScrollToEnd() }) outputWin.SetBorder(true).SetTitle("DebugWindow") - _, err := doc.NewUINode("output-window", nil, outputWin) - if err != nil { - return err + + return &OutputWinView{ + TextArea: outputWin, } - - bindOutputWindowEvents(bus, outputWin) - - return nil } diff --git a/tui/internal/views/stream.go b/tui/internal/views/stream.go index adf01d4..decb69c 100644 --- a/tui/internal/views/stream.go +++ b/tui/internal/views/stream.go @@ -42,7 +42,7 @@ func streamingWindow(bus *events.Bus, doc *dom.DOM) { var boxNode *dom.UINode // delete the currently existing streaming-box - actionPages := doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages) + actionPages := doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages) actionPages.RemovePage(streamingBoxID) // Get the currently exisiting streaming box in the dom so we can delete it @@ -54,7 +54,7 @@ func streamingWindow(bus *events.Bus, doc *dom.DOM) { // Register this streaming box as an UINode boxNode, err = doc.NewUINode( streamingBoxID, - doc.GetElemByID(layoutToolActionPagesID), + doc.GetElemByID(LayoutToolActionPagesID), box, ) if err != nil { diff --git a/tui/tui.go b/tui/tui.go index 58a141f..b71588e 100644 --- a/tui/tui.go +++ b/tui/tui.go @@ -2,10 +2,23 @@ package tui import ( - t "esdi/tui/internal/tui" + ctrls "esdi/tui/internal/controllers" "log/slog" ) func Run(logger *slog.Logger) error { - return t.Start(logger) + // // Call the main controller and let the program start! + // return ctrl.Init(logger) + + // The app starts running here! + // + // Set the event capture for the global app itself here + mc := ctrls.NewMainController(logger.With("[ctrl]", "main")) + + err := mc.Main() + if err != nil { + return err + } + + return nil }