From fb43b88a0bee0b664c5763a6502502bb54e2c5d6 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Wed, 5 Apr 2023 13:06:42 -0500 Subject: [PATCH] gocui: rework spacing logic Signed-off-by: Jeff Carr --- toolkit/gocui/click.go | 7 ++- toolkit/gocui/common.go | 22 +++---- toolkit/gocui/debug.go | 29 +++++---- toolkit/gocui/keybindings.go | 1 - toolkit/gocui/log.go | 2 +- toolkit/gocui/logical.go | 2 + toolkit/gocui/place.go | 111 ++++++++++++++++++++++++++++++----- toolkit/gocui/plugin.go | 57 +++++++++++++++++- toolkit/gocui/structs.go | 25 ++++---- 9 files changed, 202 insertions(+), 54 deletions(-) diff --git a/toolkit/gocui/click.go b/toolkit/gocui/click.go index 142f00c..f755d45 100644 --- a/toolkit/gocui/click.go +++ b/toolkit/gocui/click.go @@ -23,10 +23,13 @@ func (w *cuiWidget) doWidgetClick() { case toolkit.Tab: w.redoBox(true) w.toggleTree() + case toolkit.Group: + w.redoBox(true) + w.toggleTree() case toolkit.Grid: - w.setParentLogical() + // w.setParentLogical() w.gridBounds() - w.setParentLogical() + // w.setParentLogical() for _, child := range w.children { child.showWidgetPlacement(logNow, "gridBounds:") if (child.v == nil) { diff --git a/toolkit/gocui/common.go b/toolkit/gocui/common.go index cfb177b..663994d 100644 --- a/toolkit/gocui/common.go +++ b/toolkit/gocui/common.go @@ -29,24 +29,22 @@ func setupWidget(a *toolkit.Action) *cuiWidget { // set the name used by gocui to the id w.cuiName = strconv.Itoa(w.id) - w.parent = findWidget(a.ParentId, me.rootNode) - log(logInfo, "setupWidget() w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId) - if (w.id == 0) { + if w.widgetType == toolkit.Root { + log(logInfo, "setupWidget() FOUND ROOT w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId) + w.id = 0 me.rootNode = w - // this is the rootNode return w } + + w.parent = findWidget(a.ParentId, me.rootNode) + log(logInfo, "setupWidget() w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId) if (w.parent == nil) { log(logError, "setupWidget() ERROR: PARENT = NIL w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId) // just use the rootNode (hopefully it's not nil) w.parent = me.rootNode // return w } - if (w.parent == nil) { - log(logError, "setupWidget() ERROR: PARENT = NIL w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId) - me.rootNode = w - return w - } + // add this widget as a child for the parent w.parent.Append(w) @@ -58,11 +56,9 @@ func setupWidget(a *toolkit.Action) *cuiWidget { } } if (a.WidgetType == toolkit.Grid) { - w.logicalW = make(map[int]int) // how tall each row in the grid is - w.logicalH = make(map[int]int) // how wide each column in the grid is + w.widths = make(map[int]int) // how tall each row in the grid is + w.heights = make(map[int]int) // how wide each column in the grid is } - - // w.showWidgetPlacement(logNow) return w } diff --git a/toolkit/gocui/debug.go b/toolkit/gocui/debug.go index 3995794..d78fdf9 100644 --- a/toolkit/gocui/debug.go +++ b/toolkit/gocui/debug.go @@ -33,23 +33,30 @@ func (w *cuiWidget) dumpTree(draw bool) { } func (w *cuiWidget) showWidgetPlacement(b bool, s string) { + var s1 string + var pId int if (w == nil) { log(logError, "WTF w == nil") return } - if (w.id == 0) { - log(logVerbose, "showWidgetPlacement() parent == nil ok. This is the rootNode", w.id, w.cuiName) - return - } if (w.parent == nil) { - log(logError, "showWidgetPlacement() ERROR parent == nil", w.id, w.cuiName) + log(logVerbose, "showWidgetPlacement() parent == nil", w.id, w.cuiName) + pId = 0 + } else { + pId = w.parent.id } - log(b, "dump()", s, - fmt.Sprintf("(wId,pId)=(%3d,%3d)", w.id, w.parent.id), - fmt.Sprintf("real()=(%3d,%3d,%3d,%3d)", w.realSize.w0, w.realSize.h0, w.realSize.w1, w.realSize.h1), - "size()=(", w.realWidth, ",", w.realHeight, ")", - "logical()=(", w.logicalSize.w0, ",", w.logicalSize.h0, ",", w.logicalSize.w1, ",", w.logicalSize.h1, ")", - w.widgetType, ",", w.name, "text=", w.text) + s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", w.id, pId) + s1 += fmt.Sprintf("real()=(%2d,%2d,%2d,%2d) ", w.realSize.w0, w.realSize.h0, w.realSize.w1, w.realSize.h1) + s1 += fmt.Sprintf("size()=(%2d,%2d) ", w.realWidth, w.realHeight) + + switch w.widgetType { + case toolkit.Grid: + s1 += fmt.Sprintf("next()=(%2d,%2d)", w.nextW, w.nextH) + default: + s1 += fmt.Sprintf("L()=(%2d,%2d,%2d,%2d)", + w.logicalSize.w0, w.logicalSize.h0, w.logicalSize.w1, w.logicalSize.h1) + } + log(b, s1, s, w.widgetType, ",", w.name) // , "text=", w.text) if (w.realWidth != (w.realSize.w1 - w.realSize.w0)) { log(b, "dump()", s, diff --git a/toolkit/gocui/keybindings.go b/toolkit/gocui/keybindings.go index c449906..8e8a8dc 100644 --- a/toolkit/gocui/keybindings.go +++ b/toolkit/gocui/keybindings.go @@ -40,7 +40,6 @@ func defaultKeybindings(g *gocui.Gui) error { var showDebug bool = true -// dump out the widgets func addDebugKeys(g *gocui.Gui) { // dump all widget info to the log g.SetKeybinding("", 'd', gocui.ModNone, diff --git a/toolkit/gocui/log.go b/toolkit/gocui/log.go index 222332d..76edba6 100644 --- a/toolkit/gocui/log.go +++ b/toolkit/gocui/log.go @@ -9,7 +9,7 @@ import ( var logNow bool = true // useful for active development var logError bool = true var logWarn bool = false -var logInfo bool = false +var logInfo bool = true var logVerbose bool = false func log(a ...any) { diff --git a/toolkit/gocui/logical.go b/toolkit/gocui/logical.go index a9ceff1..c3964fb 100644 --- a/toolkit/gocui/logical.go +++ b/toolkit/gocui/logical.go @@ -6,6 +6,7 @@ import ( var adjusted bool = false +/* // expands the logical size of the parents func (w *cuiWidget) setParentLogical() { p := w.parent @@ -71,3 +72,4 @@ func (w *cuiWidget) setParentLogical() { pP.setParentLogical() } } +*/ diff --git a/toolkit/gocui/place.go b/toolkit/gocui/place.go index 1f0c768..31ef808 100644 --- a/toolkit/gocui/place.go +++ b/toolkit/gocui/place.go @@ -29,7 +29,6 @@ func (w *cuiWidget) setFake() { func findPlace(w *cuiWidget) { w.isFake = false - w.visable = true switch w.widgetType { case toolkit.Root: w.isFake = true @@ -48,6 +47,75 @@ func findPlace(w *cuiWidget) { } } +// find the start (w,h) for child a inside a box widget +func (w *cuiWidget) getBoxWH() { + p := w.parent // the parent must be a box widget + + // update parent realSize + p.realWidth = 0 + p.realHeight = 0 + for _, child := range p.children { + p.realWidth += child.realWidth + p.realHeight += child.realHeight + } + + // compute child offset + w.startW = p.startW + w.startH = p.startH + for _, child := range p.children { + if (p.horizontal) { + log("BOX IS HORIZONTAL (w,h)", w.startW, w.startH) + log("BOX IS HORIZONTAL (w,h)", w.startW, w.startH) + log("BOX IS HORIZONTAL (w,h)", w.startW, w.startH) + w.startW += child.realWidth + } else { + log("BOX IS VERTICAL (w,h)", w.startW, w.startH) + log("BOX IS VERTICAL (w,h)", w.startW, w.startH) + log("BOX IS VERTICAL (w,h)", w.startW, w.startH) + w.startH += child.realHeight + } + if child == w { + return + } + } + return +} + +// find the start (w,h) for child a inside a Group widget +func (w *cuiWidget) getGroupWH() { + p := w.parent // the parent must be a group widget + + // update parent realSize + p.realWidth = 0 + p.realHeight = 0 + p.realHeight += me.buttonPadding // pad height for the group label + for _, child := range p.children { + p.realWidth += child.realWidth + p.realHeight += child.realHeight + } + + // compute child offset + w.startW = p.startW + w.startH = p.startH + for _, child := range p.children { + w.startH += child.realHeight + if child == w { + return + } + } + return +} + +// find the start (w,h) for child a inside a Grid widget +func (w *cuiWidget) getGridWH() { + p := w.parent + w.startW = p.startW + w.startH = p.startH + w.nextW = p.startW + w.nextH = p.startH + w.gridBounds() +} + func (w *cuiWidget) redoBox(draw bool) { if (w == nil) { return @@ -126,10 +194,14 @@ func (w *cuiWidget) redoBox(draw bool) { } func (w *cuiWidget) moveTo(leftW int, topH int) { - w.realSize.w0 = leftW - w.realSize.h0 = topH - w.realSize.w1 = leftW + w.realWidth - w.realSize.h1 = topH + w.realHeight + if (w.isFake) { + // don't ever move these + } else { + w.realSize.w0 = leftW + w.realSize.h0 = topH + } + w.realSize.w1 = w.realSize.w0 + w.realWidth + w.realSize.h1 = w.realSize.h0 + w.realHeight w.logicalSize.w0 = w.realSize.w0 w.logicalSize.h0 = w.realSize.h0 @@ -166,7 +238,7 @@ func (w *cuiWidget) gridBounds() { for a := 0; a < w.x; a++ { for b := 0; b < w.y; b++ { log(logNow, "gridBounds() (w,h)", a, b, - "logical(W,H)", w.logicalW[a], w.logicalH[b], + "logical(W,H)", w.widths[a], w.heights[b], "p.next(W,H)", p.nextW, p.nextH) } log("\n") @@ -183,11 +255,11 @@ func (w *cuiWidget) gridBounds() { // set the child's realWidth, and grid offset child.parentH = hCount child.parentW = wCount - if (w.logicalW[wCount] < child.realWidth) { - w.logicalW[wCount] = child.realWidth + if (w.widths[wCount] < child.realWidth) { + w.widths[wCount] = child.realWidth } - if (w.logicalH[hCount] < child.realHeight) { - w.logicalH[hCount] = child.realHeight + if (w.heights[hCount] < child.realHeight) { + w.heights[hCount] = child.realHeight } log(logNow, "redoBox(GRID) (w,h count)", wCount, hCount, "(X,Y)", w.x, w.y, w.name) child.showWidgetPlacement(logNow, "grid:") @@ -200,17 +272,26 @@ func (w *cuiWidget) gridBounds() { } } + // reset the size of the whole grid + w.realWidth = 0 + w.realHeight = 0 + for _, val := range w.widths { + w.realWidth += val + } + for _, val := range w.heights { + w.realHeight += val + } for _, child := range w.children { child.showWidgetPlacement(logVerbose, "gridBounds:") var totalW, totalH int - for i, val := range w.logicalW { + for i, val := range w.widths { if (i < child.parentW) { - log(logVerbose, "gridBounds() (w, logicalW[])", i, val) - totalW += w.logicalW[i] + log(logVerbose, "gridBounds() (w, widths[])", i, val) + totalW += w.widths[i] } } - for i, h := range w.logicalH { + for i, h := range w.heights { if (i < child.parentH) { totalH += h } @@ -228,6 +309,6 @@ func (w *cuiWidget) gridBounds() { child.showWidgetPlacement(logInfo, "gridBounds:") log(logInfo) } - w.updateLogicalSizes() + // w.updateLogicalSizes() w.showWidgetPlacement(logNow, "gridBounds:") } diff --git a/toolkit/gocui/plugin.go b/toolkit/gocui/plugin.go index 01579ab..389b3b7 100644 --- a/toolkit/gocui/plugin.go +++ b/toolkit/gocui/plugin.go @@ -10,14 +10,69 @@ func Quit() { me.baseGui.Close() } +// set the widget start width & height +// re-run this when things change to recalibrate the position of the gocui view rect +func (w *cuiWidget) setStartWH() { + log(logInfo, "setStartWH() w.id =", w.id, "w.name", w.name) + switch w.widgetType { + case toolkit.Root: + log(logInfo, "setStartWH() rootNode w.id =", w.id, "w.name", w.name) + w.startW = 1 + w.startH = 1 + w.id = 0 + w.isFake = true + w.setFake() + w.showWidgetPlacement(logNow, "Tree:") + return + case toolkit.Flag: + w.startW = 1 + w.startH = 1 + w.isFake = true + w.setFake() + w.showWidgetPlacement(logNow, "Tree:") + return + case toolkit.Window: + w.startW = 1 + w.startH = 3 + return + case toolkit.Tab: + w.startW = 1 + w.startH = 3 + return + } + p := w.parent + switch p.widgetType { + case toolkit.Box: + if (w.isFake == false) { + w.isFake = true + w.setFake() + } + w.getBoxWH() + return + case toolkit.Grid: + if (w.isFake == false) { + w.isFake = true + w.setFake() + } + w.getGridWH() + return + case toolkit.Group: + w.getGroupWH() + return + } +} + func Action(a *toolkit.Action) { log(logInfo, "Action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name) w := findWidget(a.WidgetId, me.rootNode) switch a.ActionType { case toolkit.Add: w = setupWidget(a) - findPlace(w) + w.setStartWH() + w.moveTo(w.startW, w.startH) w.drawView() + + // findPlace(w) case toolkit.Show: if (a.B) { w.drawView() diff --git a/toolkit/gocui/structs.go b/toolkit/gocui/structs.go index b4a2ab6..6ab77cf 100644 --- a/toolkit/gocui/structs.go +++ b/toolkit/gocui/structs.go @@ -87,20 +87,29 @@ type cuiWidget struct { vals []string // dropdown menu options - visable bool // track if it's currently supposed to be shown + // visable bool // track if it's currently supposed to be shown isFake bool // widget types like 'box' are 'false' - realWidth int // the real width - realHeight int // the real height + + // where the widget should calculate it's existance from + startW int + startH int + + // the widget size to reserve or things will overlap + realWidth int + realHeight int + realSize rectType // the display size of this widget logicalSize rectType // the logical size. Includes all the child widgets // used to track the size of grids - logicalW map[int]int // how tall each row in the grid is - logicalH map[int]int // how wide each column in the grid is - // where in the parent grid this widget should go + widths map[int]int // how tall each row in the grid is + heights map[int]int // how wide each column in the grid is + + // deprecate // where in the parent grid this widget should go parentW int parentH int + // deprecate nextW int nextH int @@ -113,10 +122,6 @@ type cuiWidget struct { width int height int - //deprecate -// nextX int -// nextY int - // horizontal=true means layout widgets like books on a bookshelf // horizontal=false means layout widgets like books in a stack horizontal bool `default:false`