very bare bones layout selectable menu

This commit is contained in:
2026-06-09 16:39:13 +01:00
parent d3c4464aa0
commit 24fea285c3
6 changed files with 351 additions and 7 deletions
+67 -2
View File
@@ -2,6 +2,7 @@ package controllers
import (
"fmt"
"os"
"strconv"
"esdi/cdashdisplay"
@@ -20,6 +21,7 @@ type LayoutController struct {
Messages chan string
DevService *services.CDashService
MoveToolState *windowManipState
SelectedLayout string // NOTE: This should be a struct to handle its own things
}
func NewLayoutController(base *Controller, service *services.CDashService) *LayoutController {
@@ -29,6 +31,7 @@ func NewLayoutController(base *Controller, service *services.CDashService) *Layo
Messages: make(chan string, 10),
DevService: service,
MoveToolState: &windowManipState{Mode: moveMode},
SelectedLayout: "layout.yaml",
}
lc.registerHooks()
@@ -56,6 +59,9 @@ func (lc *LayoutController) registerHooks() {
case 'm':
lc.Messages <- "calling window manipulation tool\n"
lc.moveWindow()
case 'c':
lc.Messages <- "calling change selected layout tool\n"
lc.changeSelectedLoadout()
case 's':
// Save the current layout
lc.Messages <- "calling save layout\n"
@@ -64,6 +70,10 @@ func (lc *LayoutController) registerHooks() {
// Load the layout
lc.Messages <- "calling load layout\n"
lc.loadLayout()
case 'u':
// Unload the layout
lc.Messages <- "calling unload layout\n"
lc.unloadLayout()
case 'g':
// Go -> launches the current set up source
// streamingWindow(bus, doc)
@@ -339,7 +349,7 @@ func (lc *LayoutController) getCurrentTreeNodeModel() (*tview.TreeNode, int16, e
func (lc *LayoutController) loadLayout() {
// We would get the layout path from somewhere but for nots its layout.yaml
err := lc.DevService.LoadLayout("layout.yaml")
err := lc.DevService.LoadLayout(lc.SelectedLayout)
if err != nil {
lc.Messages <- "failed to load layout: " + err.Error()
return
@@ -348,8 +358,16 @@ func (lc *LayoutController) loadLayout() {
lc.displayLoadedLayouts()
}
func (lc *LayoutController) unloadLayout() {
err := lc.DevService.UnloadLayout()
if err != nil {
lc.Logger.Error(fmt.Sprintf("Failed to unload layout: %+v", err))
return
}
}
func (lc *LayoutController) saveLayout() {
err := lc.DevService.SaveLayout("layout.yaml")
err := lc.DevService.SaveLayout(lc.SelectedLayout)
if err != nil {
lc.Messages <- "failed to save layout: " + err.Error()
return
@@ -423,3 +441,50 @@ func (lc *LayoutController) moveWindow() {
lc.App.SetFocus(formView.Form)
}
// changeSelectedLoadout is used to change the currently selected loadout
// its a very bare bones utility to aid development
// NOTE: FOR THE LOVE OF WHATS HOLY ACTUALLY MAKE THIS GOOD BEFORE ADDING MORE FEATURES
func (lc *LayoutController) changeSelectedLoadout() {
// First we get the files in the layouts directory
entries, err := os.ReadDir("./layouts")
if err != nil {
lc.Logger.Error(fmt.Sprintf("Failed to read directory: %v", err))
return
}
// Then we open a modal and pass that list there
lc.Logger.Debug(fmt.Sprintf("Found layouts: %+v", entries))
layoutSelection := views.NewLayoutToolLayoutsList()
layoutSelection.AddEntries(entries)
layoutSelection.Tree.SetInputCapture(func(ev *tcell.EventKey) *tcell.EventKey {
switch ev.Key() {
case tcell.KeyESC:
// We have to destroy this window, but first we tell the pages to show something else
// NOTE: will this be left hanging and then given to GC? Can we improve that?
lc.LayoutToolView.LayoutActions.LayoutSelection = nil
lc.LayoutToolView.DeleteLayoutList()
lc.App.SetFocus(lc.LayoutToolView.LayoutTree.Tree)
}
return ev
})
layoutSelection.Tree.SetSelectedFunc(func(node *tview.TreeNode) {
ref := node.GetReference()
if ref == nil {
return
}
lc.Messages <- "User selected " + fmt.Sprintf("%+v", ref) + "\n"
lc.SelectedLayout = ref.(string)
lc.LayoutToolView.LayoutTree.Tree.SetTitle(fmt.Sprintf("%s [%s]",
views.LayoutToolTreeViewTitle, ref.(string)))
})
lc.LayoutToolView.LayoutActions.LayoutSelection = layoutSelection
lc.LayoutToolView.ShowLayoutList()
lc.App.SetFocus(lc.LayoutToolView.LayoutActions.LayoutSelection.Tree)
}
+8 -3
View File
@@ -1,13 +1,14 @@
package services
import (
"fmt"
"log/slog"
"sync/atomic"
"esdi/cdashdisplay"
helper "esdi/helpers"
"esdi/peripheral"
"esdi/telemetry"
"fmt"
"log/slog"
"sync/atomic"
)
type CDashService struct {
@@ -65,6 +66,10 @@ func (cds *CDashService) SaveLayout(layoutPath string) error {
return cds.CDash.SaveLayout(layoutPath)
}
func (cds *CDashService) UnloadLayout() error {
return cds.CDash.UnloadLayout()
}
func (cds *CDashService) UpdateWindow(win *cdashdisplay.DesktopUIWindow) error {
cds.Messages <- fmt.Sprintf("Updating a window:\n%+v\n", win)
return cds.CDash.UpdateWindow(win)
+15 -1
View File
@@ -12,6 +12,7 @@ import (
)
const (
LayoutToolTreeViewTitle = "Layout Tree"
LayoutToolFlexID = "layout-tool-flex"
LayoutToolTreeID = "layout-tool-tree"
LayoutToolActionPagesID = "layout-tool-action-pages"
@@ -30,7 +31,7 @@ func NewLayoutTreeView() *LayoutTreeView {
view.Tree = tview.NewTreeView()
view.Tree.SetBorder(true).SetTitle("Layout Tree")
view.Tree.SetBorder(true).SetTitle(LayoutToolTreeViewTitle)
view.Tree.SetInputCapture(view.InputCapture)
// Inject ChangedFunc
// Inject SelectedFunc
@@ -61,6 +62,7 @@ func (lt *LayoutTreeView) AddWindow(win *cdashdisplay.DesktopUIWindow) error {
type LayoutToolActionView struct {
Pages *tview.Pages
CreateWindowView *CreateWindowFormView
LayoutSelection *LayoutToolLayoutsList
}
func NewLayoutToolActionView() *LayoutToolActionView {
@@ -154,6 +156,18 @@ func (ltv *LayoutToolView) ShowWindowFormByID(idx int16) {
)
}
func (ltv *LayoutToolView) ShowLayoutList() {
AddAndShowPage(
ltv.LayoutActions.Pages,
"available-layouts-list",
ltv.LayoutActions.LayoutSelection.Tree,
)
}
func (ltv *LayoutToolView) DeleteLayoutList() {
ltv.LayoutActions.Pages.RemovePage("available-layouts-list")
}
func (ltv *LayoutToolView) DeleteWindowByNode(node *tview.TreeNode) {
root := ltv.LayoutTree.Tree.GetRoot()
if root == nil {
@@ -0,0 +1,45 @@
package views
import (
"os"
"github.com/rivo/tview"
)
type LayoutToolLayoutsList struct {
Tree *tview.TreeView
}
func NewLayoutToolLayoutsList() *LayoutToolLayoutsList {
view := &LayoutToolLayoutsList{}
view.Tree = tview.NewTreeView()
view.Tree.SetBorder(true).SetTitle("Layout List")
// Inject InputCapture
// Inject ChangedFunc
// Inject SelectedFunc
// Create a root element
rootElem := tview.NewTreeNode(".")
view.Tree.SetRoot(rootElem).SetCurrentNode(rootElem)
return view
}
// AddEntries adds the list of files we wish the user to select from
// For now we will send just a list of []string but in the future this should
// receive (or have an alternative to receive) a directory structure
func (ltll *LayoutToolLayoutsList) AddEntries(entries []os.DirEntry) {
root := ltll.Tree.GetRoot()
if root == nil {
// NOTE: shouldn't happen at all
return
}
for _, e := range entries {
node := tview.NewTreeNode(e.Name()).
SetReference(e.Name())
root.AddChild(node)
}
}