Added the window updated command, can update titles now. Very nice

This commit is contained in:
2026-02-13 23:36:27 +00:00
parent 9fde9ccd5f
commit c0e33c3585
10 changed files with 237 additions and 48 deletions
+3 -5
View File
@@ -1,7 +1,5 @@
# TASK # TASK
- [ ] Add a way to manage the windows in the layout tool UI - [ ] Add a way to manage the windows in the layout tool UI
we need to be able to create a new windw: - [X] need to create the new form that changes in the action pages
-> creates a new form we can edit - [ ] form must reflect updates to the window data on other tools like
-> on creation updates that form to be an updatable window the move tool. Can update it OnChange function
when traversing the layouttreeview:
-> update the tool page so we can jump to edit and update window info
+32 -25
View File
@@ -32,7 +32,8 @@ const (
newWindowCMDID types.Command = 3 newWindowCMDID types.Command = 3
destroyWindowCMDID types.Command = 4 destroyWindowCMDID types.Command = 4
updateWindowDimsCMDID types.Command = 5 updateWindowDimsCMDID types.Command = 5
newLayoutCMDID types.Command = 6 updateWindowCMDID types.Command = 6 // Change this to a move cmd instead
newLayoutCMDID types.Command = 7
) )
const ( const (
@@ -53,29 +54,11 @@ var DefaultDecorations = UIDecorations{
Padding: 0x00, Padding: 0x00,
} }
type UIDimensions struct {
X0 uint16 `yaml:"X0"`
Y0 uint16 `yaml:"Y0"`
Width uint16 `yaml:"Width"`
Height uint16 `yaml:"Height"`
}
type UpdateDimsPacket struct { type UpdateDimsPacket struct {
ID int16 ID int16
Dims UIDimensions Dims UIDimensions
} }
type UIDecorations struct {
BGColour uint16 `yaml:"BGColour"`
FGColour uint16 `yaml:"FGColour"`
TitleColour uint16 `yaml:"TitleColour"`
BorderColour uint16 `yaml:"BorderColour"`
TitleSize uint8 `yaml:"TitleSize"`
TextSize uint8 `yaml:"TextSize"`
HasBorder uint8 `yaml:"HasBorder"`
Padding uint8 `yaml:"Padding"`
}
type FString32 [32]byte type FString32 [32]byte
func (s FString32) String() string { func (s FString32) String() string {
@@ -115,12 +98,6 @@ func (s *FString32) UnmarshalYAML(value *yaml.Node) error {
return nil return nil
} }
type UIWindow struct {
Dims UIDimensions `yaml:"Dims"`
Decor UIDecorations `yaml:"Decor"`
Title FString32 `yaml:"Title"`
}
type LayoutTree struct { type LayoutTree struct {
Windows map[int16]*UIWindow `yaml:"Windows"` Windows map[int16]*UIWindow `yaml:"Windows"`
} }
@@ -195,6 +172,36 @@ func (d *CDashDisplay) CreateWindow(win UIWindow) (int16, error) {
return wID.ID, nil return wID.ID, nil
} }
func (d *CDashDisplay) UpdateWindow(wID int16, win *UIWindow) error {
data := UIWindowUpdatePacket{
WinID: wID,
Window: *win,
}
bytes, err := helper.StructToBytes(data)
if err != nil {
return err
}
err = d.WT.SendCommand(updateWindowCMDID, bytes, nil)
if err != nil {
return err
}
// NOTE: need to check the flow of this because:
// windows has a pointer to a UIWindow stored
// I get it and update it in the controller
// I send the pointer here
// -> it should be the same pointer then right?
pLogger.Debug(fmt.Sprintf("PreUpdate ID: %p", win))
d.State.Layout.Windows[wID] = win
pLogger.Debug(fmt.Sprintf("PostUpdate ID: %p", win))
// Yeah, same address as suspected
// I can't think about it right now. I'll think about that tomorrow
return nil
}
func (d *CDashDisplay) DestroyWindow(wID int16) error { func (d *CDashDisplay) DestroyWindow(wID int16) error {
type UIWindowDestructPacket struct { type UIWindowDestructPacket struct {
WinID int16 WinID int16
+4
View File
@@ -0,0 +1,4 @@
package cdashdisplay
type layoutManager struct {
}
+33
View File
@@ -0,0 +1,33 @@
package cdashdisplay
// In this file we will place all structs that are 1:1 representation of the
// types in the device transport layer ->
type UIDimensions struct {
X0 uint16 `yaml:"X0"`
Y0 uint16 `yaml:"Y0"`
Width uint16 `yaml:"Width"`
Height uint16 `yaml:"Height"`
}
type UIDecorations struct {
BGColour uint16 `yaml:"BGColour"`
FGColour uint16 `yaml:"FGColour"`
TitleColour uint16 `yaml:"TitleColour"`
BorderColour uint16 `yaml:"BorderColour"`
TitleSize uint8 `yaml:"TitleSize"`
TextSize uint8 `yaml:"TextSize"`
HasBorder uint8 `yaml:"HasBorder"`
Padding uint8 `yaml:"Padding"`
}
type UIWindow struct {
Dims UIDimensions `yaml:"Dims"`
Decor UIDecorations `yaml:"Decor"`
Title FString32 `yaml:"Title"`
}
type UIWindowUpdatePacket struct {
WinID int16
Window UIWindow
}
+23 -1
View File
@@ -84,11 +84,33 @@ func NewMainController(logger *slog.Logger) *MainController {
return return
} }
mc.EvBus.Emit(ui.WindowCreatedEv{ID: wID, Title: win.Title}) mc.EvBus.Emit(ui.WindowCreatedEv{ID: wID, Win: uiWindow})
mc.EvBus.Emit(ui.PrintLogEv{Log: "Window created!\n"}) mc.EvBus.Emit(ui.PrintLogEv{Log: "Window created!\n"})
}() }()
}) })
mc.EvBus.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"})
return
}
curWindow.Dims.X0 = winModel.Window.X
curWindow.Dims.Y0 = winModel.Window.Y
curWindow.Dims.Width = winModel.Window.Width
curWindow.Dims.Height = winModel.Window.Height
curWindow.Title = helper.B32(winModel.Window.Title)
err := mc.CDash.UpdateWindow(winModel.ID, curWindow)
if err != nil {
mc.EvBus.Emit(ui.PrintLogEv{Log: "failed to update window"})
}
})
mc.EvBus.On(ui.DestroyWindowEv{}, func(e any) { mc.EvBus.On(ui.DestroyWindowEv{}, func(e any) {
go func() { go func() {
pLogger.Info(fmt.Sprintf("Called in to destroy win: %d", e.(ui.DestroyWindowEv).ID)) pLogger.Info(fmt.Sprintf("Called in to destroy win: %d", e.(ui.DestroyWindowEv).ID))
+7 -2
View File
@@ -37,6 +37,11 @@ type RegisterLoadedLayout struct {
Layout cdashdisplay.LayoutTree Layout cdashdisplay.LayoutTree
} }
type UpdateWindowEv struct {
ID int16
Window models.Window
}
type CreateWindowEv struct { type CreateWindowEv struct {
Window models.Window Window models.Window
} }
@@ -60,8 +65,8 @@ type ResizeWindowEv struct {
} }
type WindowCreatedEv struct { type WindowCreatedEv struct {
ID int16 ID int16
Title string Win cdashdisplay.UIWindow
} }
type WindowDestroyedEv struct { type WindowDestroyedEv struct {
+10 -3
View File
@@ -9,8 +9,13 @@ import (
"github.com/rivo/tview" "github.com/rivo/tview"
) )
func AddAndShowPage(bus *events.Bus, doc *dom.DOM, func AddAndShowPage(
pages *tview.Pages, page *dom.UINode) error { bus *events.Bus,
doc *dom.DOM,
pages *tview.Pages,
page *dom.UINode,
changeFocus bool,
) error {
if !slices.Contains(pages.GetPageNames(false), page.ID) { if !slices.Contains(pages.GetPageNames(false), page.ID) {
pages.AddAndSwitchToPage(page.ID, page.Self, true) pages.AddAndSwitchToPage(page.ID, page.Self, true)
} else { } else {
@@ -19,7 +24,9 @@ func AddAndShowPage(bus *events.Bus, doc *dom.DOM,
} }
// Set focus to our new tool // Set focus to our new tool
bus.Emit(ui.ChangeFocusEv{Target: page.Self}) if changeFocus {
bus.Emit(ui.ChangeFocusEv{Target: page.Self})
}
return nil return nil
} }
+48 -10
View File
@@ -1,6 +1,7 @@
package views package views
import ( import (
"esdi/cdashdisplay"
"esdi/tui/internal/dom" "esdi/tui/internal/dom"
"esdi/tui/internal/events" "esdi/tui/internal/events"
"esdi/tui/internal/ui" "esdi/tui/internal/ui"
@@ -17,7 +18,8 @@ const (
) )
type windowReference struct { type windowReference struct {
ID int16 ID int16
Form *dom.UINode
} }
func getWindowRefFromNode(node *tview.TreeNode) *windowReference { func getWindowRefFromNode(node *tview.TreeNode) *windowReference {
@@ -54,16 +56,21 @@ func FindNodeByID(
return nil return nil
} }
func appendWindow(bus *events.Bus, tree *tview.TreeView, idx int16, title string) { func appendWindow(bus *events.Bus, doc *dom.DOM, tree *tview.TreeView, idx int16,
win *cdashdisplay.UIWindow) {
root := tree.GetRoot() root := tree.GetRoot()
if root == nil { if root == nil {
bus.Emit(ui.LogEv{Log: "unable to get root of tree view"}) bus.Emit(ui.LogEv{Log: "unable to get root of tree view"})
return return
} }
fmtTitle := fmt.Sprintf("%s [%2d]", title, idx) // Create the update tool
updateForm := windowInfoForm(bus, doc, idx, win)
fmtTitle := fmt.Sprintf("%s [%2d]", win.Title.String(), idx)
ref := windowReference{ ref := windowReference{
ID: idx, ID: idx,
Form: updateForm,
} }
newWindow := tview.NewTreeNode(fmtTitle).SetReference(&ref) newWindow := tview.NewTreeNode(fmtTitle).SetReference(&ref)
root.AddChild(newWindow) root.AddChild(newWindow)
@@ -79,7 +86,7 @@ func BindWindowEvents(
bus.On(ui.WindowCreatedEv{}, func(e any) { bus.On(ui.WindowCreatedEv{}, func(e any) {
go func() { go func() {
win := e.(ui.WindowCreatedEv) ev := e.(ui.WindowCreatedEv)
bus.Emit(ui.LogEv{Log: "Received a window created event\n"}) bus.Emit(ui.LogEv{Log: "Received a window created event\n"})
if tree == nil { if tree == nil {
@@ -87,7 +94,7 @@ func BindWindowEvents(
return return
} }
appendWindow(bus, tree, win.ID, win.Title) appendWindow(bus, doc, tree, ev.ID, &ev.Win)
}() }()
}) })
@@ -116,7 +123,7 @@ func BindWindowEvents(
layout := e.(ui.RegisterLoadedLayout) layout := e.(ui.RegisterLoadedLayout)
for idx, w := range layout.Layout.Windows { for idx, w := range layout.Layout.Windows {
appendWindow(bus, tree, idx, w.Title.String()) appendWindow(bus, doc, tree, idx, w)
} }
// bus.Emit(ui.ForceRedraw{}) // bus.Emit(ui.ForceRedraw{})
@@ -216,12 +223,42 @@ func layoutToolUIOnSelect(bus *events.Bus, doc *dom.DOM) {
} }
} }
AddAndShowPage(bus, doc, apiToolPages, layoutToolUINode) AddAndShowPage(bus, doc, apiToolPages, layoutToolUINode, true)
} }
func layoutToolTreeViewOnChange() func(node *tview.TreeNode) { func layoutToolTreeViewOnChange(bus *events.Bus, doc *dom.DOM) func(node *tview.TreeNode) {
return func(node *tview.TreeNode) { return func(node *tview.TreeNode) {
// Here we want to change the current existing form on the action pages // 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(bus, doc, pages.(*tview.Pages), nodeWinRef.Form, false)
}
}
func layoutToolTreeViewOnSelect(bus *events.Bus) func(node *tview.TreeNode) {
return func(node *tview.TreeNode) {
// Get the window reference which will have the ID for the form
bus.Emit(ui.LogEv{Log: "PRESSED ENTER\n"})
ref := node.GetReference()
if ref == nil {
bus.Emit(ui.LogEv{Log: "Couldn't find reference for node\n"})
return
}
nodeWinRef := ref.(*windowReference)
bus.Emit(ui.ChangeFocusEv{Target: nodeWinRef.Form.Self})
} }
} }
@@ -231,7 +268,8 @@ func buildLayoutTreeComponent(bus *events.Bus, doc *dom.DOM) (*dom.UINode, error
layoutTree.SetBorder(true).SetTitle("Layout Tree"). layoutTree.SetBorder(true).SetTitle("Layout Tree").
SetInputCapture(layoutToolTreeViewEvCapture(bus, doc, layoutTree)) SetInputCapture(layoutToolTreeViewEvCapture(bus, doc, layoutTree))
layoutTree.SetChangedFunc(layoutToolTreeViewOnChange()) layoutTree.SetChangedFunc(layoutToolTreeViewOnChange(bus, doc))
layoutTree.SetSelectedFunc(layoutToolTreeViewOnSelect(bus))
layoutTreeUINode, err := doc.NewUINode(layoutToolTreeID, layoutTreeUINode, err := doc.NewUINode(layoutToolTreeID,
doc.GetElemByID(rightFlexID), layoutTree) doc.GetElemByID(rightFlexID), layoutTree)
+76 -1
View File
@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"strconv" "strconv"
"esdi/cdashdisplay"
"esdi/tui/internal/dom" "esdi/tui/internal/dom"
"esdi/tui/internal/events" "esdi/tui/internal/events"
"esdi/tui/internal/models" "esdi/tui/internal/models"
@@ -104,5 +105,79 @@ func createNewWindowForm(bus *events.Bus, doc *dom.DOM) {
} }
AddAndShowPage(bus, doc, doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages), AddAndShowPage(bus, doc, doc.GetElemByID(layoutToolActionPagesID).(*tview.Pages),
formNode) formNode, true)
}
func windowInfoPageID(idx int16) string {
return fmt.Sprintf("layout-tool-win-info-%d", idx)
}
func windowInfoForm(bus *events.Bus, doc *dom.DOM, idx int16,
win *cdashdisplay.UIWindow) *dom.UINode {
var err error
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())
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)
form := tview.NewForm().
AddFormItem(x0).
AddFormItem(y0).
AddFormItem(width).
AddFormItem(height).
AddFormItem(title).
AddFormItem(winType).
AddButton("Update", func() {
bus.Emit(ui.LogEv{Log: "update event was created\n"})
// Validate the inputs
window, err := validateFormInputs(
x0.GetText(),
y0.GetText(),
width.GetText(),
height.GetText(),
title.GetText(),
)
if err != nil {
bus.Emit(ui.LogEv{Log: fmt.Sprintf("failed to parse form: %s\n", err.Error())})
return
}
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
})
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())
}
}
// AddAndShowPage(bus, doc, layoutToolActionPagesElem.(*tview.Pages), formNode)
return formNode
} }
@@ -168,5 +168,5 @@ func windowManipulationTool(bus *events.Bus, doc *dom.DOM, idx int16) {
} }
box.SetInputCapture(windowManipulationEvCapture(bus, doc, idx, &state)) box.SetInputCapture(windowManipulationEvCapture(bus, doc, idx, &state))
AddAndShowPage(bus, doc, actionPages, boxNode) AddAndShowPage(bus, doc, actionPages, boxNode, true)
} }