feel like I'm doing shit here, but I reckon it will work

This commit is contained in:
2026-02-25 00:17:38 +00:00
parent e64b1c31b9
commit 34120f10af
10 changed files with 154 additions and 120 deletions
+45
View File
@@ -0,0 +1,45 @@
// Package controllers defines the controller stuff for our TUI
package controllers
import (
"esdi/tui/internal/dom"
"esdi/tui/internal/events"
"log/slog"
"github.com/rivo/tview"
)
type Controller struct {
Logger *slog.Logger
Bus *events.Bus
App *tview.Application
Dom *dom.DOM
}
type ControlPanel struct {
*Controller
DeviceController *DeviceController
}
func NewControlPanel(logger *slog.Logger) *ControlPanel {
baseController := &Controller{
Logger: logger,
Bus: events.NewBus(),
App: tview.NewApplication(),
Dom: dom.NewDOM(),
}
return &ControlPanel{
Controller: baseController,
DeviceController: NewDeviceController(baseController),
}
}
func (cp *ControlPanel) Run() error {
if err := cp.DeviceController.Main(); err != nil {
return err
}
return cp.App.Run()
}
@@ -11,45 +11,27 @@ import (
"esdi/tui/internal/views"
"fmt"
"io"
"log/slog"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
var pLogger *slog.Logger
func mcLog(msg string, args ...any) {
pLogger.Debug(msg, args)
}
type Ctrls struct {
MC *MainController
}
type MainController struct {
type DeviceController struct {
*Controller
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 {
pLogger = logger
mc := &MainController{
App: tview.NewApplication(),
Dom: dom.NewDOM(),
EvBus: events.NewBus(),
func NewDeviceController(base *Controller) *DeviceController {
mc := &DeviceController{
Controller: base,
DevClerk: peripheral.NewPeripheralDeviceClerk(),
CDash: nil,
StreamStrl: NewStreamingCtrl(),
}
mc.EvBus.On(ui.RedrawEv{}, func(e any) {
mc.Bus.On(ui.RedrawEv{}, func(e any) {
go func() {
rev := e.(ui.RedrawEv)
if rev.Fn != nil {
@@ -58,19 +40,25 @@ func NewMainController(logger *slog.Logger) *MainController {
}()
})
mc.EvBus.On(ui.ChangeFocusEv{}, func(e any) {
mc.Bus.On(ui.TUILoaded{}, func(e any) {
mc.Logger.Debug("Yo, we do get here!\n")
mc.Main()
mc.PrintToOutputWindow("TUI LOADED EVENT")
})
mc.Bus.On(ui.ChangeFocusEv{}, func(e any) {
mc.App.SetFocus(e.(ui.ChangeFocusEv).Target)
})
mc.EvBus.On(ui.LogEv{}, func(e any) {
mc.Bus.On(ui.LogEv{}, func(e any) {
go func() {
mc.App.QueueUpdateDraw(func() {
mc.EvBus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log})
mc.Bus.Emit(ui.PrintLogEv{Log: e.(ui.LogEv).Log})
})
}()
})
mc.EvBus.On(ui.CreateWindowEv{}, func(e any) {
mc.Bus.On(ui.CreateWindowEv{}, func(e any) {
win := e.(ui.CreateWindowEv).Window
winDecor := cdashdisplay.DefaultDecorations
@@ -95,21 +83,21 @@ func NewMainController(logger *slog.Logger) *MainController {
wID, err := mc.CDash.CreateWindow(uiWindow)
if err != nil {
mc.EvBus.Emit(ui.PrintLogEv{Log: "failed to create window\n"})
mc.Bus.Emit(ui.PrintLogEv{Log: "failed to create window\n"})
return
}
mc.EvBus.Emit(ui.WindowCreatedEv{ID: wID, Win: uiWindow})
mc.EvBus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
mc.Bus.Emit(ui.WindowCreatedEv{ID: wID, Win: uiWindow})
mc.Bus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
})
mc.EvBus.On(ui.UpdateWindowEv{}, func(e any) {
mc.Bus.On(ui.UpdateWindowEv{}, func(e any) {
winModel := e.(ui.UpdateWindowEv)
// Build a new UIWindow here I guess
curWindow, ok := mc.CDash.State.Layout.Windows[winModel.ID]
if !ok {
mc.EvBus.Emit(ui.PrintLogEv{Log: "could not acquire window from display state"})
mc.Bus.Emit(ui.PrintLogEv{Log: "could not acquire window from display state"})
return
}
@@ -131,91 +119,91 @@ func NewMainController(logger *slog.Logger) *MainController {
err := mc.CDash.UpdateWindow(winModel.ID, curWindow)
if err != nil {
mc.EvBus.Emit(ui.PrintLogEv{Log: "failed to update window"})
mc.Bus.Emit(ui.PrintLogEv{Log: "failed to update window"})
}
})
mc.EvBus.On(ui.DestroyWindowEv{}, func(e any) {
pLogger.Info(fmt.Sprintf("Called in to destroy win: %d", e.(ui.DestroyWindowEv).ID))
mc.Bus.On(ui.DestroyWindowEv{}, func(e any) {
mc.Logger.Info(fmt.Sprintf("Called in to destroy win: %d", e.(ui.DestroyWindowEv).ID))
mc.CDash.DestroyWindow(e.(ui.DestroyWindowEv).ID)
mc.EvBus.Emit(ui.WindowDestroyedEv{ID: e.(ui.DestroyWindowEv).ID})
mc.Bus.Emit(ui.WindowDestroyedEv{ID: e.(ui.DestroyWindowEv).ID})
})
mc.EvBus.On(ui.MoveWindowEv{}, func(e any) {
mc.Bus.On(ui.MoveWindowEv{}, func(e any) {
mvData := e.(ui.MoveWindowEv)
pLogger.Debug(fmt.Sprintf("request to move window '%d'", mvData.WindowID))
mc.Logger.Debug(fmt.Sprintf("request to move window '%d'", mvData.WindowID))
newDims, err := mc.CDash.MoveWindow(mvData.WindowID, mvData.Delta)
if err != nil && err != io.EOF {
pLogger.Debug(fmt.Sprintf("failed to move window '%d' %s", mvData.WindowID, err.Error()))
mc.Logger.Debug(fmt.Sprintf("failed to move window '%d' %s", mvData.WindowID, err.Error()))
return
}
mc.EvBus.Emit(ui.WindowMovedEv{ID: mvData.WindowID, Dims: newDims})
mc.Bus.Emit(ui.WindowMovedEv{ID: mvData.WindowID, Dims: newDims})
})
mc.EvBus.On(ui.ResizeWindowEv{}, func(e any) {
mc.Bus.On(ui.ResizeWindowEv{}, func(e any) {
mvData := e.(ui.ResizeWindowEv)
pLogger.Debug(fmt.Sprintf("requested to resize window '%d'", mvData.WindowID))
mc.Logger.Debug(fmt.Sprintf("requested to resize window '%d'", mvData.WindowID))
err := mc.CDash.ResizeWindow(mvData.WindowID, mvData.Delta)
if err != nil && err != io.EOF {
pLogger.Debug(fmt.Sprintf("failed to resize window '%d' %s", mvData.WindowID, err.Error()))
mc.Logger.Debug(fmt.Sprintf("failed to resize window '%d' %s", mvData.WindowID, err.Error()))
return
}
})
mc.EvBus.On(ui.SaveLayoutEv{}, func(e any) {
mc.Bus.On(ui.SaveLayoutEv{}, func(e any) {
mc.CDash.SaveLayout()
})
mc.EvBus.On(ui.LoadLayoutEv{}, func(e any) {
mc.Bus.On(ui.LoadLayoutEv{}, func(e any) {
mc.CDash.LoadLayout()
mc.EvBus.Emit(ui.RegisterLoadedLayout{*mc.CDash.State.Layout})
mc.Bus.Emit(ui.RegisterLoadedLayout{*mc.CDash.State.Layout})
})
mc.EvBus.On(ui.ForceRedraw{}, func(e any) {
mc.Bus.On(ui.ForceRedraw{}, func(e any) {
// mc.App.QueueUpdateDraw(func() {})
mc.App.Draw()
})
mc.EvBus.On(ui.StartStreamingReqEv{}, func(e any) {
mc.StreamStrl.Start(mc.EvBus)
mc.Bus.On(ui.StartStreamingReqEv{}, func(e any) {
mc.StreamStrl.Start(mc.Bus)
})
mc.EvBus.On(ui.StopStreamingReqEv{}, func(e any) {
mc.StreamStrl.Stop(mc.EvBus)
mc.Bus.On(ui.StopStreamingReqEv{}, func(e any) {
mc.StreamStrl.Stop(mc.Bus)
})
return mc
}
func (mc *MainController) PrintToOutputWindow(msg string) {
func (mc *DeviceController) PrintToOutputWindow(msg string) {
mc.App.QueueUpdateDraw(func() {
fmt.Fprintf(mc.DeviceAPIView.OutputWindow.TextArea,
"%s", msg)
})
}
func (mc *MainController) findCDashDisplay() {
func (mc *DeviceController) findCDashDisplay() {
mc.PrintToOutputWindow("looking for cdash display\n")
pLogger.Info("Looking for CDashDisplay")
mc.Logger.Info("Looking for CDashDisplay")
cdashdisplay.SetLogger(pLogger.With("[device]", "cdashdisplay"))
cdashdisplay.SetLogger(mc.Logger.With("[device]", "cdashdisplay"))
display, err := cdashdisplay.NewCDashDisplay()
if err != nil {
pLogger.Info("didn't find cdashdisplay")
mc.Logger.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.Logger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
mc.PrintToOutputWindow("found cdashdisplay on: " + display.WT.Cfg.Name + "\n")
}
func (mc *MainController) setAppEventCapture() {
func (mc *DeviceController) setAppEventCapture() {
mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' {
mc.App.Stop()
@@ -226,7 +214,7 @@ func (mc *MainController) setAppEventCapture() {
})
}
func (mc *MainController) setDeviceAPIViewEvents() {
func (mc *DeviceController) setDeviceAPIViewEvents() {
mc.DeviceAPIView.MainFlex.
SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
switch ev.Rune() {
@@ -238,43 +226,39 @@ func (mc *MainController) setDeviceAPIViewEvents() {
}
func (mc *MainController) AddDeviceAPIListItems() {
func (mc *DeviceController) 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})
// var err error
//
// // Get the api pages
// apiToolPages := mc.DeviceAPIView.DevAPIToolView
//
// layoutToolUINode := mc.Dom.GetNodeByID(views.LayoutToolFlexID)
// if layoutToolUINode == nil {
// layoutToolUINode, err = buildLayoutFlexComponent(mc.Bus, mc.Dom)
// if err != nil {
// mc.PrintToOutputWindow(
// fmt.Sprintf(" Failed to build layout tool UI: %s\n", err.Error()),
// )
// }
// }
//
// err = views.AddAndShowPage(apiToolPages.Pages, layoutToolUINode, true)
// if err == nil {
// mc.App.SetFocus(layoutToolUINode.Self)
// }
})
}
func layoutToolUIOnSelect(bus *events.Bus, doc *dom.DOM) {
}
func (mc *MainController) mainUI() error {
func (mc *DeviceController) mainUI() error {
var err error
// Set the main view
deviceAPIView, err := views.NewDeviceAPIView(mc.Dom)
mc.DeviceAPIView, err = views.NewDeviceAPIView(mc.Dom)
if err != nil {
return err
}
@@ -284,32 +268,32 @@ func (mc *MainController) mainUI() error {
// Add the API things to the deviceAPIListView
mc.AddDeviceAPIListItems()
rootNode, err := mc.Dom.NewUINode("root", nil, deviceAPIView.MainFlex)
rootNode, err := mc.Dom.NewUINode("root", nil, mc.DeviceAPIView.MainFlex)
if err != nil {
return err
}
mc.DeviceAPIView = deviceAPIView
mc.Dom.SetRoot(rootNode)
return nil
}
func (mc *MainController) Main() error {
mc.setAppEventCapture()
func (mc *DeviceController) Main() error {
mc.Logger.Debug("and then here")
err := mc.mainUI()
mc.Logger.Debug("and then here x2")
mc.setAppEventCapture()
// First focused element
mc.Logger.Debug("and then here x3")
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
}
mc.Logger.Debug("and then here x4")
mc.App.SetRoot(mc.DeviceAPIView.MainFlex, true)
mc.App.SetFocus(firstFocus)
return err
}
@@ -1,5 +1,17 @@
package controllers
import "esdi/tui/internal/events"
type LayoutController struct {
EvBus *events.Bus
LayoutToolView any
}
func (lc *LayoutController) registerEvents() {
}
func NewLayoutController(bus *events.Bus) *LayoutController {
return &LayoutController{
EvBus: bus,
}
}
+6
View File
@@ -8,6 +8,12 @@ import (
"github.com/rivo/tview"
)
//
type TUILoaded struct{}
//
// Main controller events
// Find a way to remove this
+1 -1
View File
@@ -219,7 +219,7 @@ func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview.
})
pages := doc.GetElemByID(LayoutToolActionPagesID)
AddAndShowPage(bus, doc, pages.(*tview.Pages), nodeWinRef.Form, false)
AddAndShowPage(pages.(*tview.Pages), nodeWinRef.Form, false)
}
}
+1 -2
View File
@@ -144,8 +144,7 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
}
}
AddAndShowPage(bus, doc, doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages),
formNode, true)
AddAndShowPage(doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages), formNode, true)
}
func windowInfoPageID(idx int16) string {
@@ -168,5 +168,5 @@ func windowManipulationTool(bus *events.Bus, doc *dom.DOM, idx int16) {
}
box.SetInputCapture(windowManipulationEvCapture(bus, doc, idx, &state))
AddAndShowPage(bus, doc, actionPages, boxNode, true)
AddAndShowPage(actionPages, boxNode, true)
}
+4 -4
View File
@@ -52,10 +52,10 @@ type DeviceAPIListView struct {
}
func NewDeviceAPIListView() *DeviceAPIListView {
deviceAPIList := tview.NewList().
AddItem("layout", "build a layout for CDashDisplay", 0, func() {
// layoutToolUIOnSelect(bus, doc)
})
deviceAPIList := tview.NewList()
// AddItem("layout", "build a layout for CDashDisplay", 0, func() {
// layoutToolUIOnSelect(bus, doc)
// })
deviceAPIList.SetBorder(true).SetTitle("list")
return &DeviceAPIListView{
+1 -1
View File
@@ -62,7 +62,7 @@ func streamingWindow(bus *events.Bus, doc *dom.DOM) {
}
// Add it to the action pages and view it
AddAndShowPage(bus, doc, actionPages, boxNode, true)
AddAndShowPage(actionPages, boxNode, true)
bus.Emit(ui.StartStreamingReqEv{})
+3 -15
View File
@@ -2,23 +2,11 @@
package tui
import (
ctrls "esdi/tui/internal/controllers"
"esdi/tui/internal/controllers"
"log/slog"
)
func Run(logger *slog.Logger) error {
// // 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
progController := controllers.NewControlPanel(logger)
return progController.Run()
}