399 lines
8.0 KiB
Go
399 lines
8.0 KiB
Go
// 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) Hidden() bool {
|
|
if tk.parent == nil {
|
|
return tk.node.Hidden()
|
|
}
|
|
if tk.parent.node.WidgetId == 0 {
|
|
return tk.node.Hidden()
|
|
}
|
|
if tk.parent.Hidden() {
|
|
return true
|
|
}
|
|
return tk.node.Hidden()
|
|
}
|
|
|
|
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.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.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.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.Textbox:
|
|
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
|
case widget.Checkbox:
|
|
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
|
}
|
|
if tk.isFake {
|
|
return 0, 0
|
|
}
|
|
return len(tk.String()), 3
|
|
}
|
|
|
|
func (w *guiWidget) sizeGrid() (int, int) {
|
|
if w.Hidden() {
|
|
return 0, 0
|
|
}
|
|
|
|
// first compute the max sizes of the rows and columns
|
|
for _, child := range w.children {
|
|
if w.Hidden() {
|
|
continue
|
|
}
|
|
sizeW, sizeH := child.Size()
|
|
|
|
// 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.Hidden() {
|
|
return 0, 0
|
|
}
|
|
var maxW int = 0
|
|
var maxH int = 0
|
|
|
|
for _, child := range w.children {
|
|
if w.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()
|
|
|
|
if tk.Hidden() {
|
|
p := tk.parent
|
|
if p != nil {
|
|
// tk.full.w0 = p.full.w0
|
|
// tk.full.w1 = p.full.w1
|
|
// tk.full.h0 = p.full.h0
|
|
// tk.full.h1 = p.full.h1
|
|
tk.full.w0 = 0
|
|
tk.full.w1 = 0
|
|
tk.full.h0 = 0
|
|
tk.full.h1 = 0
|
|
} else {
|
|
tk.full.w0 = 0
|
|
tk.full.w1 = 0
|
|
tk.full.h0 = 0
|
|
tk.full.h1 = 0
|
|
}
|
|
return false
|
|
}
|
|
|
|
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.Hidden() {
|
|
/*
|
|
p := tk.parent
|
|
if p != nil {
|
|
return p.full
|
|
}
|
|
*/
|
|
var r rectType
|
|
r.w0 = 0
|
|
r.w1 = 0
|
|
r.h0 = 0
|
|
r.h1 = 0
|
|
return r
|
|
}
|
|
|
|
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
|
|
}
|