From ee0f84fd8ef5993a6c374c8ee4e22c837ca39d97 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Fri, 2 Feb 2024 14:49:17 -0600 Subject: [PATCH] finds the item chosen from the dropdown list Signed-off-by: Jeff Carr --- click.go | 28 ++++++++++--- dropdown.go | 58 +++++++++++++------------- main.go | 2 +- place.go | 50 ++++++++++++++++++++++ tab.go | 118 ---------------------------------------------------- view.go | 68 +++++++++++++++--------------- widget.go | 42 +++++++++++++++---- window.go | 26 ++++++++++++ 8 files changed, 197 insertions(+), 195 deletions(-) delete mode 100644 tab.go create mode 100644 window.go diff --git a/click.go b/click.go index 57a6179..59d33b3 100644 --- a/click.go +++ b/click.go @@ -231,16 +231,34 @@ func click(g *gocui.Gui, v *gocui.View) error { 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) - if w.String() == "DropBox" { - log.Log(NOW, "click() this is the dropdown menu. set a flag here what did I click? where is the mouse?") - log.Log(NOW, "click() set a global dropdown clicked flag=true here") - } 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 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()) diff --git a/dropdown.go b/dropdown.go index 872bc22..b9d6266 100644 --- a/dropdown.go +++ b/dropdown.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "strings" "github.com/awesome-gocui/gocui" log "go.wit.com/log" @@ -68,24 +69,23 @@ func addDropdown() *tree.Node { func (tk *guiWidget) showDropdown() { var ddItems string + // todo: fix this after switching to protobuf + // var items []string + // items = tk.node.State.Strings + //for i, s := range items { for i, s := range tk.vals { log.Log(NOW, "showDropdown()", tk.String(), i, s) ddItems += s + "\n" } - log.Log(NOW, "showDropdown() visible =", tk.Visible()) - if tk.Visible() { - tk.SetVisible(false) - me.baseGui.DeleteView("ddview") - tk.v = nil - } else { - log.Log(NOW, "new dns list should be set to:", ddItems) - tk.labelN = ddItems - tk.SetText(ddItems) - tk.SetVisible(true) - tk.v.Clear() - fmt.Fprint(tk.v, ddItems) - } + log.Log(NOW, "new dropdown items should be set to:", ddItems) + sizeW, sizeH := tk.Size() + log.Log(NOW, "showDropdown() size W,H=", sizeW, sizeH) + startW, startH := tk.Position() + log.Log(NOW, "showDropdown() location W,H=", startW, startH) + me.dropdownV.MoveToOffset(startW+3, startH+2) + me.dropdownV.labelN = ddItems + me.dropdownV.Show() } func hideDDview() error { @@ -115,24 +115,26 @@ func showDDview() error { } // if there is a drop down view active, treat it like a dialog box and close it -func (w *guiWidget) dropdownClicked(mouseW, mouseH int) { - log.Log(NOW, "dropdownClicked() (w,h) =", mouseW, mouseH) - w.deleteView() +func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string { + w.Hide() - /* - tk := me.dropdownV - if tk.Visible() { - log.Log(NOW, "hide DDview() Mouse really down at:", mouseX, mouseH) - // hideDDview() - } else { - log.Log(NOW, "show DDview() Mouse really down at:", mouseX, mouseH) - log.Log(NOW, "can you see the dropdown menu right now?") - log.Log(NOW, "if so, something is wrong. I think you can't see it") - showDDview() + startW, startH := w.Position() + log.Log(NOW, "dropdownClicked() start (w,h) =", startW, startH) + log.Log(NOW, "dropdownClicked() at (w,h) =", mouseW, mouseH) + + itemNumber := mouseH - startH + log.Log(NOW, "dropdownClicked() look for item", itemNumber) + if itemNumber < 1 { + return "" } - */ -} + items := strings.Split(w.labelN, "\n") + if len(items) >= itemNumber-1 { + log.Log(NOW, "dropdownClicked() found", items[itemNumber-1]) + return items[itemNumber-1] + } + return "" +} func dropdownUnclicked(mouseX, mouseH int) { tk := me.dropdownV diff --git a/main.go b/main.go index c056652..07cdb68 100644 --- a/main.go +++ b/main.go @@ -123,7 +123,6 @@ func gocuiMain() { log.Warn("YAHOOOO Recovered in gocuiMain()", r) log.Warn("Recovered from panic:", r) me.baseGui.Close() - panic("BUMMER 2") // allow gocui to close if possible, then print stack log.Sleep(1) @@ -132,6 +131,7 @@ func gocuiMain() { me.myTree.SendToolkitPanic() log.Warn("Stack trace:") debug.PrintStack() + // panic("BUMMER 2") // attempt to switch to the nocui toolkit log.Sleep(1) diff --git a/place.go b/place.go index 726e8ed..1ef1775 100644 --- a/place.go +++ b/place.go @@ -214,3 +214,53 @@ func textSize(n *tree.Node) (int, int) { } 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 + } +} diff --git a/tab.go b/tab.go deleted file mode 100644 index e318035..0000000 --- a/tab.go +++ /dev/null @@ -1,118 +0,0 @@ -package main - -import ( - "strings" - - "go.wit.com/widget" -) - -/* -func (w *guiWidget) RealWidth() int { - if w.frame { - return w.gocuiSize.w1 - w.gocuiSize.w0 - } - return w.gocuiSize.w1 - w.gocuiSize.w0 - 1 -} - -func (w *guiWidget) Height() int { - if w.frame { - return w.gocuiSize.h1 - w.gocuiSize.h0 - } - return w.gocuiSize.h1 - w.gocuiSize.h0 - 1 -} -*/ - -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 - } -} - -func (w *guiWidget) redoWindows(nextW int, nextH int) { - var startW int = nextW - var startH int = nextH - - for _, child := range w.children { - if child.node.WidgetType != widget.Window { - continue - } - - child.frame = false - child.hasTabs = false - - child.gocuiSetWH(nextW, nextH) - child.deleteView() - child.showView() - sizeW := child.gocuiSize.Width() - nextW += sizeW + 4 - child.redoWindows(startW+3, startH+2) - } -} - -/* -func (p *guiWidget) redoTabs(nextW int, nextH int) { - for _, w := range p.children { - if w.node.WidgetType != widget.Tab { - continue - } - w.frame = true - - w.gocuiSetWH(nextW, nextH) - w.deleteView() - // setCurrentTab(n) - // if (len(w.cuiName) < 4) { - // w.cuiName = "abcd" - // } - - w.showView() - - sizeW := w.Width() + me.TabPadW - sizeH := w.Height() - log.Log(NOW, "redoTabs() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, w.String()) - nextW += sizeW - } -} -*/ - -/* -func (p *guiWidget) drawWindow(nextW int, nextH int) { - for _, w := range p.children { - w.frame = true - - w.gocuiSetWH(nextW, nextH) - w.deleteView() - // setCurrentTab(n) - // if (len(w.cuiName) < 4) { - // w.cuiName = "abcd" - // } - - w.showView() - - sizeW := w.gocuiSize.Width() + me.TabPadW - sizeH := w.gocuiSize.Height() - log.Log(NOW, "redoTabs() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, w.String()) - nextW += sizeW - } -} -*/ diff --git a/view.go b/view.go index 67a1e11..0709a1c 100644 --- a/view.go +++ b/view.go @@ -63,10 +63,10 @@ func (w *guiWidget) showView() { log.Log(INFO, "showView() labelN =", w.labelN) /* - if w.hidden { - w.SetVisible(false) - return - } + if w.hidden { + w.SetVisible(false) + return + } */ if w.v != nil { return @@ -77,41 +77,41 @@ func (w *guiWidget) showView() { w.v.Clear() fmt.Fprint(w.v, w.labelN) /* - x0, y0, x1, y1, _ := me.baseGui.ViewPosition(w.cuiName) - // x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName) - // log.Log(INFO, "showView() w.v already defined for widget", w.String(), x0, y0, x1, y1, err) + x0, y0, x1, y1, _ := me.baseGui.ViewPosition(w.cuiName) + // x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName) + // log.Log(INFO, "showView() w.v already defined for widget", w.String(), x0, y0, x1, y1, err) - // n.smartGocuiSize() - // changed := w.textResize() + // n.smartGocuiSize() + // changed := w.textResize() - log.Log(INFO, "showView() Clear() and Fprint() here wId =", w.cuiName) - w.v.Clear() - fmt.Fprint(w.v, w.labelN) - log.Log(INFO, "showView() textResize() changed. Should recreateView here wId =", w.cuiName) + log.Log(INFO, "showView() Clear() and Fprint() here wId =", w.cuiName) + w.v.Clear() + fmt.Fprint(w.v, w.labelN) + log.Log(INFO, "showView() textResize() changed. Should recreateView here wId =", w.cuiName) */ /* - // if the gocui element has changed where it is supposed to be on the screen - // recreate it - if x0 != w.gocuiSize.w0 { - w.recreateView() - return - } - if y0 != w.gocuiSize.h0 { - log.Log(ERROR, "showView() start hight mismatch id=", w.cuiName, "gocui h vs computed h =", w.gocuiSize.h0, y0) - w.recreateView() - return - } - if x1 != w.gocuiSize.w1 { - log.Log(INFO, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1) - w.recreateView() - return - } - if y1 != w.gocuiSize.h1 { - log.Log(ERROR, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1) - w.recreateView() - return - } + // if the gocui element has changed where it is supposed to be on the screen + // recreate it + if x0 != w.gocuiSize.w0 { + w.recreateView() + return + } + if y0 != w.gocuiSize.h0 { + log.Log(ERROR, "showView() start hight mismatch id=", w.cuiName, "gocui h vs computed h =", w.gocuiSize.h0, y0) + w.recreateView() + return + } + if x1 != w.gocuiSize.w1 { + log.Log(INFO, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1) + w.recreateView() + return + } + if y1 != w.gocuiSize.h1 { + log.Log(ERROR, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1) + w.recreateView() + return + } */ // w.SetVisible(true) diff --git a/widget.go b/widget.go index ec1387c..10f1af9 100644 --- a/widget.go +++ b/widget.go @@ -3,6 +3,7 @@ package main import ( "strconv" + "github.com/awesome-gocui/gocui" "go.wit.com/log" "go.wit.com/toolkits/tree" "go.wit.com/widget" @@ -11,19 +12,13 @@ import ( func initWidget(n *tree.Node) *guiWidget { var w *guiWidget w = new(guiWidget) - // Set(w, "default") w.node = n - - // set the name used by gocui to the id - // w.cuiName = string(n.WidgetId) - w.cuiName = strconv.Itoa(w.node.WidgetId) + " TK" - w.WidgetType = n.WidgetType - w.labelN = n.State.Label if w.labelN == "" { + // remove this debugging hack once things are stable and fixed w.labelN = n.GetProgName() } w.frame = true @@ -106,7 +101,6 @@ func (tk *guiWidget) Visible() bool { if tk.v == nil { return false } - // return tk.v.Visible tk.v.Visible = true return true } @@ -125,5 +119,35 @@ func (tk *guiWidget) SetVisible(b bool) { } else { tk.Hide() } - // w.v.Visible = b +} + +func (tk *guiWidget) findWidgetByName(name string) *guiWidget { + if tk.cuiName == name { + return tk + } + for _, child := range tk.children { + found := child.findWidgetByName(name) + if found != nil { + return found + } + } + return nil +} + +func (tk *guiWidget) findWidgetByView(v *gocui.View) *guiWidget { + if tk.v == v { + return tk + } + if tk.cuiName == v.Name() { + log.Log(NOW, "findWidget() error. names are mismatched or out of sync", tk.cuiName) + log.Log(NOW, "findWidget() or maybe the view has been deleted") + // return tk + } + for _, child := range tk.children { + found := child.findWidgetByView(v) + if found != nil { + return found + } + } + return nil } diff --git a/window.go b/window.go new file mode 100644 index 0000000..0918c45 --- /dev/null +++ b/window.go @@ -0,0 +1,26 @@ +package main + +import ( + "go.wit.com/widget" +) + +func (w *guiWidget) redoWindows(nextW int, nextH int) { + var startW int = nextW + var startH int = nextH + + for _, child := range w.children { + if child.node.WidgetType != widget.Window { + continue + } + + child.frame = false + child.hasTabs = false + + child.gocuiSetWH(nextW, nextH) + child.deleteView() + child.showView() + sizeW := child.gocuiSize.Width() + nextW += sizeW + 4 + child.redoWindows(startW+3, startH+2) + } +}