package main import ( "errors" "github.com/awesome-gocui/gocui" "go.wit.com/log" "go.wit.com/widget" ) // set isCurrent = false everywhere func (w *guiWidget) unsetCurrent() { w.isCurrent = false if w.node.WidgetType == widget.Tab { // n.tk.color = &colorTab // n.setColor() } for _, child := range w.children { child.unsetCurrent() } } // when adding a new widget, this will update the display // of the current widgets if that widget is supposed // to be in current display func (w *guiWidget) updateCurrent() { log.Log(NOW, "updateCurrent()", w.String()) if w.WidgetType == widget.Tab { if w.IsCurrent() { // n.tk.color = &colorActiveT w.setColor(&colorActiveT) w.hideView() w.showView() w.setCurrentTab() } else { // n.tk.color = &colorTab // n.setColor() } return } if w.WidgetType == widget.Window { if w.IsCurrent() { // setCurrentWindow(n) } return } if w.WidgetType == widget.Root { return } w.parent.updateCurrent() } // shows the widgets in a window func (w *guiWidget) setCurrentWindow() { if w.IsCurrent() { return } if w.WidgetType != widget.Window { return } var rootTK *guiWidget rootTK = me.treeRoot.TK.(*guiWidget) rootTK.unsetCurrent() if w.hasTabs { // set isCurrent = true on the first tab for _, child := range w.children { child.isCurrent = true break } } else { w.isCurrent = true } } // shows the widgets in a tab func (w *guiWidget) setCurrentTab() { var p, rootTK *guiWidget if w.WidgetType != widget.Tab { return } rootTK = me.treeRoot.TK.(*guiWidget) rootTK.unsetCurrent() w.isCurrent = true p = w.parent p.isCurrent = true log.Log(NOW, "setCurrent()", w.String()) } func (w *guiWidget) doWidgetClick() { switch w.WidgetType { case widget.Root: // THIS IS THE BEGINING OF THE LAYOUT log.Log(NOW, "doWidgetClick()", w.String()) wRoot := me.treeRoot.TK.(*guiWidget) wRoot.redoWindows(0, 0) case widget.Flag: log.Log(NOW, "doWidgetClick() FLAG widget name =", w.String()) log.Log(NOW, "doWidgetClick() if this is the dropdown menu, handle it here?") case widget.Window: log.Log(NOW, "doWidgetClick() START on window", w.String()) if me.currentWindow == w.node { if !w.active { return } } if me.currentWindow != nil { var curw *guiWidget curw = me.currentWindow.TK.(*guiWidget) curw.unsetCurrent() curw.setColor(&colorWindow) curw.hideWidgets() } me.currentWindow = w.node log.Log(NOW, "doWidgetClick() set currentWindow to", w.String()) w.setColor(&colorActiveW) w.active = false // w.dumpTree("before") w.placeWidgets(3, 2) w.showWidgets() hideFake() showDebug = true // w.dumpTree("after") case widget.Group: // n.placeWidgets(p.tk.startH, newH) // w.dumpTree("click start") if w.active { w.active = false w.placeWidgets(w.startW, w.startH) w.showWidgets() /* for _, child := range w.children { log.Log(INFO, "START W,H", startW, startH) child.placeWidgets(startW, startH) child.showWidgets() } */ } else { w.active = true for _, child := range w.children { child.hideWidgets() } } // w.dumpTree("click end") case widget.Checkbox: if w.node.State.Checked { log.Log(WARN, "checkbox is being set to false") w.node.State.Checked = false w.setCheckbox() } else { log.Log(WARN, "checkbox is being set to true") w.node.State.Checked = true w.setCheckbox() } me.myTree.SendUserEvent(w.node) case widget.Grid: newR := w.realGocuiSize() // w,h := n.logicalSize() // w := newR.w1 - newR.w0 // h := newR.h1 - newR.h0 w.placeGrid(newR.w0, newR.h0) w.showWidgets() case widget.Box: // w.showWidgetPlacement(logNow, "drawTree()") if w.direction == widget.Horizontal { log.Log(NOW, "BOX IS HORIZONTAL", w.String()) } else { log.Log(NOW, "BOX IS VERTICAL", w.String()) } w.placeWidgets(me.RawW, me.RawH) w.toggleTree() case widget.Button: // doUserEvent(n) me.myTree.SendFromUser(w.node) case widget.Combobox: log.Log(NOW, "do the combobox here") w.showDropdown() case widget.Dropdown: log.Log(NOW, "do the dropdown here") w.showDropdown() default: } } var toggle bool = true func (w *guiWidget) toggleTree() { if toggle { w.drawTree(toggle) toggle = false } else { w.hideWidgets() toggle = true } } // display the widgets in the binary tree func (w *guiWidget) drawTree(draw bool) { if w == nil { return } w.showWidgetPlacement("drawTree()") if draw { // w.textResize() w.showView() } else { w.deleteView() } for _, child := range w.children { child.drawTree(draw) } } func click(g *gocui.Gui, v *gocui.View) error { // var l string // var err error log.Log(NOW, "click() START gocui name:", v.Name()) // n := me.rootNode.findWidgetName(v.Name()) w := findUnderMouse() if w == nil { log.Error(errors.New("click() could not find widget for view =" + v.Name())) } else { log.Log(NOW, "click() Found widget =", w.node.WidgetId, w.String(), ",", w.labelN) w.doWidgetClick() } rootTK := me.treeRoot.TK.(*guiWidget) realTK := rootTK.findWidgetByView(v) if realTK == nil { log.Error(errors.New("toolkit click() out of reality with gocui. v.Name() not in binary tree " + v.Name())) log.Log(NOW, "click() END FAILURE ON gocui v.Name =", v.Name()) // return nil // otherwise gocui exits } // double check the widget view really still exists nameTK := rootTK.findWidgetByName(v.Name()) if nameTK == nil { log.Error(errors.New("toolkit click() out of reality with gocui. v.Name() not in binary tree " + v.Name())) return nil } if nameTK.v == nil { log.Log(NOW, "click() maybe this widget has had it's view distroyed?", nameTK.cuiName, nameTK.WidgetType) log.Log(NOW, "yep. it's gone now") return nil } // SetCurrentView dies if it's sent an non-existent view if _, err := g.SetCurrentView(v.Name()); err != nil { log.Log(NOW, "click() END v.Name =", v.Name(), "err =", err) // return err // return causes gocui.MainLoop() to exit. Do we ever want that to happen here? return nil } log.Log(NOW, "click() END gocui name:", v.Name()) return nil } func findUnderMouse() *guiWidget { var widgets []*guiWidget var f func(w *guiWidget) w, h := me.baseGui.MousePosition() // if the dropdown view is visable, close it if me.dropdownV.Visible() { me.dropdownV.dropdownClicked(w, h) return me.dropdownV } // find buttons that are below where the mouse button click f = func(widget *guiWidget) { // ignore widgets that are not visible if widget.Visible() { if (widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) && (widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1) { widgets = append(widgets, widget) } } for _, child := range widget.children { f(child) } } rootW := me.treeRoot.TK.(*guiWidget) f(rootW) var found *guiWidget // widgets has everything that matches for _, w := range widgets { w.showWidgetPlacement("findUnderMouse() FOUND") // prioritize window buttons. This means if some code covers // up the window widgets, then it will ignore everything else // and allow the user (hopefully) to redraw or switch windows // TODO: display the window widgets on top if w.WidgetType == widget.Window { return w } found = w } return found } // find the widget under the mouse click func ctrlDown(g *gocui.Gui, v *gocui.View) error { var found *guiWidget // var widgets []*node // var f func (n *node) found = findUnderMouse() if me.ctrlDown == nil { setupCtrlDownWidget() var tk *guiWidget tk = me.ctrlDown.TK.(*guiWidget) tk.labelN = found.String() tk.cuiName = "ctrlDown" // me.ctrlDown.parent = me.rootNode } var tk *guiWidget tk = me.ctrlDown.TK.(*guiWidget) if found == nil { found = me.treeRoot.TK.(*guiWidget) } tk.labelN = found.String() newR := found.realGocuiSize() tk.gocuiSize.w0 = newR.w0 tk.gocuiSize.h0 = newR.h0 tk.gocuiSize.w1 = newR.w1 tk.gocuiSize.h1 = newR.h1 if tk.Visible() { // me.ctrlDown.hideView() } else { // me.ctrlDown.showView() } // me.ctrlDown.showWidgetPlacement("ctrlDown:") return nil }