summaryrefslogtreecommitdiff
path: root/view.go
diff options
context:
space:
mode:
Diffstat (limited to 'view.go')
-rw-r--r--view.go233
1 files changed, 233 insertions, 0 deletions
diff --git a/view.go b/view.go
new file mode 100644
index 0000000..b2bc81b
--- /dev/null
+++ b/view.go
@@ -0,0 +1,233 @@
+package main
+
+import (
+ "bufio"
+ "errors"
+ "fmt"
+ "strings"
+
+ "github.com/awesome-gocui/gocui"
+
+ "go.wit.com/lib/widget"
+ "go.wit.com/log"
+)
+
+func splitLines(s string) []string {
+ var lines []string
+ sc := bufio.NewScanner(strings.NewReader(s))
+ for sc.Scan() {
+ lines = append(lines, sc.Text())
+ }
+ return lines
+}
+
+func (n *node) textResize() bool {
+ w := n.tk
+ var width, height int = 0, 0
+ var changed bool = false
+
+ for i, s := range splitLines(n.tk.label) {
+ log.Log(INFO, "textResize() len =", len(s), i, s)
+ if width < len(s) {
+ width = len(s)
+ }
+ height += 1
+ }
+ if w.gocuiSize.w1 != w.gocuiSize.w0+width+me.FramePadW {
+ w.gocuiSize.w1 = w.gocuiSize.w0 + width + me.FramePadW
+ changed = true
+ }
+ if w.gocuiSize.h1 != w.gocuiSize.h0+height+me.FramePadH {
+ w.gocuiSize.h1 = w.gocuiSize.h0 + height + me.FramePadH
+ changed = true
+ }
+ if changed {
+ n.showWidgetPlacement(true, "textResize() changed")
+ }
+ return changed
+}
+
+func (n *node) hideView() {
+ n.SetVisible(false)
+}
+
+// display's the text of the widget in gocui
+// will create a new gocui view if there isn't one or if it has been moved
+func (n *node) showView() {
+ var err error
+ w := n.tk
+
+ if w.cuiName == "" {
+ log.Log(ERROR, "showView() w.cuiName was not set for widget", w)
+ w.cuiName = string(n.WidgetId)
+ }
+
+ // if the gocui element doesn't exist, create it
+ if w.v == nil {
+ n.recreateView()
+ }
+ x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName)
+ log.Log(INFO, "showView() w.v already defined for widget", n.progname, err)
+
+ // n.smartGocuiSize()
+ changed := n.textResize()
+
+ if changed {
+ log.Log(NOW, "showView() textResize() changed. Should recreateView here wId =", w.cuiName)
+ } else {
+ log.Log(NOW, "showView() Clear() and Fprint() here wId =", w.cuiName)
+ w.v.Clear()
+ fmt.Fprint(w.v, n.tk.label)
+ n.SetVisible(false)
+ n.SetVisible(true)
+ return
+ }
+
+ // if the gocui element has changed where it is supposed to be on the screen
+ // recreate it
+ if x0 != w.gocuiSize.w0 {
+ n.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)
+ n.recreateView()
+ return
+ }
+ if x1 != w.gocuiSize.w1 {
+ log.Log(ERROR, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1)
+ n.recreateView()
+ return
+ }
+ if y1 != w.gocuiSize.h1 {
+ log.Log(ERROR, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1)
+ n.recreateView()
+ return
+ }
+
+ n.SetVisible(true)
+}
+
+// create or recreate the gocui widget visible
+// deletes the old view if it exists and recreates it
+func (n *node) recreateView() {
+ var err error
+ w := n.tk
+ log.Log(ERROR, "recreateView() START", n.WidgetType, n.progname)
+ if me.baseGui == nil {
+ log.Log(ERROR, "recreateView() ERROR: me.baseGui == nil", w)
+ return
+ }
+
+ // this deletes the button from gocui
+ me.baseGui.DeleteView(w.cuiName)
+ w.v = nil
+
+ if n.progname == "CLOUDFLARE_EMAIL" {
+ n.showWidgetPlacement(true, "n.progname="+n.progname+" n.tk.label="+n.tk.label+" "+w.cuiName)
+ n.dumpWidget("jwc")
+ n.textResize()
+ n.showWidgetPlacement(true, "n.progname="+n.progname+" n.tk.label="+n.tk.label+" "+w.cuiName)
+ }
+
+ a := w.gocuiSize.w0
+ b := w.gocuiSize.h0
+ c := w.gocuiSize.w1
+ d := w.gocuiSize.h1
+
+ w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
+ if err == nil {
+ n.showWidgetPlacement(true, "recreateView()")
+ log.Log(ERROR, "recreateView() internal plugin error err = nil")
+ return
+ }
+ if !errors.Is(err, gocui.ErrUnknownView) {
+ n.showWidgetPlacement(true, "recreateView()")
+ log.Log(ERROR, "recreateView() internal plugin error error.IS()", err)
+ return
+ }
+
+ // this sets up the keybinding for the name of the window
+ // does this really need to be done? I think we probably already
+ // know everything about where all the widgets are so we could bypass
+ // the gocui package and just handle all the mouse events internally here (?)
+ // for now, the w.v.Name is a string "1", "2", "3", etc from the widgetId
+
+ // set the binding for this gocui view now that it has been created
+ // gocui handles overlaps of views so it will run on the view that is clicked on
+ me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
+
+ // this actually sends the text to display to gocui
+ w.v.Wrap = true
+ w.v.Frame = w.frame
+ w.v.Clear()
+ fmt.Fprint(w.v, n.tk.label)
+ // n.showWidgetPlacement(true, "n.progname=" + n.progname + " n.tk.label=" + n.tk.label + " " + w.cuiName)
+ // n.dumpWidget("jwc 2")
+
+ // if you don't do this here, it will be black & white only
+ if w.color != nil {
+ w.v.FrameColor = w.color.frame
+ w.v.FgColor = w.color.fg
+ w.v.BgColor = w.color.bg
+ w.v.SelFgColor = w.color.selFg
+ w.v.SelBgColor = w.color.selBg
+ }
+ if n.progname == "CLOUDFLARE_EMAIL" {
+ n.showWidgetPlacement(true, "n.progname="+n.progname+" n.tk.label="+n.tk.label+" "+w.cuiName)
+ n.dumpTree(true)
+ }
+ log.Log(ERROR, "recreateView() END")
+}
+
+func (n *node) hideWidgets() {
+ w := n.tk
+ w.isCurrent = false
+ switch n.WidgetType {
+ case widget.Root:
+ case widget.Flag:
+ case widget.Window:
+ case widget.Box:
+ case widget.Grid:
+ default:
+ n.hideView()
+ }
+ for _, child := range n.children {
+ child.hideWidgets()
+ }
+}
+
+func (n *node) hideFake() {
+ w := n.tk
+ if w.isFake {
+ n.hideView()
+ }
+ for _, child := range n.children {
+ child.hideFake()
+ }
+}
+
+func (n *node) showFake() {
+ w := n.tk
+ if w.isFake {
+ n.setFake()
+ n.showWidgetPlacement(true, "showFake:")
+ n.showView()
+ }
+ for _, child := range n.children {
+ child.showFake()
+ }
+}
+
+func (n *node) showWidgets() {
+ w := n.tk
+ if w.isFake {
+ // don't display by default
+ } else {
+ n.showWidgetPlacement(true, "current:")
+ n.showView()
+ }
+ for _, child := range n.children {
+ child.showWidgets()
+ }
+}