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 } }