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
This commit is contained in:
@@ -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{})
|
||||
// }
|
||||
@@ -0,0 +1,5 @@
|
||||
package controllers
|
||||
|
||||
type LayoutController struct {
|
||||
LayoutToolView any
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+15
-2
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user