doesnt look as cool, but for sure feels simpler
This commit is contained in:
@@ -1,45 +0,0 @@
|
||||
// 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()
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// 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
|
||||
}
|
||||
@@ -2,15 +2,10 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"esdi/cdashdisplay"
|
||||
helper "esdi/helpers"
|
||||
"esdi/peripheral"
|
||||
"esdi/tui/internal/dom"
|
||||
"esdi/tui/internal/events"
|
||||
serv "esdi/tui/internal/services"
|
||||
"esdi/tui/internal/ui"
|
||||
"esdi/tui/internal/views"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
@@ -18,16 +13,16 @@ import (
|
||||
type DeviceController struct {
|
||||
*Controller
|
||||
DeviceAPIView *views.DeviceAPIView
|
||||
DevClerk *peripheral.PeripheralDeviceClerk
|
||||
CDash *cdashdisplay.CDashDisplay
|
||||
LayoutCtrl *LayoutController
|
||||
StreamStrl *StreamingCtrl
|
||||
DevService *serv.CDashService
|
||||
}
|
||||
|
||||
func NewDeviceController(base *Controller) *DeviceController {
|
||||
func NewDeviceController(base *Controller, devService *serv.CDashService) *DeviceController {
|
||||
mc := &DeviceController{
|
||||
Controller: base,
|
||||
DevClerk: peripheral.NewPeripheralDeviceClerk(),
|
||||
CDash: nil,
|
||||
LayoutCtrl: NewLayoutController(base),
|
||||
DevService: devService,
|
||||
StreamStrl: NewStreamingCtrl(),
|
||||
}
|
||||
|
||||
@@ -58,122 +53,92 @@ func NewDeviceController(base *Controller) *DeviceController {
|
||||
}()
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.CreateWindowEv{}, func(e any) {
|
||||
win := e.(ui.CreateWindowEv).Window
|
||||
// mc.Bus.On(ui.CreateWindowEv{}, func(e any) {
|
||||
// })
|
||||
|
||||
winDecor := cdashdisplay.DefaultDecorations
|
||||
winDecor.TextSize = win.TextSize
|
||||
winDecor.TitleSize = win.TitleSize
|
||||
// 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.Bus.Emit(ui.PrintLogEv{Log: "could not acquire window from display state"})
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Need to use a better interface for this me things
|
||||
// // Update the dimensions
|
||||
// curWindow.Dims.X0 = winModel.Window.X
|
||||
// curWindow.Dims.Y0 = winModel.Window.Y
|
||||
// curWindow.Dims.Width = winModel.Window.Width
|
||||
// curWindow.Dims.Height = winModel.Window.Height
|
||||
// // Update the opts
|
||||
// curWindow.Opts.ShowID = winModel.Window.ShowID
|
||||
// curWindow.Opts.WinType = winModel.Window.Type
|
||||
// curWindow.Opts.PreviewValue = helper.B32(winModel.Window.PreviewValue)
|
||||
// // Update the decorations
|
||||
// curWindow.Decor.TitleSize = winModel.Window.TitleSize
|
||||
// curWindow.Decor.TextSize = winModel.Window.TextSize
|
||||
// // Update the title
|
||||
// curWindow.Title = helper.B32(winModel.Window.Title)
|
||||
//
|
||||
// err := mc.CDash.UpdateWindow(winModel.ID, curWindow)
|
||||
// if err != nil {
|
||||
// mc.Bus.Emit(ui.PrintLogEv{Log: "failed to update window"})
|
||||
// }
|
||||
// })
|
||||
|
||||
uiWindow := cdashdisplay.UIWindow{
|
||||
Dims: cdashdisplay.UIDimensions{
|
||||
X0: win.X,
|
||||
Y0: win.Y,
|
||||
Width: win.Width,
|
||||
Height: win.Height,
|
||||
},
|
||||
Opts: cdashdisplay.UIWindowOpts{
|
||||
WinType: win.Type, // NOTE: values aren't implemented yet
|
||||
ShowID: win.ShowID,
|
||||
PreviewValue: helper.B32(win.PreviewValue),
|
||||
},
|
||||
Decor: winDecor,
|
||||
Title: helper.B32(win.Title),
|
||||
}
|
||||
// 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.Bus.Emit(ui.WindowDestroyedEv{ID: e.(ui.DestroyWindowEv).ID})
|
||||
// })
|
||||
|
||||
wID, err := mc.CDash.CreateWindow(uiWindow)
|
||||
if err != nil {
|
||||
mc.Bus.Emit(ui.PrintLogEv{Log: "failed to create window\n"})
|
||||
return
|
||||
}
|
||||
// mc.Bus.On(ui.MoveWindowEv{}, func(e any) {
|
||||
// mvData := e.(ui.MoveWindowEv)
|
||||
// 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 {
|
||||
// mc.Logger.Debug(fmt.Sprintf("failed to move window '%d' %s", mvData.WindowID, err.Error()))
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// mc.Bus.Emit(ui.WindowMovedEv{ID: mvData.WindowID, Dims: newDims})
|
||||
// })
|
||||
|
||||
mc.Bus.Emit(ui.WindowCreatedEv{ID: wID, Win: uiWindow})
|
||||
mc.Bus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
|
||||
})
|
||||
// mc.Bus.On(ui.ResizeWindowEv{}, func(e any) {
|
||||
// mvData := e.(ui.ResizeWindowEv)
|
||||
// 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 {
|
||||
// mc.Logger.Debug(fmt.Sprintf("failed to resize window '%d' %s", mvData.WindowID, err.Error()))
|
||||
// return
|
||||
// }
|
||||
// })
|
||||
|
||||
mc.Bus.On(ui.UpdateWindowEv{}, func(e any) {
|
||||
winModel := e.(ui.UpdateWindowEv)
|
||||
// mc.Bus.On(ui.SaveLayoutEv{}, func(e any) {
|
||||
// mc.CDash.SaveLayout()
|
||||
// })
|
||||
|
||||
// Build a new UIWindow here I guess
|
||||
curWindow, ok := mc.CDash.State.Layout.Windows[winModel.ID]
|
||||
if !ok {
|
||||
mc.Bus.Emit(ui.PrintLogEv{Log: "could not acquire window from display state"})
|
||||
return
|
||||
}
|
||||
// mc.Bus.On(ui.LoadLayoutEv{}, func(e any) {
|
||||
// mc.CDash.LoadLayout()
|
||||
// mc.Bus.Emit(ui.RegisterLoadedLayout{*mc.CDash.State.Layout})
|
||||
// })
|
||||
|
||||
// Need to use a better interface for this me things
|
||||
// Update the dimensions
|
||||
curWindow.Dims.X0 = winModel.Window.X
|
||||
curWindow.Dims.Y0 = winModel.Window.Y
|
||||
curWindow.Dims.Width = winModel.Window.Width
|
||||
curWindow.Dims.Height = winModel.Window.Height
|
||||
// Update the opts
|
||||
curWindow.Opts.ShowID = winModel.Window.ShowID
|
||||
curWindow.Opts.WinType = winModel.Window.Type
|
||||
curWindow.Opts.PreviewValue = helper.B32(winModel.Window.PreviewValue)
|
||||
// Update the decorations
|
||||
curWindow.Decor.TitleSize = winModel.Window.TitleSize
|
||||
curWindow.Decor.TextSize = winModel.Window.TextSize
|
||||
// Update the title
|
||||
curWindow.Title = helper.B32(winModel.Window.Title)
|
||||
// mc.Bus.On(ui.ForceRedraw{}, func(e any) {
|
||||
// // mc.App.QueueUpdateDraw(func() {})
|
||||
// mc.App.Draw()
|
||||
// })
|
||||
|
||||
err := mc.CDash.UpdateWindow(winModel.ID, curWindow)
|
||||
if err != nil {
|
||||
mc.Bus.Emit(ui.PrintLogEv{Log: "failed to update window"})
|
||||
}
|
||||
})
|
||||
// mc.Bus.On(ui.StartStreamingReqEv{}, func(e any) {
|
||||
// mc.StreamStrl.Start(mc.Bus)
|
||||
// })
|
||||
|
||||
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.Bus.Emit(ui.WindowDestroyedEv{ID: e.(ui.DestroyWindowEv).ID})
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.MoveWindowEv{}, func(e any) {
|
||||
mvData := e.(ui.MoveWindowEv)
|
||||
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 {
|
||||
mc.Logger.Debug(fmt.Sprintf("failed to move window '%d' %s", mvData.WindowID, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
mc.Bus.Emit(ui.WindowMovedEv{ID: mvData.WindowID, Dims: newDims})
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.ResizeWindowEv{}, func(e any) {
|
||||
mvData := e.(ui.ResizeWindowEv)
|
||||
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 {
|
||||
mc.Logger.Debug(fmt.Sprintf("failed to resize window '%d' %s", mvData.WindowID, err.Error()))
|
||||
return
|
||||
}
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.SaveLayoutEv{}, func(e any) {
|
||||
mc.CDash.SaveLayout()
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.LoadLayoutEv{}, func(e any) {
|
||||
mc.CDash.LoadLayout()
|
||||
mc.Bus.Emit(ui.RegisterLoadedLayout{*mc.CDash.State.Layout})
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.ForceRedraw{}, func(e any) {
|
||||
// mc.App.QueueUpdateDraw(func() {})
|
||||
mc.App.Draw()
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.StartStreamingReqEv{}, func(e any) {
|
||||
mc.StreamStrl.Start(mc.Bus)
|
||||
})
|
||||
|
||||
mc.Bus.On(ui.StopStreamingReqEv{}, func(e any) {
|
||||
mc.StreamStrl.Stop(mc.Bus)
|
||||
})
|
||||
// mc.Bus.On(ui.StopStreamingReqEv{}, func(e any) {
|
||||
// mc.StreamStrl.Stop(mc.Bus)
|
||||
// })
|
||||
|
||||
return mc
|
||||
}
|
||||
@@ -185,24 +150,6 @@ func (mc *DeviceController) PrintToOutputWindow(msg string) {
|
||||
})
|
||||
}
|
||||
|
||||
func (mc *DeviceController) findCDashDisplay() {
|
||||
mc.PrintToOutputWindow("looking for cdash display\n")
|
||||
mc.Logger.Info("Looking for CDashDisplay")
|
||||
|
||||
cdashdisplay.SetLogger(mc.Logger.With("[device]", "cdashdisplay"))
|
||||
|
||||
display, err := cdashdisplay.NewCDashDisplay()
|
||||
if err != nil {
|
||||
mc.Logger.Info("didn't find cdashdisplay")
|
||||
mc.PrintToOutputWindow("didn't find cdash display\n")
|
||||
return
|
||||
}
|
||||
|
||||
mc.CDash = display
|
||||
mc.Logger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
|
||||
mc.PrintToOutputWindow("found cdashdisplay on: " + display.WT.Cfg.Name + "\n")
|
||||
}
|
||||
|
||||
func (mc *DeviceController) setAppEventCapture() {
|
||||
mc.App.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
|
||||
if event.Key() == tcell.KeyCtrlC || event.Rune() == 'q' {
|
||||
@@ -215,43 +162,53 @@ func (mc *DeviceController) setAppEventCapture() {
|
||||
}
|
||||
|
||||
func (mc *DeviceController) setDeviceAPIViewEvents() {
|
||||
mc.DeviceAPIView.MainFlex.
|
||||
// api list hooks
|
||||
mc.DeviceAPIView.DevAPIList.List.
|
||||
SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Rune() {
|
||||
case 'r':
|
||||
go mc.findCDashDisplay()
|
||||
go mc.DevService.FindDevice()
|
||||
}
|
||||
return ev
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
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 := 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)
|
||||
// }
|
||||
// Get the api pages
|
||||
views.AddAndShowPage(
|
||||
mc.DeviceAPIView.DevAPIToolView.Pages,
|
||||
"layout-tool",
|
||||
mc.LayoutCtrl.LayoutToolView.Flex,
|
||||
)
|
||||
mc.App.SetFocus(mc.LayoutCtrl.LayoutToolView.LayoutTree.Tree)
|
||||
})
|
||||
}
|
||||
|
||||
func layoutToolUIOnSelect(bus *events.Bus, doc *dom.DOM) {
|
||||
func (mc *DeviceController) injectViewCallbacks() {
|
||||
mc.setDeviceAPIViewEvents()
|
||||
}
|
||||
|
||||
func (mc *DeviceController) injectControllerCallbacks() {
|
||||
// Tell the layout controller what to do on exit
|
||||
mc.LayoutCtrl.OnExit = func() {
|
||||
mc.App.SetFocus(mc.DeviceAPIView.DevAPIList.List)
|
||||
}
|
||||
}
|
||||
|
||||
func (mc *DeviceController) injectChannels() {
|
||||
go func() {
|
||||
for msg := range mc.DevService.Messages {
|
||||
mc.PrintToOutputWindow(msg)
|
||||
}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for msg := range mc.LayoutCtrl.Messages {
|
||||
mc.PrintToOutputWindow(msg)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func (mc *DeviceController) mainUI() error {
|
||||
@@ -263,37 +220,27 @@ func (mc *DeviceController) mainUI() error {
|
||||
return err
|
||||
}
|
||||
|
||||
mc.setDeviceAPIViewEvents()
|
||||
// Inject the view hooks
|
||||
mc.injectViewCallbacks()
|
||||
|
||||
// Inject controller callbacks
|
||||
mc.injectControllerCallbacks()
|
||||
|
||||
// Run channels
|
||||
mc.injectChannels()
|
||||
|
||||
// Add the API things to the deviceAPIListView
|
||||
mc.AddDeviceAPIListItems()
|
||||
|
||||
rootNode, err := mc.Dom.NewUINode("root", nil, mc.DeviceAPIView.MainFlex)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mc.Dom.SetRoot(rootNode)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
mc.Logger.Debug("and then here x4")
|
||||
mc.App.SetRoot(mc.DeviceAPIView.MainFlex, true)
|
||||
mc.App.SetFocus(firstFocus)
|
||||
mc.App.SetFocus(mc.DeviceAPIView.DevAPIList.List)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,17 +1,220 @@
|
||||
package controllers
|
||||
|
||||
import "esdi/tui/internal/events"
|
||||
import (
|
||||
"esdi/cdashdisplay"
|
||||
"esdi/tui/internal/views"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
|
||||
type LayoutController struct {
|
||||
EvBus *events.Bus
|
||||
LayoutToolView any
|
||||
*Controller
|
||||
OnExit func()
|
||||
LayoutToolView *views.LayoutToolView
|
||||
Messages chan string
|
||||
}
|
||||
|
||||
func (lc *LayoutController) registerEvents() {
|
||||
}
|
||||
|
||||
func NewLayoutController(bus *events.Bus) *LayoutController {
|
||||
return &LayoutController{
|
||||
EvBus: bus,
|
||||
func NewLayoutController(base *Controller) *LayoutController {
|
||||
lc := &LayoutController{
|
||||
Controller: base,
|
||||
LayoutToolView: views.NewLayoutToolView(),
|
||||
Messages: make(chan string, 10),
|
||||
}
|
||||
|
||||
lc.registerHooks()
|
||||
|
||||
return lc
|
||||
}
|
||||
|
||||
func (lc *LayoutController) registerHooks() {
|
||||
lc.LayoutToolView.LayoutTree.Tree.SetInputCapture(
|
||||
func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEsc:
|
||||
lc.OnExit()
|
||||
}
|
||||
|
||||
switch ev.Rune() {
|
||||
case 'n':
|
||||
// Create a new window
|
||||
lc.Messages <- "calling new window form\n"
|
||||
lc.newWindowAction()
|
||||
case 'x':
|
||||
lc.Messages <- "calling delete window\n"
|
||||
// Delete selected window
|
||||
// bus.Emit(ui.LogEv{Log: })
|
||||
// wRef, err := getCurNodeRef(tree)
|
||||
// if err != nil {
|
||||
// bus.Emit(ui.LogEv{Log: " -> " + err.Error()})
|
||||
// break
|
||||
// }
|
||||
// bus.Emit(ui.DestroyWindowEv{ID: wRef.ID})
|
||||
case 'm':
|
||||
lc.Messages <- "calling window manipulation tool\n"
|
||||
// Go into move mode
|
||||
// bus.Emit(ui.LogEv{Log: })
|
||||
// wRef, err := getCurNodeRef(tree)
|
||||
// if err != nil {
|
||||
// bus.Emit(ui.LogEv{Log: " -> " + err.Error()})
|
||||
// break
|
||||
// }
|
||||
// windowManipulationTool(bus, doc, wRef.ID)
|
||||
case 'e':
|
||||
// Go into edit mode
|
||||
case 's':
|
||||
// Save the current layout
|
||||
// bus.Emit(ui.SaveLayoutEv{})
|
||||
case 'l':
|
||||
// Load the layout
|
||||
// bus.Emit(ui.LoadLayoutEv{})
|
||||
case 'g':
|
||||
// Go -> launches the current set up source
|
||||
// streamingWindow(bus, doc)
|
||||
}
|
||||
|
||||
return ev
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func (lc *LayoutController) parseCreateWindowInput() (*cdashdisplay.UIWindow, error) {
|
||||
form := lc.LayoutToolView.LayoutActions.CreateWindowView
|
||||
|
||||
lc.Messages <- form.Form.X.GetText()
|
||||
|
||||
// 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
|
||||
// }
|
||||
// titleSizeValue, err := strconv.ParseUint(titleSize, 10, 64)
|
||||
// if err != nil {
|
||||
// return models.Window{}, err
|
||||
// }
|
||||
// textSizeValue, err := strconv.ParseUint(textSize, 10, 64)
|
||||
// if err != nil {
|
||||
// return models.Window{}, err
|
||||
// }
|
||||
//
|
||||
// showIDValue := cdashdisplay.ShowIDFalse
|
||||
// if showID {
|
||||
// showIDValue = cdashdisplay.ShowIDTrue
|
||||
// }
|
||||
|
||||
// win := e.(ui.CreateWindowEv).Window
|
||||
//
|
||||
// winDecor := cdashdisplay.DefaultDecorations
|
||||
// winDecor.TextSize = win.TextSize
|
||||
// winDecor.TitleSize = win.TitleSize
|
||||
//
|
||||
// uiWindow := cdashdisplay.UIWindow{
|
||||
// Dims: cdashdisplay.UIDimensions{
|
||||
// X0: win.X,
|
||||
// Y0: win.Y,
|
||||
// Width: win.Width,
|
||||
// Height: win.Height,
|
||||
// },
|
||||
// Opts: cdashdisplay.UIWindowOpts{
|
||||
// WinType: win.Type, // NOTE: values aren't implemented yet
|
||||
// ShowID: win.ShowID,
|
||||
// PreviewValue: helper.B32(win.PreviewValue),
|
||||
// },
|
||||
// Decor: winDecor,
|
||||
// Title: helper.B32(win.Title),
|
||||
// }
|
||||
//
|
||||
// wID, err := mc.CDash.CreateWindow(uiWindow)
|
||||
// if err != nil {
|
||||
// mc.Bus.Emit(ui.PrintLogEv{Log: "failed to create window\n"})
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// mc.Bus.Emit(ui.WindowCreatedEv{ID: wID, Win: uiWindow})
|
||||
// mc.Bus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
|
||||
|
||||
// return models.Window{
|
||||
// X: uint16(xValue),
|
||||
// Y: uint16(yValue),
|
||||
// Width: uint16(widthValue),
|
||||
// Height: uint16(heightValue),
|
||||
// ShowID: showIDValue,
|
||||
// TitleSize: uint8(titleSizeValue),
|
||||
// TextSize: uint8(textSizeValue),
|
||||
// PreviewValue: prev,
|
||||
// Title: title,
|
||||
// }, nil
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (lc *LayoutController) newWindowAction() {
|
||||
if lc.LayoutToolView.LayoutActions.CreateWindowView != nil {
|
||||
// already exists, just change focus and leave
|
||||
lc.App.SetFocus(lc.LayoutToolView.LayoutActions.CreateWindowView.Form.Form)
|
||||
lc.Messages <- "already exists"
|
||||
return
|
||||
}
|
||||
|
||||
// Get the new window form view
|
||||
newWindowForm := views.NewCreateWindowFormView()
|
||||
lc.LayoutToolView.LayoutActions.CreateWindowView = newWindowForm
|
||||
|
||||
// Set the event capture for this form
|
||||
newWindowForm.Form.Form.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEscape:
|
||||
lc.App.SetFocus(lc.LayoutToolView.LayoutTree.Tree)
|
||||
}
|
||||
|
||||
return ev
|
||||
})
|
||||
|
||||
// Set the behaviour for when we press the create button
|
||||
newWindowForm.CreateBtn.SetSelectedFunc(func() {
|
||||
lc.Messages <- "am I here???"
|
||||
lc.parseCreateWindowInput()
|
||||
// _, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
// _, textSizeTxt := textSize.GetCurrentOption()
|
||||
// // Validate the inputs
|
||||
// window, err := validateFormInputs(
|
||||
// x0.GetText(),
|
||||
// y0.GetText(),
|
||||
// width.GetText(),
|
||||
// height.GetText(),
|
||||
// title.GetText(),
|
||||
// previewValue.GetText(),
|
||||
// titleSizeTxt,
|
||||
// textSizeTxt,
|
||||
// showID.IsChecked(),
|
||||
// )
|
||||
|
||||
// if err != nil {
|
||||
// // bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())})
|
||||
// return
|
||||
// }
|
||||
|
||||
// bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
// bus.Emit(ui.CreateWindowEv{Window: window})
|
||||
})
|
||||
|
||||
// Set this on the action page and change to it
|
||||
views.AddAndShowPage(
|
||||
lc.LayoutToolView.LayoutActions.Pages,
|
||||
"new-window-action-form",
|
||||
newWindowForm.Form.Form,
|
||||
)
|
||||
|
||||
// Set its focus
|
||||
lc.App.SetFocus(newWindowForm.Form.Form)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"esdi/cdashdisplay"
|
||||
"esdi/peripheral"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type CDashService struct {
|
||||
Logger *slog.Logger
|
||||
CDash *cdashdisplay.CDashDisplay
|
||||
DevClerk *peripheral.PeripheralDeviceClerk
|
||||
Messages chan string
|
||||
}
|
||||
|
||||
func NewCDashService(logger *slog.Logger) *CDashService {
|
||||
return &CDashService{
|
||||
Logger: logger,
|
||||
CDash: nil,
|
||||
DevClerk: peripheral.NewPeripheralDeviceClerk(),
|
||||
Messages: make(chan string, 10),
|
||||
}
|
||||
}
|
||||
|
||||
func (cds *CDashService) FindDevice() {
|
||||
cds.Messages <- "looking for cdash display...\n"
|
||||
cds.Logger.Info("Looking for CDashDisplay")
|
||||
|
||||
cdashdisplay.SetLogger(cds.Logger.With("[device]", "cdashdisplay"))
|
||||
|
||||
display, err := cdashdisplay.NewCDashDisplay()
|
||||
if err != nil {
|
||||
cds.Logger.Info("didn't find cdashdisplay")
|
||||
cds.Messages <- "didn't find cdash display\n"
|
||||
return
|
||||
}
|
||||
|
||||
cds.CDash = display
|
||||
cds.Logger.Info("found cdashdisplay on: " + display.WT.Cfg.Name)
|
||||
cds.Messages <- "found cdashdisplay on: " + display.WT.Cfg.Name + "\n"
|
||||
}
|
||||
@@ -1,27 +1,16 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
"esdi/tui/internal/dom"
|
||||
"slices"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
func AddAndShowPage(
|
||||
pages *tview.Pages,
|
||||
page *dom.UINode,
|
||||
changeFocus bool,
|
||||
) error {
|
||||
if !slices.Contains(pages.GetPageNames(false), page.ID) {
|
||||
pages.AddAndSwitchToPage(page.ID, page.Self, true)
|
||||
func AddAndShowPage(pages *tview.Pages, pageID string, page tview.Primitive) {
|
||||
if !slices.Contains(pages.GetPageNames(false), pageID) {
|
||||
pages.AddAndSwitchToPage(pageID, page, true)
|
||||
} else {
|
||||
// Only change to page
|
||||
pages.SwitchToPage(page.ID)
|
||||
pages.SwitchToPage(pageID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// func PageExists(pages *tview.Pages, needle string) bool {
|
||||
// return slices.Contains(pages.GetPageNames(false), needle)
|
||||
// }
|
||||
|
||||
@@ -58,22 +58,22 @@ func FindNodeByID(
|
||||
|
||||
func appendWindow(bus *events.Bus, doc *dom.DOM, tree *tview.TreeView, idx int16,
|
||||
win *cdashdisplay.UIWindow) {
|
||||
root := tree.GetRoot()
|
||||
if root == nil {
|
||||
bus.Emit(ui.LogEv{Log: "unable to get root of tree view"})
|
||||
return
|
||||
}
|
||||
|
||||
// Create the update tool
|
||||
updateForm := windowInfoForm(bus, doc, idx, win)
|
||||
|
||||
fmtTitle := fmt.Sprintf("%s [%2d]", win.Title.String(), idx)
|
||||
ref := windowReference{
|
||||
ID: idx,
|
||||
Form: updateForm,
|
||||
}
|
||||
newWindow := tview.NewTreeNode(fmtTitle).SetReference(&ref)
|
||||
root.AddChild(newWindow)
|
||||
// root := tree.GetRoot()
|
||||
// if root == nil {
|
||||
// bus.Emit(ui.LogEv{Log: "unable to get root of tree view"})
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Create the update tool
|
||||
// updateForm := windowInfoForm(bus, doc, idx, win)
|
||||
//
|
||||
// fmtTitle := fmt.Sprintf("%s [%2d]", win.Title.String(), idx)
|
||||
// ref := windowReference{
|
||||
// ID: idx,
|
||||
// Form: updateForm,
|
||||
// }
|
||||
// newWindow := tview.NewTreeNode(fmtTitle).SetReference(&ref)
|
||||
// root.AddChild(newWindow)
|
||||
}
|
||||
|
||||
func BindWindowEvents(
|
||||
@@ -150,54 +150,6 @@ func getCurNodeRef(tree *tview.TreeView) (*windowReference, error) {
|
||||
return winRef, nil
|
||||
}
|
||||
|
||||
func layoutToolTreeViewEvCapture(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:
|
||||
bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(DeviceAPIListID)})
|
||||
}
|
||||
|
||||
switch event.Rune() {
|
||||
case 'n':
|
||||
// Create a new window
|
||||
bus.Emit(ui.LogEv{Log: "calling new window form\n"})
|
||||
createNewWindowForm(bus, doc)
|
||||
case 'x':
|
||||
// Delete selected window
|
||||
bus.Emit(ui.LogEv{Log: "calling delete window\n"})
|
||||
wRef, err := getCurNodeRef(tree)
|
||||
if err != nil {
|
||||
bus.Emit(ui.LogEv{Log: " -> " + err.Error()})
|
||||
break
|
||||
}
|
||||
bus.Emit(ui.DestroyWindowEv{ID: wRef.ID})
|
||||
case 'm':
|
||||
// Go into move mode
|
||||
bus.Emit(ui.LogEv{Log: "calling window manipulation tool\n"})
|
||||
wRef, err := getCurNodeRef(tree)
|
||||
if err != nil {
|
||||
bus.Emit(ui.LogEv{Log: " -> " + err.Error()})
|
||||
break
|
||||
}
|
||||
windowManipulationTool(bus, doc, wRef.ID)
|
||||
case 'e':
|
||||
// Go into edit mode
|
||||
case 's':
|
||||
// Save the current layout
|
||||
bus.Emit(ui.SaveLayoutEv{})
|
||||
case 'l':
|
||||
// Load the layout
|
||||
bus.Emit(ui.LoadLayoutEv{})
|
||||
case 'g':
|
||||
// Go -> launches the current set up source
|
||||
streamingWindow(bus, doc)
|
||||
}
|
||||
|
||||
return event
|
||||
}
|
||||
}
|
||||
|
||||
func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview.TreeNode) {
|
||||
// Set focus to our new tool
|
||||
// if changeFocus {
|
||||
@@ -205,21 +157,21 @@ func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview.
|
||||
// }
|
||||
|
||||
return func(node *tview.TreeNode) {
|
||||
// Here we want to change the current existing form on the action pages
|
||||
nodeRef := node.GetReference()
|
||||
if nodeRef == nil {
|
||||
// its probably root I guess, thats what I'll believe
|
||||
return
|
||||
}
|
||||
|
||||
nodeWinRef := nodeRef.(*windowReference)
|
||||
|
||||
bus.Emit(ui.LogEv{
|
||||
Log: fmt.Sprintf("changing to -> %d | %s\n", nodeWinRef.ID, nodeWinRef.Form.ID),
|
||||
})
|
||||
|
||||
pages := doc.GetElemByID(LayoutToolActionPagesID)
|
||||
AddAndShowPage(pages.(*tview.Pages), nodeWinRef.Form, false)
|
||||
// // Here we want to change the current existing form on the action pages
|
||||
// nodeRef := node.GetReference()
|
||||
// if nodeRef == nil {
|
||||
// // its probably root I guess, thats what I'll believe
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// nodeWinRef := nodeRef.(*windowReference)
|
||||
//
|
||||
// bus.Emit(ui.LogEv{
|
||||
// Log: fmt.Sprintf("changing to -> %d | %s\n", nodeWinRef.ID, nodeWinRef.Form.ID),
|
||||
// })
|
||||
//
|
||||
// pages := doc.GetElemByID(LayoutToolActionPagesID)
|
||||
// AddAndShowPage(pages.(*tview.Pages), nodeWinRef.Form, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,75 +191,87 @@ func layoutToolTreeViewOnSelect(bus *events.Bus) func(node *tview.TreeNode) {
|
||||
}
|
||||
}
|
||||
|
||||
func buildLayoutTreeComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) {
|
||||
layoutTree := tview.NewTreeView()
|
||||
type LayoutTreeView struct {
|
||||
Tree *tview.TreeView
|
||||
InputCapture func(*tcell.EventKey) *tcell.EventKey
|
||||
OnChange func(node *tview.TreeNode)
|
||||
OnSelect func(node *tview.TreeNode)
|
||||
}
|
||||
|
||||
layoutTree.SetBorder(true).SetTitle("Layout Tree").
|
||||
SetInputCapture(layoutToolTreeViewEvCapture(bus, doc, layoutTree))
|
||||
|
||||
layoutTree.SetChangedFunc(layoutToolTreeViewOnChange(bus, doc))
|
||||
layoutTree.SetSelectedFunc(layoutToolTreeViewOnSelect(bus))
|
||||
|
||||
layoutTreeUINode, err := doc.NewUINode(LayoutToolTreeID,
|
||||
doc.GetElemByID(RightFlexID), layoutTree)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func NewLayoutTreeView() *LayoutTreeView {
|
||||
view := &LayoutTreeView{
|
||||
InputCapture: blankInputCapture,
|
||||
OnChange: blankTreeViewOnChange,
|
||||
OnSelect: blankTreeViewOnChange,
|
||||
}
|
||||
|
||||
view.Tree = tview.NewTreeView()
|
||||
|
||||
view.Tree.SetBorder(true).SetTitle("Layout Tree")
|
||||
view.Tree.SetInputCapture(view.InputCapture)
|
||||
view.Tree.SetChangedFunc(view.OnChange)
|
||||
view.Tree.SetSelectedFunc(view.OnSelect)
|
||||
|
||||
// view.Tree.SetChangedFunc(layoutToolTreeViewOnChange(bus, doc))
|
||||
// view.Tree.SetSelectedFunc(layoutToolTreeViewOnSelect(bus))
|
||||
|
||||
// Bind the events for the treeview
|
||||
BindWindowEvents(bus, doc, layoutTreeUINode.Self.(*tview.TreeView))
|
||||
// BindWindowEvents(bus, doc, layoutTreeUINode.Self.(*tview.TreeView))
|
||||
|
||||
// Create a root element
|
||||
rootElem := tview.NewTreeNode(".")
|
||||
layoutTree.SetRoot(rootElem).SetCurrentNode(rootElem)
|
||||
view.Tree.SetRoot(rootElem).SetCurrentNode(rootElem)
|
||||
|
||||
return layoutTreeUINode, nil
|
||||
return view
|
||||
}
|
||||
|
||||
func buildLayoutActionPagesComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) {
|
||||
type LayoutToolActionView struct {
|
||||
Pages *tview.Pages
|
||||
CreateWindowView *CreateWindowFormView
|
||||
}
|
||||
|
||||
func NewLayoutToolActionView() *LayoutToolActionView {
|
||||
view := &LayoutToolActionView{
|
||||
CreateWindowView: nil,
|
||||
}
|
||||
|
||||
// Create an empty page for it
|
||||
emptyPage := tview.NewTextView().
|
||||
SetTextAlign(tview.AlignCenter).
|
||||
SetChangedFunc(func() {
|
||||
bus.Emit(ui.RedrawEv{})
|
||||
})
|
||||
SetChangedFunc(func() {}) // Need to hook here
|
||||
|
||||
emptyPage.SetBorder(true).SetTitle("-- Tool Area --")
|
||||
fmt.Fprintf(emptyPage, "No tool selected")
|
||||
|
||||
actionPages := tview.NewPages().AddPage(EmptyPageName, emptyPage, true, true)
|
||||
view.Pages = tview.NewPages().AddPage(EmptyPageName, emptyPage, true, true)
|
||||
|
||||
actionPagesUINode, err := doc.NewUINode(LayoutToolActionPagesID,
|
||||
doc.GetElemByID("right-flex"), actionPages)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return actionPagesUINode, nil
|
||||
return view
|
||||
}
|
||||
|
||||
func buildLayoutFlexComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error) {
|
||||
type LayoutToolView struct {
|
||||
Flex *tview.Flex
|
||||
LayoutTree *LayoutTreeView
|
||||
LayoutActions *LayoutToolActionView
|
||||
}
|
||||
|
||||
func NewLayoutToolView() *LayoutToolView {
|
||||
view := &LayoutToolView{}
|
||||
|
||||
// Want a TreeView at the top
|
||||
layoutTreeUINode, err := buildLayoutTreeComponent(bus, doc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
view.LayoutTree = NewLayoutTreeView()
|
||||
|
||||
// Want pages below to run actions
|
||||
actionPagesUINode, err := buildLayoutActionPagesComponent(bus, doc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
view.LayoutActions = NewLayoutToolActionView()
|
||||
|
||||
layoutToolFlex := tview.NewFlex().SetDirection(tview.FlexRow)
|
||||
layoutToolFlexNode, err := doc.NewUINode(LayoutToolFlexID,
|
||||
doc.GetElemByID(APIToolPagesID), layoutToolFlex)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Create the flex
|
||||
view.Flex = tview.NewFlex().SetDirection(tview.FlexRow)
|
||||
|
||||
layoutToolFlex.
|
||||
AddItem(layoutTreeUINode.Self, 0, 2, true).
|
||||
AddItem(actionPagesUINode.Self, 0, 5, false)
|
||||
view.Flex.
|
||||
AddItem(view.LayoutTree.Tree, 0, 2, true).
|
||||
AddItem(view.LayoutActions.Pages, 0, 5, false)
|
||||
|
||||
return layoutToolFlexNode, nil
|
||||
return view
|
||||
}
|
||||
|
||||
func (ltv *LayoutToolView) AddWindow() {
|
||||
}
|
||||
|
||||
@@ -2,274 +2,165 @@ package views
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"esdi/cdashdisplay"
|
||||
"esdi/tui/internal/dom"
|
||||
"esdi/tui/internal/events"
|
||||
"esdi/tui/internal/models"
|
||||
"esdi/tui/internal/ui"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
// Validate the form inputs
|
||||
func validateFormInputs(x, y, w, h,
|
||||
title, prev, titleSize, textSize string,
|
||||
showID bool) (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
|
||||
}
|
||||
titleSizeValue, err := strconv.ParseUint(titleSize, 10, 64)
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
}
|
||||
textSizeValue, err := strconv.ParseUint(textSize, 10, 64)
|
||||
if err != nil {
|
||||
return models.Window{}, err
|
||||
}
|
||||
|
||||
showIDValue := cdashdisplay.ShowIDFalse
|
||||
if showID {
|
||||
showIDValue = cdashdisplay.ShowIDTrue
|
||||
}
|
||||
|
||||
return models.Window{
|
||||
X: uint16(xValue),
|
||||
Y: uint16(yValue),
|
||||
Width: uint16(widthValue),
|
||||
Height: uint16(heightValue),
|
||||
ShowID: showIDValue,
|
||||
TitleSize: uint8(titleSizeValue),
|
||||
TextSize: uint8(textSizeValue),
|
||||
PreviewValue: prev,
|
||||
Title: title,
|
||||
}, nil
|
||||
type CDashDisplayWindowFormView struct {
|
||||
Form *tview.Form
|
||||
X *tview.InputField
|
||||
Y *tview.InputField
|
||||
Width *tview.InputField
|
||||
Height *tview.InputField
|
||||
Title *tview.InputField
|
||||
PreviewValue *tview.InputField
|
||||
ShowID *tview.Checkbox
|
||||
WinType *tview.DropDown
|
||||
TitleSize *tview.DropDown
|
||||
TextSize *tview.DropDown
|
||||
}
|
||||
|
||||
func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
|
||||
var err error
|
||||
func NewCDashDisplayWindowFormView() *CDashDisplayWindowFormView {
|
||||
view := &CDashDisplayWindowFormView{}
|
||||
|
||||
x0 := tview.NewInputField().SetLabel("x")
|
||||
y0 := tview.NewInputField().SetLabel("y")
|
||||
width := tview.NewInputField().SetLabel("width")
|
||||
height := tview.NewInputField().SetLabel("height")
|
||||
title := tview.NewInputField().SetLabel("title")
|
||||
previewValue := tview.NewInputField().SetLabel("preview value")
|
||||
showID := tview.NewCheckbox().SetLabel("show ID").SetChecked(true)
|
||||
winType := tview.NewDropDown().SetLabel("type").
|
||||
SetOptions([]string{"string", "bar"}, func(s string, id int) {
|
||||
// Here we have to add extra options for the configuration of default
|
||||
// values and so on
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
titleSize := tview.NewDropDown().SetLabel("Title Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8"}, func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
textSize := tview.NewDropDown().SetLabel("Text Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8"}, func(s string, id int) {
|
||||
}).
|
||||
view.X = tview.NewInputField().SetLabel("x")
|
||||
view.Y = tview.NewInputField().SetLabel("y")
|
||||
view.Width = tview.NewInputField().SetLabel("width")
|
||||
view.Height = tview.NewInputField().SetLabel("height")
|
||||
view.Title = tview.NewInputField().SetLabel("title")
|
||||
view.PreviewValue = tview.NewInputField().SetLabel("preview value")
|
||||
view.ShowID = tview.NewCheckbox().SetLabel("show ID").SetChecked(true)
|
||||
view.WinType = tview.NewDropDown().SetLabel("type").
|
||||
SetOptions([]string{"string", "bar"}, func(s string, id int) {}).
|
||||
SetCurrentOption(0)
|
||||
view.TitleSize = tview.NewDropDown().SetLabel("Title Size").SetCurrentOption(0)
|
||||
for k := range 20 {
|
||||
view.TitleSize.AddOption(fmt.Sprintf("%d", k+1), blankDropdownOptionCallback)
|
||||
}
|
||||
view.TitleSize.SetCurrentOption(0)
|
||||
|
||||
form := tview.NewForm().
|
||||
AddFormItem(x0).
|
||||
AddFormItem(y0).
|
||||
AddFormItem(width).
|
||||
AddFormItem(height).
|
||||
AddFormItem(title).
|
||||
AddFormItem(previewValue).
|
||||
AddFormItem(showID).
|
||||
AddFormItem(winType).
|
||||
AddFormItem(titleSize).
|
||||
AddFormItem(textSize).
|
||||
AddButton("Create", func() {
|
||||
_, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
_, textSizeTxt := textSize.GetCurrentOption()
|
||||
// Validate the inputs
|
||||
window, err := validateFormInputs(
|
||||
x0.GetText(),
|
||||
y0.GetText(),
|
||||
width.GetText(),
|
||||
height.GetText(),
|
||||
title.GetText(),
|
||||
previewValue.GetText(),
|
||||
titleSizeTxt,
|
||||
textSizeTxt,
|
||||
showID.IsChecked(),
|
||||
)
|
||||
view.TextSize = tview.NewDropDown().SetLabel("Text Size")
|
||||
for k := range 20 {
|
||||
view.TextSize.AddOption(fmt.Sprintf("%d", k+1), blankDropdownOptionCallback)
|
||||
}
|
||||
view.TitleSize.SetCurrentOption(0)
|
||||
|
||||
if err != nil {
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())})
|
||||
return
|
||||
}
|
||||
view.Form = tview.NewForm().
|
||||
AddFormItem(view.X).
|
||||
AddFormItem(view.Y).
|
||||
AddFormItem(view.Width).
|
||||
AddFormItem(view.Height).
|
||||
AddFormItem(view.Title).
|
||||
AddFormItem(view.PreviewValue).
|
||||
AddFormItem(view.ShowID).
|
||||
AddFormItem(view.WinType).
|
||||
AddFormItem(view.TitleSize).
|
||||
AddFormItem(view.TextSize)
|
||||
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
bus.Emit(ui.CreateWindowEv{Window: window})
|
||||
})
|
||||
view.Form.SetBorder(true).
|
||||
SetTitle("New Window Form").
|
||||
SetTitleAlign(tview.AlignLeft)
|
||||
// Need to inject the event capture later
|
||||
|
||||
form.SetBorder(true).
|
||||
SetTitle("new window form").
|
||||
SetTitleAlign(tview.AlignLeft).
|
||||
SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEscape:
|
||||
bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(LayoutToolFlexID)})
|
||||
}
|
||||
return view
|
||||
}
|
||||
|
||||
return ev
|
||||
})
|
||||
type CreateWindowFormView struct {
|
||||
Form *CDashDisplayWindowFormView
|
||||
CreateBtn *tview.Button
|
||||
}
|
||||
|
||||
var formNode *dom.UINode
|
||||
formNode = doc.GetNodeByID("new-window-form")
|
||||
if formNode == nil {
|
||||
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())
|
||||
}
|
||||
func NewCreateWindowFormView() *CreateWindowFormView {
|
||||
view := &CreateWindowFormView{
|
||||
Form: NewCDashDisplayWindowFormView(),
|
||||
}
|
||||
|
||||
AddAndShowPage(doc.GetElemByID(LayoutToolActionPagesID).(*tview.Pages), formNode, true)
|
||||
view.CreateBtn = tview.NewButton("Create")
|
||||
// Need to inject the button functionality later
|
||||
|
||||
view.Form.Form.AddButton("Create", func() {})
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
func windowInfoPageID(idx int16) string {
|
||||
return fmt.Sprintf("layout-tool-win-info-%d", idx)
|
||||
type WindowFormView struct {
|
||||
Form *CDashDisplayWindowFormView
|
||||
UpdateBtn *tview.Button
|
||||
}
|
||||
|
||||
func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
|
||||
win *cdashdisplay.UIWindow) *dom.UINode {
|
||||
var err error
|
||||
func NewWindowFormView(win *cdashdisplay.UIWindow) *WindowFormView {
|
||||
view := &WindowFormView{
|
||||
Form: NewCDashDisplayWindowFormView(),
|
||||
}
|
||||
|
||||
x0 := tview.NewInputField().SetLabel("x").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.X0))
|
||||
y0 := tview.NewInputField().SetLabel("y").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Y0))
|
||||
width := tview.NewInputField().SetLabel("width").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Width))
|
||||
height := tview.NewInputField().SetLabel("height").
|
||||
SetText(fmt.Sprintf("%d", win.Dims.Height))
|
||||
title := tview.NewInputField().SetLabel("title").
|
||||
SetText(win.Title.String())
|
||||
previewValue := tview.NewInputField().SetLabel("preview value").
|
||||
SetText(win.Opts.PreviewValue.String())
|
||||
showID := tview.NewCheckbox().SetLabel("show ID").SetChecked(true)
|
||||
winType := tview.NewDropDown().SetLabel("type").
|
||||
SetOptions([]string{"string", "bar"}, func(s string, id int) {
|
||||
// Here we have to add extra options for the configuration of default
|
||||
// values and so on
|
||||
}).
|
||||
SetCurrentOption(0)
|
||||
// NOTE: put this thing into a loop that generate the numbers or something yo
|
||||
titleSize := tview.NewDropDown().SetLabel("Title Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"},
|
||||
func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(int(win.Decor.TitleSize))
|
||||
textSize := tview.NewDropDown().SetLabel("Text Size").
|
||||
SetOptions([]string{"1", "2", "3", "4", "5", "6", "7", "8", "9", "10",
|
||||
"11", "12", "13", "14", "15", "16", "17", "18", "19", "20"},
|
||||
func(s string, id int) {
|
||||
}).
|
||||
SetCurrentOption(int(win.Decor.TextSize))
|
||||
|
||||
form := tview.NewForm().
|
||||
AddFormItem(x0).
|
||||
AddFormItem(y0).
|
||||
AddFormItem(width).
|
||||
AddFormItem(height).
|
||||
AddFormItem(title).
|
||||
AddFormItem(previewValue).
|
||||
AddFormItem(showID).
|
||||
AddFormItem(titleSize).
|
||||
AddFormItem(textSize).
|
||||
AddFormItem(winType).
|
||||
AddButton("Update", func() {
|
||||
bus.Emit(ui.LogEv{Log: "update event was created\n"})
|
||||
|
||||
_, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
_, textSizeTxt := textSize.GetCurrentOption()
|
||||
// Validate the inputs
|
||||
window, err := validateFormInputs(
|
||||
x0.GetText(),
|
||||
y0.GetText(),
|
||||
width.GetText(),
|
||||
height.GetText(),
|
||||
title.GetText(),
|
||||
previewValue.GetText(),
|
||||
titleSizeTxt,
|
||||
textSizeTxt,
|
||||
showID.IsChecked(),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())})
|
||||
return
|
||||
}
|
||||
|
||||
bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
bus.Emit(ui.LogEv{Log: "sending update window ev\n"})
|
||||
bus.Emit(ui.UpdateWindowEv{ID: idx, Window: window})
|
||||
})
|
||||
|
||||
form.SetBorder(true).
|
||||
SetTitle(fmt.Sprintf("Info - %s [%2d]", win.Title.String(), idx)).
|
||||
SetTitleAlign(tview.AlignLeft).
|
||||
SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEscape:
|
||||
bus.Emit(ui.ChangeFocusEv{Target: doc.GetElemByID(LayoutToolTreeID)})
|
||||
}
|
||||
|
||||
return ev
|
||||
})
|
||||
view.UpdateBtn = tview.NewButton("Update")
|
||||
// Need to inject the button functionality later
|
||||
// AddButton("Update", func() {
|
||||
// bus.Emit(ui.LogEv{Log: "update event was created\n"})
|
||||
//
|
||||
// _, titleSizeTxt := titleSize.GetCurrentOption()
|
||||
// _, textSizeTxt := textSize.GetCurrentOption()
|
||||
// // Validate the inputs
|
||||
// window, err := validateFormInputs(
|
||||
// x0.GetText(),
|
||||
// y0.GetText(),
|
||||
// width.GetText(),
|
||||
// height.GetText(),
|
||||
// title.GetText(),
|
||||
// previewValue.GetText(),
|
||||
// titleSizeTxt,
|
||||
// textSizeTxt,
|
||||
// showID.IsChecked(),
|
||||
// )
|
||||
//
|
||||
// if err != nil {
|
||||
// bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())})
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// bus.Emit(ui.LogEv{Log: fmt.Sprintf("showID: %d\n", window.ShowID)})
|
||||
// bus.Emit(ui.LogEv{Log: "sending update window ev\n"})
|
||||
// bus.Emit(ui.UpdateWindowEv{ID: idx, Window: window})
|
||||
// })
|
||||
|
||||
// In case the window is moved we need to update this form
|
||||
bus.On(ui.WindowMovedEv{}, func(e any) {
|
||||
data := e.(ui.WindowMovedEv)
|
||||
// Only update the fields if the event is for this thing
|
||||
if data.ID != idx {
|
||||
return
|
||||
}
|
||||
// bus.On(ui.WindowMovedEv{}, func(e any) {
|
||||
// data := e.(ui.WindowMovedEv)
|
||||
// // Only update the fields if the event is for this thing
|
||||
// if data.ID != idx {
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// // Get the current window-info-page
|
||||
// elem := doc.GetElemByID(windowInfoPageID(data.ID))
|
||||
// if elem == nil {
|
||||
// bus.Emit(ui.LogEv{Log: "could't get hold of info page"})
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// x0.SetText(fmt.Sprintf("%d", data.Dims.X0))
|
||||
// x0.SetText(fmt.Sprintf("%d", data.Dims.Y0))
|
||||
// width.SetText(fmt.Sprintf("%d", data.Dims.Width))
|
||||
// height.SetText(fmt.Sprintf("%d", data.Dims.Height))
|
||||
// })
|
||||
|
||||
// Get the current window-info-page
|
||||
elem := doc.GetElemByID(windowInfoPageID(data.ID))
|
||||
if elem == nil {
|
||||
bus.Emit(ui.LogEv{Log: "could't get hold of info page"})
|
||||
return
|
||||
}
|
||||
// Set the fields data
|
||||
view.Form.X.SetText(fmt.Sprintf("%d", win.Dims.X0))
|
||||
view.Form.Y.SetText(fmt.Sprintf("%d", win.Dims.Y0))
|
||||
view.Form.Width.SetText(fmt.Sprintf("%d", win.Dims.Width))
|
||||
view.Form.Height.SetText(fmt.Sprintf("%d", win.Dims.Height))
|
||||
view.Form.Title.SetText(win.Title.String())
|
||||
view.Form.PreviewValue.SetText(win.Opts.PreviewValue.String())
|
||||
view.Form.ShowID.SetChecked(win.Opts.ShowID == 1)
|
||||
view.Form.WinType.SetCurrentOption(0) // NOTE: this needs to set the correct option
|
||||
view.Form.TitleSize.SetCurrentOption(int(win.Decor.TitleSize))
|
||||
view.Form.TextSize.SetCurrentOption(int(win.Decor.TextSize))
|
||||
|
||||
x0.SetText(fmt.Sprintf("%d", data.Dims.X0))
|
||||
x0.SetText(fmt.Sprintf("%d", data.Dims.Y0))
|
||||
width.SetText(fmt.Sprintf("%d", data.Dims.Width))
|
||||
height.SetText(fmt.Sprintf("%d", data.Dims.Height))
|
||||
})
|
||||
return view
|
||||
}
|
||||
|
||||
var formNode *dom.UINode
|
||||
elemID := windowInfoPageID(idx)
|
||||
formNode = doc.GetNodeByID(elemID)
|
||||
layoutToolActionPagesElem := doc.GetElemByID(LayoutToolActionPagesID)
|
||||
if formNode == nil {
|
||||
formNode, err = doc.NewUINode(elemID, layoutToolActionPagesElem, form)
|
||||
if err != nil {
|
||||
panic("failed to create UI node for the new window form: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
return formNode
|
||||
func WindowInfoPageID(idx int16) string {
|
||||
return fmt.Sprintf("layout-tool-win-info-%d", idx)
|
||||
}
|
||||
|
||||
@@ -168,5 +168,5 @@ func windowManipulationTool(bus *events.Bus, doc *dom.DOM, idx int16) {
|
||||
}
|
||||
|
||||
box.SetInputCapture(windowManipulationEvCapture(bus, doc, idx, &state))
|
||||
AddAndShowPage(actionPages, boxNode, true)
|
||||
// AddAndShowPage(actionPages, boxNode, true)
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func streamingWindow(bus *events.Bus, doc *dom.DOM) {
|
||||
}
|
||||
|
||||
// Add it to the action pages and view it
|
||||
AddAndShowPage(actionPages, boxNode, true)
|
||||
// AddAndShowPage(actionPages, boxNode, true)
|
||||
|
||||
bus.Emit(ui.StartStreamingReqEv{})
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
package views
|
||||
|
||||
import (
|
||||
"github.com/gdamore/tcell/v2"
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
var (
|
||||
blankInputCapture = func(ev *tcell.EventKey) *tcell.EventKey { return ev }
|
||||
blankTreeViewOnChange = func(node *tview.TreeNode) {}
|
||||
blankDropdownOptionCallback = func() {}
|
||||
)
|
||||
+36
-1
@@ -3,10 +3,45 @@ package tui
|
||||
|
||||
import (
|
||||
"esdi/tui/internal/controllers"
|
||||
"esdi/tui/internal/dom"
|
||||
"esdi/tui/internal/events"
|
||||
"esdi/tui/internal/services"
|
||||
"log/slog"
|
||||
|
||||
"github.com/rivo/tview"
|
||||
)
|
||||
|
||||
type ControlPanel struct {
|
||||
*controllers.Controller
|
||||
|
||||
DeviceController *controllers.DeviceController
|
||||
}
|
||||
|
||||
func NewControlPanel(logger *slog.Logger) *ControlPanel {
|
||||
baseController := &controllers.Controller{
|
||||
Logger: logger,
|
||||
Bus: events.NewBus(),
|
||||
App: tview.NewApplication(),
|
||||
Dom: dom.NewDOM(),
|
||||
}
|
||||
|
||||
deviceService := services.NewCDashService(logger)
|
||||
|
||||
return &ControlPanel{
|
||||
Controller: baseController,
|
||||
DeviceController: controllers.NewDeviceController(baseController, deviceService),
|
||||
}
|
||||
}
|
||||
|
||||
func (cp *ControlPanel) Run() error {
|
||||
if err := cp.DeviceController.Main(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return cp.App.Run()
|
||||
}
|
||||
|
||||
func Run(logger *slog.Logger) error {
|
||||
progController := controllers.NewControlPanel(logger)
|
||||
progController := NewControlPanel(logger)
|
||||
return progController.Run()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user