2024-01-01 16:11:54 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"errors"
|
|
|
|
"bufio"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/awesome-gocui/gocui"
|
2024-01-08 20:52:10 -06:00
|
|
|
|
|
|
|
"go.wit.com/log"
|
2024-01-05 13:35:01 -06:00
|
|
|
"go.wit.com/gui/widget"
|
2024-01-01 16:11:54 -06:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2024-01-11 19:10:24 -06:00
|
|
|
for i, s := range splitLines(n.tk.label) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(INFO, "textResize() len =", len(s), i, s)
|
2024-01-01 16:11:54 -06:00
|
|
|
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) {
|
2024-01-08 20:52:10 -06:00
|
|
|
n.showWidgetPlacement(true, "textResize() changed")
|
2024-01-01 16:11:54 -06:00
|
|
|
}
|
|
|
|
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 == "") {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "showView() w.cuiName was not set for widget", w)
|
2024-01-17 21:31:49 -06:00
|
|
|
w.cuiName = string(n.WidgetId)
|
2024-01-01 16:11:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
2024-01-11 19:10:24 -06:00
|
|
|
log.Log(INFO, "showView() w.v already defined for widget", n.progname, err)
|
2024-01-01 16:11:54 -06:00
|
|
|
|
|
|
|
// n.smartGocuiSize()
|
|
|
|
changed := n.textResize()
|
|
|
|
|
|
|
|
if (changed) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(NOW, "showView() textResize() changed. Should recreateView here wId =", w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
} else {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(NOW, "showView() Clear() and Fprint() here wId =", w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
w.v.Clear()
|
2024-01-11 19:10:24 -06:00
|
|
|
fmt.Fprint(w.v, n.tk.label)
|
2024-01-01 16:11:54 -06:00
|
|
|
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) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "showView() start hight mismatch id=", w.cuiName, "gocui h vs computed h =", w.gocuiSize.h0, y0)
|
2024-01-01 16:11:54 -06:00
|
|
|
n.recreateView()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (x1 != w.gocuiSize.w1) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1)
|
2024-01-01 16:11:54 -06:00
|
|
|
n.recreateView()
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if (y1 != w.gocuiSize.h1) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1)
|
2024-01-01 16:11:54 -06:00
|
|
|
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
|
2024-01-11 19:10:24 -06:00
|
|
|
log.Log(ERROR, "recreateView() START", n.WidgetType, n.progname)
|
2024-01-01 16:11:54 -06:00
|
|
|
if (me.baseGui == nil) {
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "recreateView() ERROR: me.baseGui == nil", w)
|
2024-01-01 16:11:54 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
// this deletes the button from gocui
|
|
|
|
me.baseGui.DeleteView(w.cuiName)
|
|
|
|
w.v = nil
|
|
|
|
|
2024-01-11 19:10:24 -06:00
|
|
|
if (n.progname == "CLOUDFLARE_EMAIL") {
|
|
|
|
n.showWidgetPlacement(true, "n.progname=" + n.progname + " n.tk.label=" + n.tk.label + " " + w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
n.dumpWidget("jwc")
|
|
|
|
n.textResize()
|
2024-01-11 19:10:24 -06:00
|
|
|
n.showWidgetPlacement(true, "n.progname=" + n.progname + " n.tk.label=" + n.tk.label + " " + w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
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 {
|
2024-01-08 20:52:10 -06:00
|
|
|
n.showWidgetPlacement(true, "recreateView()")
|
|
|
|
log.Log(ERROR, "recreateView() internal plugin error err = nil")
|
2024-01-01 16:11:54 -06:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
2024-01-08 20:52:10 -06:00
|
|
|
n.showWidgetPlacement(true, "recreateView()")
|
|
|
|
log.Log(ERROR, "recreateView() internal plugin error error.IS()", err)
|
2024-01-01 16:11:54 -06:00
|
|
|
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()
|
2024-01-11 19:10:24 -06:00
|
|
|
fmt.Fprint(w.v, n.tk.label)
|
|
|
|
// n.showWidgetPlacement(true, "n.progname=" + n.progname + " n.tk.label=" + n.tk.label + " " + w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
// 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
|
|
|
|
}
|
2024-01-11 19:10:24 -06:00
|
|
|
if (n.progname == "CLOUDFLARE_EMAIL") {
|
|
|
|
n.showWidgetPlacement(true, "n.progname=" + n.progname + " n.tk.label=" + n.tk.label + " " + w.cuiName)
|
2024-01-01 16:11:54 -06:00
|
|
|
n.dumpTree(true)
|
|
|
|
}
|
2024-01-08 20:52:10 -06:00
|
|
|
log.Log(ERROR, "recreateView() END")
|
2024-01-01 16:11:54 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (n *node) hideWidgets() {
|
|
|
|
w := n.tk
|
|
|
|
w.isCurrent = false
|
|
|
|
switch n.WidgetType {
|
2024-01-05 13:35:01 -06:00
|
|
|
case widget.Root:
|
|
|
|
case widget.Flag:
|
|
|
|
case widget.Window:
|
|
|
|
case widget.Box:
|
|
|
|
case widget.Grid:
|
2024-01-01 16:11:54 -06:00
|
|
|
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()
|
2024-01-08 20:52:10 -06:00
|
|
|
n.showWidgetPlacement(true, "showFake:")
|
2024-01-01 16:11:54 -06:00
|
|
|
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 {
|
2024-01-08 20:52:10 -06:00
|
|
|
n.showWidgetPlacement(true, "current:")
|
2024-01-01 16:11:54 -06:00
|
|
|
n.showView()
|
|
|
|
}
|
|
|
|
for _, child := range n.children {
|
|
|
|
child.showWidgets()
|
|
|
|
}
|
|
|
|
}
|