// Copyright 2017-2025 WIT.COM Inc. All rights reserved. // Use of this source code is governed by the GPL 3.0 package main import ( "fmt" "go.wit.com/widget" ) func (tk *guiWidget) Size() (int, int) { if tk == nil { return 0, 0 } if me.treeRoot == nil { return 0, 0 } // don't count hidden widgets in size calculations if tk.node.Hidden() { return 0, 0 } switch tk.node.WidgetType { case widget.Window: var maxH int = 0 var maxW int = 0 for _, child := range tk.children { if tk.node.Hidden() { continue } sizeW, sizeH := child.Size() maxW += sizeW if sizeH > maxH { maxH = sizeH } } return maxW, maxH case widget.Grid: return tk.sizeGrid() case widget.Box: return tk.sizeBox() case widget.Group: // move the group to the parent's next location maxW := tk.gocuiSize.Width() maxH := tk.gocuiSize.Height() for _, child := range tk.children { if tk.node.Hidden() { continue } sizeW, sizeH := child.Size() // increment straight down maxH += sizeH if sizeW > maxW { maxW = sizeW } } return maxW + me.GroupPadW + 3, maxH case widget.Label: return len(tk.String()) + 2, 1 case widget.Checkbox: return len(tk.String()) + 2, 3 } if tk.isFake { return 0, 0 } return len(tk.String()), 3 } func (w *guiWidget) sizeGrid() (int, int) { if w.node.Hidden() { return 0, 0 } // first compute the max sizes of the rows and columns for _, child := range w.children { if w.node.Hidden() { continue } sizeW, sizeH := child.Size() sizeW += 2 // set the child's realWidth, and grid offset if w.widths[child.node.State.AtW] < sizeW { w.widths[child.node.State.AtW] = sizeW } if w.heights[child.node.State.AtH] < sizeH { w.heights[child.node.State.AtH] = sizeH } } // find the width and height offset of the grid for AtW,AtH var totalW int = 0 var totalH int = 0 for _, width := range w.widths { totalW += width } for _, h := range w.heights { totalH += h } return totalW + me.GridPadW, totalH } func (w *guiWidget) sizeBox() (int, int) { if w.node.WidgetType != widget.Box { return 0, 0 } if w.node.Hidden() { return 0, 0 } var maxW int = 0 var maxH int = 0 for _, child := range w.children { if w.node.Hidden() { continue } sizeW, sizeH := child.Size() if child.node.State.Direction == widget.Vertical { maxW += sizeW if sizeH > maxH { maxH = sizeH } } else { maxH += sizeH if sizeW > maxW { maxW = sizeW } } } return maxW + me.BoxPadW, maxH } /* var wtf bool func (tk *guiWidget) verifyRect() bool { if !tk.Visible() { // log.Info("verifyRect() tk is not visible", tk.cuiName) return false } vw0, vh0, vw1, vh1, err := me.baseGui.ViewPosition(tk.cuiName) if err != nil { // log.Printf("verifyRect() gocui err=%v cuiName=%s v.Name=%s", err, tk.cuiName, tk.v.Name()) vw0, vh0, vw1, vh1, err = me.baseGui.ViewPosition(tk.v.Name()) if err != nil { log.Printf("verifyRect() ACTUAL FAIL gocui err=%v cuiName=%s v.Name=%s", err, tk.cuiName, tk.v.Name()) return false } // return false } var ok bool = true if vw0 != tk.full.w0 { // log.Info("verifyRect() FIXING w0", tk.cuiName, vw0, vw1, vh0, vh1, tk.gocuiSize.w0, "w0 =", vw0) tk.full.w0 = vw0 ok = false } if vw1 != tk.full.w1 { // log.Info("verifyRect() FIXING w1", tk.cuiName, vw0, vw1, vh0, vh1, tk.gocuiSize.w1, "w1 =", vw1) tk.full.w1 = vw1 ok = false } if vh0 != tk.full.h0 { // log.Info("verifyRect() FIXING h0", tk.cuiName, vw0, vw1, vh0, vh1, tk.gocuiSize.h0) tk.full.h0 = vh0 ok = false } if vh1 != tk.full.h1 { // log.Info("verifyRect() FIXING h1", tk.cuiName, vw0, vw1, vh0, vh1, tk.gocuiSize.h1) tk.full.h1 = vh1 ok = false } if !ok { // log.Info("verifyRect() NEED TO FIX RECT HERE", tk.cuiName) // tk.dumpWidget("verifyRect() FIXME") } // log.Printf("verifyRect() OK cuiName=%s v.Name=%s", tk.cuiName, tk.v.Name()) return true } */ func (tk *guiWidget) setFullSize() bool { r := tk.getFullSize() var changed bool if tk.full.w0 != r.w0 { tk.full.w0 = r.w0 changed = true } // widget might be forced to a certain location if tk.full.w0 < tk.force.w0 { tk.gocuiSize.w0 = tk.force.w0 tk.full.w0 = tk.force.w0 changed = false } if tk.full.w1 != r.w1 { tk.full.w1 = r.w1 changed = true } if tk.full.h0 != r.h0 { tk.full.h0 = r.h0 changed = true } // widget might be forced to a certain location if tk.full.h0 < tk.force.h0 { tk.gocuiSize.h0 = tk.force.h0 tk.full.h0 = tk.force.h0 changed = false } if tk.full.h1 != r.h1 { tk.full.h1 = r.h1 changed = true } if changed { tk.dumpWidget(fmt.Sprintf("setFullSize(changed)")) } return changed } func (tk *guiWidget) gridFullSize() rectType { var r rectType var first bool = true for _, child := range tk.children { cr := child.getFullSize() if cr.Width() == 0 && cr.Height() == 0 { // ignore widgets of zero size? continue } if first { // use the lowest width and hight from children widgets r.w0 = cr.w0 r.h0 = cr.h0 r.w1 = cr.w1 r.h1 = cr.h1 first = false // child.dumpWidget(fmt.Sprintf("grid(f)")) continue } // child.dumpWidget(fmt.Sprintf("grid()")) // use the lowest width and hight from children widgets if r.w0 > cr.w0 { r.w0 = cr.w0 } if r.h0 > cr.h0 { r.h0 = cr.h0 } // use the highest width and hight from children widgets if r.w1 < cr.w1 { r.w1 = cr.w1 } if r.h1 < cr.h1 { r.h1 = cr.h1 } } tk.full.w0 = r.w0 tk.full.w1 = r.w1 tk.full.h0 = r.h0 tk.full.h1 = r.h1 return r } func (tk *guiWidget) buttonFullSize() rectType { var r rectType r.w0 = tk.gocuiSize.w0 r.w1 = tk.gocuiSize.w1 r.h0 = tk.gocuiSize.h0 r.h1 = tk.gocuiSize.h1 // try setting the full values here ? is this right? tk.full.w0 = r.w0 tk.full.w1 = r.w1 tk.full.h0 = r.h0 tk.full.h1 = r.h1 return r } // this checks a widget to see if it is under (W,H), then checks the widget's children // anything that matches is passed back as an array of widgets func (tk *guiWidget) getFullSize() rectType { var r rectType if tk.node.WidgetType == widget.Grid { return tk.gridFullSize() } // these are 'simple' widgets // the full size is exactly what gocui uses switch tk.node.WidgetType { case widget.Label: return tk.buttonFullSize() case widget.Button: return tk.buttonFullSize() case widget.Checkbox: return tk.buttonFullSize() case widget.Dropdown: return tk.buttonFullSize() default: } if tk.v == nil { r.w0 = tk.full.w0 r.w1 = tk.full.w1 r.h0 = tk.full.h0 r.h1 = tk.full.h1 } else { r.w0 = tk.gocuiSize.w0 r.w1 = tk.gocuiSize.w1 r.h0 = tk.gocuiSize.h0 r.h1 = tk.gocuiSize.h1 } // search through the children widgets in the binary tree for _, child := range tk.children { cr := child.getFullSize() /* this didn't make things work either if child.v == nil { continue } */ // use the lowest width and hight from children widgets if r.w0 > cr.w0 { r.w0 = cr.w0 } if r.h0 > cr.h0 { r.h0 = cr.h0 } // use the highest width and hight from children widgets if r.w1 < cr.w1 { r.w1 = cr.w1 } if r.h1 < cr.h1 { r.h1 = cr.h1 } } // try setting the full values here ? is this right? tk.full.w0 = r.w0 tk.full.w1 = r.w1 tk.full.h0 = r.h0 tk.full.h1 = r.h1 return r }