267 lines
6.4 KiB
Go
267 lines
6.4 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"go.wit.com/log"
|
|
"go.wit.com/toolkits/tree"
|
|
"go.wit.com/widget"
|
|
)
|
|
|
|
func (w *guiWidget) placeBox(startW int, startH int) {
|
|
if w.WidgetType != widget.Box {
|
|
return
|
|
}
|
|
// tk.dumpTree("beforebox")
|
|
|
|
newW := startW
|
|
newH := startH
|
|
|
|
for _, child := range w.children {
|
|
sizeW, sizeH := child.Size()
|
|
log.Log(INFO, "BOX START size(W,H) =", sizeW, sizeH, "new(W,H) =", newW, newH)
|
|
child.placeWidgets(newW, newH)
|
|
// re-get the Size (they should not have changed, but maybe they can?)
|
|
// TODO: figure this out or report that they did
|
|
sizeW, sizeH = child.Size()
|
|
if w.node.State.Direction == widget.Vertical {
|
|
log.Log(INFO, "BOX IS VERTICAL ", w.String(), "newWH()", newW, newH, "child()", sizeW, sizeH, child.String())
|
|
// expand based on the child height
|
|
newH += sizeH
|
|
} else {
|
|
log.Log(INFO, "BOX IS HORIZONTAL", w.String(), "newWH()", newW, newH, "child()", sizeW, sizeH, child.String())
|
|
// expand based on the child width
|
|
newW += sizeW
|
|
}
|
|
log.Log(INFO, "BOX END size(W,H) =", sizeW, sizeH, "new(W,H) =", newW, newH)
|
|
}
|
|
// tk.dumpTree("afterbox")
|
|
}
|
|
|
|
func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
|
if tk == nil {
|
|
return 0, 0
|
|
}
|
|
if me.treeRoot == nil {
|
|
return 0, 0
|
|
}
|
|
|
|
tk.startW = startW
|
|
tk.startH = startH
|
|
|
|
switch tk.WidgetType {
|
|
case widget.Window:
|
|
newW := startW
|
|
newH := startH
|
|
var maxH int = 0
|
|
for _, child := range tk.children {
|
|
child.placeWidgets(newW, newH)
|
|
sizeW, sizeH := child.Size()
|
|
if sizeW < 20 {
|
|
sizeW = 20
|
|
}
|
|
newW += sizeW
|
|
if sizeH > maxH {
|
|
maxH = sizeH
|
|
}
|
|
|
|
}
|
|
return newW - startW, maxH
|
|
case widget.Tab:
|
|
case widget.Grid:
|
|
return tk.placeGrid(startW, startH)
|
|
case widget.Box:
|
|
tk.placeBox(startW, startH)
|
|
return 0, 0
|
|
case widget.Group:
|
|
// move the group to the parent's next location
|
|
tk.gocuiSetWH(startW, startH)
|
|
|
|
newW := startW + me.GroupPadW
|
|
newH := startH + 1 // normal hight of the group label
|
|
var maxW int = 0
|
|
// now move all the children aka: run place() on them
|
|
for _, child := range tk.children {
|
|
sizeW, sizeH := child.placeWidgets(newW, newH)
|
|
// newR := child.realGocuiSize()
|
|
// w := newR.w1 - newR.w0
|
|
// h := newR.h1 - newR.h0
|
|
|
|
// increment straight down
|
|
newH += sizeH + 1
|
|
if sizeW > maxW {
|
|
maxW = sizeW
|
|
}
|
|
log.Log(INFO, "REAL HEIGHT sizeW:", sizeW, "sizeH:", sizeH)
|
|
}
|
|
return maxW, newH - startH
|
|
default:
|
|
tk.gocuiSetWH(startW, startH)
|
|
return tk.gocuiSize.Width(), tk.gocuiSize.Height()
|
|
}
|
|
return 0, 0
|
|
}
|
|
|
|
func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
|
// w.showWidgetPlacement("grid0:")
|
|
if w.WidgetType != widget.Grid {
|
|
return 0, 0
|
|
}
|
|
|
|
// first compute the max sizes of the rows and columns
|
|
for _, child := range w.children {
|
|
childW, childH := child.placeWidgets(child.startW, child.startH)
|
|
|
|
// set the child's realWidth, and grid offset
|
|
if w.widths[child.node.State.AtW] < childW {
|
|
w.widths[child.node.State.AtW] = childW
|
|
}
|
|
if w.heights[child.node.State.AtH] < childH {
|
|
w.heights[child.node.State.AtH] = childH
|
|
}
|
|
// child.showWidgetPlacement("grid: ")
|
|
log.Log(INFO, "placeGrid:", child.String(), "child()", childW, childH, "At()", child.node.State.AtW, child.node.State.AtH)
|
|
}
|
|
|
|
var maxW int = 0
|
|
var maxH int = 0
|
|
|
|
// find the width and height offset of the grid for AtW,AtH
|
|
for _, child := range w.children {
|
|
// child.showWidgetPlacement("grid1:")
|
|
|
|
var totalW, totalH int
|
|
for i, w := range w.widths {
|
|
if i < child.node.State.AtW {
|
|
totalW += w
|
|
}
|
|
}
|
|
for i, h := range w.heights {
|
|
if i < child.node.State.AtH {
|
|
totalH += h
|
|
}
|
|
}
|
|
|
|
// the new corner to move the child to
|
|
newW := startW + totalW
|
|
newH := startH + totalH
|
|
|
|
if totalW > maxW {
|
|
maxW = totalW
|
|
}
|
|
if totalH > maxH {
|
|
maxH = totalH
|
|
}
|
|
|
|
log.Log(INFO, "placeGrid:", child.String(), "new()", newW, newH, "At()", child.node.State.AtW, child.node.State.AtH)
|
|
child.placeWidgets(newW, newH)
|
|
// child.showWidgetPlacement("grid2:")
|
|
}
|
|
// w.showWidgetPlacement("grid3:")
|
|
return maxW, maxH
|
|
}
|
|
|
|
// computes the real, actual size of all the gocli objects in a widget
|
|
func (w *guiWidget) realGocuiSize() *rectType {
|
|
var f func(tk *guiWidget, r *rectType)
|
|
newR := new(rectType)
|
|
// initialize the values to opposite
|
|
newR.w0 = 80
|
|
newR.h0 = 24
|
|
if me.baseGui != nil {
|
|
maxW, maxH := me.baseGui.Size()
|
|
newR.w0 = maxW
|
|
newR.h0 = maxH
|
|
}
|
|
newR.w1 = 0
|
|
newR.h1 = 0
|
|
|
|
// expand the rectangle to the biggest thing displayed
|
|
f = func(tk *guiWidget, r *rectType) {
|
|
newR := tk.gocuiSize
|
|
if !tk.isFake {
|
|
if r.w0 > newR.w0 {
|
|
r.w0 = newR.w0
|
|
}
|
|
if r.h0 > newR.h0 {
|
|
r.h0 = newR.h0
|
|
}
|
|
if r.w1 < newR.w1 {
|
|
r.w1 = newR.w1
|
|
}
|
|
if r.h1 < newR.h1 {
|
|
r.h1 = newR.h1
|
|
}
|
|
}
|
|
for _, child := range tk.children {
|
|
f(child, r)
|
|
}
|
|
}
|
|
f(w, newR)
|
|
return newR
|
|
}
|
|
|
|
func textSize(n *tree.Node) (int, int) {
|
|
var tk *guiWidget
|
|
tk = n.TK.(*guiWidget)
|
|
var width, height int
|
|
|
|
for _, s := range strings.Split(widget.GetString(tk.value), "\n") {
|
|
if width < len(s) {
|
|
width = len(s)
|
|
}
|
|
height += 1
|
|
}
|
|
return width, height
|
|
}
|
|
|
|
// moves the gocui view the W and H offset on the screen
|
|
/*
|
|
gocui defines the offset like this:
|
|
|
|
width -> increases to the right
|
|
---------------------------------- hieght
|
|
| H = 1 | increases
|
|
| | |
|
|
| W = 1 W = 18 | |
|
|
| | v
|
|
| H = 5 | downwards
|
|
-------------------------------------
|
|
*/
|
|
// change over to this name
|
|
func (tk *guiWidget) MoveToOffset(W, H int) {
|
|
tk.gocuiSetWH(W, H)
|
|
}
|
|
|
|
// returns where the corner of widget starts (upper left)
|
|
func (tk *guiWidget) Position() (int, int) {
|
|
return tk.gocuiSize.w0, tk.gocuiSize.h0
|
|
}
|
|
|
|
func (tk *guiWidget) gocuiSetWH(sizeW, sizeH int) {
|
|
w := len(widget.GetString(tk.value))
|
|
lines := strings.Split(widget.GetString(tk.value), "\n")
|
|
h := len(lines)
|
|
|
|
// tk := n.tk
|
|
if tk.isFake {
|
|
tk.gocuiSize.w0 = sizeW
|
|
tk.gocuiSize.h0 = sizeH
|
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
|
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
|
|
return
|
|
}
|
|
|
|
if tk.frame {
|
|
tk.gocuiSize.w0 = sizeW
|
|
tk.gocuiSize.h0 = sizeH
|
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
|
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
|
|
} else {
|
|
tk.gocuiSize.w0 = sizeW - 1
|
|
tk.gocuiSize.h0 = sizeH - 1
|
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + 1
|
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + 1
|
|
}
|
|
}
|