summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile7
-rw-r--r--README-goreadme.md12
-rw-r--r--cmds/buttonplugin/Makefile2
-rw-r--r--cmds/buttonplugin/log.go7
-rw-r--r--cmds/buttonplugin/main.go9
-rw-r--r--cmds/cloudflare/Makefile18
-rw-r--r--cmds/cloudflare/argv.go30
-rw-r--r--cmds/cloudflare/dns.go115
-rw-r--r--cmds/cloudflare/main.go122
-rw-r--r--log/structs.go13
-rw-r--r--main.go4
-rw-r--r--plugin.go9
-rw-r--r--structs.go4
-rw-r--r--toolkit/gocui/add.go83
-rw-r--r--toolkit/gocui/checkbox.go31
-rw-r--r--toolkit/gocui/click.go297
-rw-r--r--toolkit/gocui/color.go19
-rw-r--r--toolkit/gocui/common.go210
-rw-r--r--toolkit/gocui/debug.go69
-rw-r--r--toolkit/gocui/globalDown.go37
-rw-r--r--toolkit/gocui/gocui.go100
-rw-r--r--toolkit/gocui/help.go14
-rw-r--r--toolkit/gocui/keybindings.go56
-rw-r--r--toolkit/gocui/main.go2
-rw-r--r--toolkit/gocui/mouse.go88
-rw-r--r--toolkit/gocui/place.go333
-rw-r--r--toolkit/gocui/plugin.go85
-rw-r--r--toolkit/gocui/showStdout.go24
-rw-r--r--toolkit/gocui/structs.go144
-rw-r--r--toolkit/gocui/tab.go185
-rw-r--r--toolkit/gocui/view.go132
32 files changed, 1342 insertions, 920 deletions
diff --git a/.gitignore b/.gitignore
index 0a7f6ab..03137f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,6 +8,7 @@ cmds/console-ui-helloworld/console-ui-helloworld
cmds/debug/debug
cmds/helloworld/helloworld
cmds/textbox/textbox
+cmds/cloudflare/cloudflare
cmds/*/helloconsole
# temporary files when building debian packages
diff --git a/Makefile b/Makefile
index 2949aae..8e73c22 100644
--- a/Makefile
+++ b/Makefile
@@ -8,6 +8,7 @@ all: README.md
@echo
make clean
make plugins
+ make cmds-buttonplugin
build-dep:
apt install -f libgtk-3-dev
@@ -82,11 +83,11 @@ clean:
plugins: plugins-gocui plugins-andlabs
plugins-gocui:
- GO111MODULE="off" go build -v -x -C toolkit/gocui -buildmode=plugin -o ../gocui.so
- GO111MODULE="off" go build -v -x -C toolkit/nocui -buildmode=plugin -o ../nocui.so
+ GO111MODULE="off" go build -C toolkit/gocui -v -buildmode=plugin -o ../gocui.so
+ GO111MODULE="off" go build -C toolkit/nocui -v -buildmode=plugin -o ../nocui.so
plugins-andlabs:
- GO111MODULE="off" go build -v -x -C toolkit/andlabs -buildmode=plugin -o ../andlabs.so
+ GO111MODULE="off" go build -C toolkit/andlabs -v -buildmode=plugin -o ../andlabs.so
objdump:
objdump -t toolkit/andlabs.so |less
diff --git a/README-goreadme.md b/README-goreadme.md
index 63698b8..454cfff 100644
--- a/README-goreadme.md
+++ b/README-goreadme.md
@@ -139,7 +139,7 @@ Creates a window helpful for debugging this package
`func ShowDebugValues()`
-### func [StandardExit](/main.go#L149)
+### func [StandardExit](/main.go#L153)
`func StandardExit()`
@@ -158,13 +158,19 @@ This goroutine can be used like a watchdog timer
## Types
-### type [GuiArgs](/structs.go#L27)
+### type [GuiArgs](/structs.go#L29)
`type GuiArgs struct { ... }`
This struct can be used with the go-arg package
-### type [Node](/structs.go#L57)
+#### Variables
+
+```golang
+var GuiArg GuiArgs
+```
+
+### type [Node](/structs.go#L59)
`type Node struct { ... }`
diff --git a/cmds/buttonplugin/Makefile b/cmds/buttonplugin/Makefile
index 1903a67..74486e5 100644
--- a/cmds/buttonplugin/Makefile
+++ b/cmds/buttonplugin/Makefile
@@ -7,7 +7,7 @@
#
run: build
- ./buttonplugin --gui-toolkit gocui >/tmp/witgui.log.stderr 2>&1
+ ./buttonplugin --gui gocui >/tmp/witgui.log.stderr 2>&1
build-release:
go get -v -u -x .
diff --git a/cmds/buttonplugin/log.go b/cmds/buttonplugin/log.go
index 13238f4..7d65d05 100644
--- a/cmds/buttonplugin/log.go
+++ b/cmds/buttonplugin/log.go
@@ -5,6 +5,7 @@ import (
"fmt"
arg "github.com/alexflint/go-arg"
"git.wit.org/wit/gui"
+ log "git.wit.org/wit/gui/log"
)
@@ -14,6 +15,7 @@ var args struct {
User string `arg:"env:USER"`
Demo bool `help:"run a demo"`
gui.GuiArgs
+ log.LogArgs
}
/*
@@ -26,6 +28,11 @@ func init() {
arg.MustParse(&args)
fmt.Println(args.Foo, args.Bar, args.User)
+ if (args.Gui != "") {
+ gui.GuiArg.Gui = args.Gui
+ }
+ log.Log(true, "INIT() args.GuiArg.Gui =", gui.GuiArg.Gui)
+
/*
log.Println()
log.Println("STDOUT is now at /tmp/guilogfile")
diff --git a/cmds/buttonplugin/main.go b/cmds/buttonplugin/main.go
index 1fd8b5f..3200e9e 100644
--- a/cmds/buttonplugin/main.go
+++ b/cmds/buttonplugin/main.go
@@ -20,14 +20,7 @@ func main() {
// This will turn on all debugging
// gui.SetDebug(true)
- // myGui = gui.New().LoadToolkit("gocui")
- // myGui = gui.New().LoadToolkit("andlabs")
- // myGui = gui.New().Default()
- if (args.GuiToolkit == nil) {
- myGui = gui.New().Default()
- } else {
- myGui = gui.New().LoadToolkit(args.GuiToolkit[0])
- }
+ myGui = gui.New().Default()
buttonWindow()
// This is just a optional goroutine to watch that things are alive
diff --git a/cmds/cloudflare/Makefile b/cmds/cloudflare/Makefile
new file mode 100644
index 0000000..bcd88c6
--- /dev/null
+++ b/cmds/cloudflare/Makefile
@@ -0,0 +1,18 @@
+run: build
+ ./cloudflare
+
+build-release:
+ go get -v -u -x .
+ go build
+ ./cloudflare
+
+build:
+ GO111MODULE="off" go get -v -x .
+ GO111MODULE="off" go build
+
+update:
+ GO111MODULE="off" go get -v -u -x .
+
+log:
+ reset
+ tail -f /tmp/witgui.* /tmp/guilogfile
diff --git a/cmds/cloudflare/argv.go b/cmds/cloudflare/argv.go
new file mode 100644
index 0000000..38579c7
--- /dev/null
+++ b/cmds/cloudflare/argv.go
@@ -0,0 +1,30 @@
+// This creates a simple hello world window
+package main
+
+import (
+ "fmt"
+ arg "github.com/alexflint/go-arg"
+ "git.wit.org/wit/gui"
+ log "git.wit.org/wit/gui/log"
+)
+
+
+var args struct {
+ Foo string
+ Bar bool
+ User string `arg:"env:USER"`
+ Demo bool `help:"run a demo"`
+ gui.GuiArgs
+ log.LogArgs
+}
+
+func init() {
+ arg.MustParse(&args)
+ fmt.Println(args.Foo, args.Bar, args.User)
+
+ if (args.Gui != "") {
+ gui.GuiArg.Gui = args.Gui
+ }
+ log.Log(true, "INIT() args.GuiArg.Gui =", gui.GuiArg.Gui)
+
+}
diff --git a/cmds/cloudflare/dns.go b/cmds/cloudflare/dns.go
new file mode 100644
index 0000000..6626843
--- /dev/null
+++ b/cmds/cloudflare/dns.go
@@ -0,0 +1,115 @@
+// This is a simple example
+package main
+
+import (
+ "os"
+ "log"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "strconv"
+)
+
+// Define a struct to match the JSON structure of the response.
+// This structure should be adjusted based on the actual format of the response.
+type DNSRecords struct {
+ Result []struct {
+ ID string `json:"id"`
+ Type string `json:"type"`
+ Name string `json:"name"`
+ Content string `json:"content"`
+ Proxied bool `json:"proxied"`
+ Proxiable bool `json:"proxiable"`
+ TTL int `json:"ttl"`
+ } `json:"result"`
+}
+
+// var domain string = "wit.org"
+// var os.Getenv("CLOUDFLARE_DOMAIN")
+
+func loadDNS(hostname string) {
+ log.Println("adding DNS record")
+
+ // more2.NewButton(name, func () {
+ // log.Println(name, "ip =", ip)
+ // })
+
+ newt := mainWindow.NewTab(hostname)
+ newg := newt.NewGroup("more")
+ more2 := newg.NewGrid("gridnuts", 5, gridH)
+
+ records := getRecords()
+ for _, record := range records.Result {
+ more2.NewLabel(record.Type)
+ more2.NewLabel(record.Name)
+ if (record.Proxied) {
+ more2.NewLabel("Proxied")
+ } else {
+ more2.NewLabel("DNS")
+ }
+ var ttl, short string
+ if (record.TTL == 1) {
+ ttl = "Auto"
+ } else {
+ ttl = strconv.Itoa(record.TTL)
+ }
+ more2.NewLabel(ttl)
+ // short = fmt.Sprintf("%80s", record.Content)
+ short = record.Content
+ if len(short) > 40 {
+ short = short[:40] // Slice the first 20 characters
+ }
+ more2.NewLabel(short)
+
+ fmt.Printf("ID: %s, Type: %s, Name: %s, short Content: %s\n", record.ID, record.Type, record.Name, short)
+ fmt.Printf("\tproxied: %b, %b, string TTL: %i\n", record.Proxied, record.Proxiable, ttl)
+ }
+}
+
+
+func getRecords() *DNSRecords {
+ var url string = os.Getenv("CLOUDFLARE_URL")
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ fmt.Println(err)
+ return nil
+ }
+
+ var authKey string = os.Getenv("CLOUDFLARE_AUTHKEY")
+ var email string = os.Getenv("CLOUDFLARE_EMAIL")
+
+ // Set headers
+ req.Header.Set("X-Auth-Key", authKey)
+ req.Header.Set("X-Auth-Email", email)
+
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ fmt.Println(err)
+ return nil
+ }
+ defer resp.Body.Close()
+
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ fmt.Println(err)
+ return nil
+ }
+
+ var records DNSRecords
+ if err := json.Unmarshal(body, &records); err != nil {
+ fmt.Println(err)
+ return nil
+ }
+
+ // Process the records as needed
+ /*
+ for _, record := range records.Result {
+ fmt.Printf("ID: %s, Type: %s, Name: %s, Content: %s\n", record.ID, record.Type, record.Name, record.Content)
+ fmt.Printf("\tproxied: %b, %b, TTL: %i\n", record.Proxied, record.Proxiable, record.TTL)
+ }
+ */
+
+ return &records
+}
diff --git a/cmds/cloudflare/main.go b/cmds/cloudflare/main.go
new file mode 100644
index 0000000..75ba448
--- /dev/null
+++ b/cmds/cloudflare/main.go
@@ -0,0 +1,122 @@
+// This is a simple example
+package main
+
+import (
+ "os"
+ "fmt"
+ "log"
+ "strconv"
+ "git.wit.org/wit/gui"
+)
+
+var title string = "Cloudflare DNS Control Panel"
+var outfile string = "/tmp/guilogfile"
+var myGui *gui.Node
+
+var buttonCounter int = 5
+var gridW int = 5
+var gridH int = 3
+
+var mainWindow, more, more2 *gui.Node
+
+func main() {
+ myGui = gui.New().Default()
+ buttonWindow()
+
+ // This is just a optional goroutine to watch that things are alive
+ gui.Watchdog()
+ gui.StandardExit()
+}
+
+// This creates a window
+func buttonWindow() {
+ var t, g *gui.Node
+
+ log.Println("buttonWindow() START")
+
+ mainWindow = myGui.NewWindow(title).SetText(title)
+ t = mainWindow.NewTab("Cloudflare")
+ g = t.NewGroup("buttons")
+ g1 := t.NewGroup("buttonGroup 2")
+
+ more = g1.NewGroup("more")
+ showCloudflareCredentials(more)
+
+ g1.NewButton("hello", func () {
+ log.Println("world")
+ })
+ more2 = g1.NewGrid("gridnuts", gridW, gridH)
+
+ var domain string = os.Getenv("CLOUDFLARE_DOMAIN")
+ if (domain == "") {
+ domain = "example.org"
+ }
+
+ g.NewButton("Load " + domain + " DNS", func () {
+ loadDNS(domain)
+ })
+
+ g.NewButton("Load 'gocui'", func () {
+ // this set the xterm and mate-terminal window title. maybe works generally?
+ fmt.Println("\033]0;" + title + "blah \007")
+ myGui.LoadToolkit("gocui")
+ })
+
+ g.NewButton("Load 'andlabs'", func () {
+ myGui.LoadToolkit("andlabs")
+ })
+
+ g.NewButton("NewButton(more)", func () {
+ name := "foobar " + strconv.Itoa(buttonCounter)
+ log.Println("NewButton(more) Adding button", name)
+ buttonCounter += 1
+ more.NewButton(name, func () {
+ log.Println("Got all the way to main() name =", name)
+ })
+ })
+
+ g.NewButton("NewButton(more2)", func () {
+ name := "foobar " + strconv.Itoa(buttonCounter)
+ log.Println("NewButton(more2) Adding button", name)
+ buttonCounter += 1
+ more2.NewButton(name, func () {
+ log.Println("Got all the way to main() name =", name)
+ })
+ })
+
+ g.NewButton("NewButton(more2 d)", func () {
+ name := "d" + strconv.Itoa(buttonCounter)
+ log.Println("NewButton(more2 d) Adding button", name)
+ buttonCounter += 1
+ more2.NewButton(name, func () {
+ log.Println("Got all the way to main() name =", name)
+ })
+ })
+
+ g.NewButton("NewGroup()", func () {
+ name := "neat " + strconv.Itoa(buttonCounter)
+ log.Println("NewGroup() Adding button", name)
+ buttonCounter += 1
+ more.NewGroup(name)
+ })
+
+ g.NewButton("gui.DebugWindow()", func () {
+ gui.DebugWindow()
+ })
+}
+
+func showCloudflareCredentials(box *gui.Node) {
+ grid := box.NewGrid("credsGrid", 2, 4) // width = 2
+
+ grid.NewLabel("Domain")
+ grid.NewLabel(os.Getenv("CLOUDFLARE_DOMAIN"))
+
+ grid.NewLabel("Auth Key")
+ grid.NewLabel(os.Getenv("CLOUDFLARE_AUTHKEY"))
+
+ grid.NewLabel("Email")
+ grid.NewLabel(os.Getenv("CLOUDFLARE_EMAIL"))
+
+ grid.NewLabel("URL")
+ grid.NewLabel(os.Getenv("CLOUDFLARE_URL"))
+}
diff --git a/log/structs.go b/log/structs.go
new file mode 100644
index 0000000..b5d849c
--- /dev/null
+++ b/log/structs.go
@@ -0,0 +1,13 @@
+package witlog
+
+import (
+)
+
+//
+// Attempt to switch logging to syslog on linux
+//
+
+// This struct can be used with the go-arg package
+type LogArgs struct {
+ Log []string `arg:"--log" help:"Where to log [syslog,stdout]"`
+}
diff --git a/main.go b/main.go
index 17b69ba..f121cec 100644
--- a/main.go
+++ b/main.go
@@ -123,6 +123,10 @@ func New() *Node {
// try to load andlabs, if that doesn't work, fall back to the console
func (n *Node) Default() *Node {
+ if (GuiArg.Gui != "") {
+ log(logError, "New.Default() try toolkit =", GuiArg.Gui)
+ return n.LoadToolkit(GuiArg.Gui)
+ }
// if DISPLAY isn't set, return since gtk can't load
// TODO: figure out how to check what to do in macos and mswindows
if (os.Getenv("DISPLAY") == "") {
diff --git a/plugin.go b/plugin.go
index d9f2bdd..42dc7cc 100644
--- a/plugin.go
+++ b/plugin.go
@@ -119,8 +119,15 @@ func searchPaths(name string) *aplug {
filename = "plugins/" + name + ".so"
pfile, err = me.resFS.ReadFile(filename)
if (err == nil) {
+ filename = "/tmp/" + name + ".so"
log(logError, "write out file here", name, filename, len(pfile))
- exit()
+ f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
+ f.Write(pfile)
+ f.Close()
+ p := initToolkit(name, filename)
+ if (p != nil) {
+ return p
+ }
} else {
log(logError, filename, "was not embedded. Error:", err)
}
diff --git a/structs.go b/structs.go
index 53572f2..b7a38a2 100644
--- a/structs.go
+++ b/structs.go
@@ -23,9 +23,11 @@ import (
var me guiConfig
+var GuiArg GuiArgs
+
// This struct can be used with the go-arg package
type GuiArgs struct {
- GuiToolkit []string `arg:"--gui-toolkit" help:"The order to attempt loading plugins [gocui,andlabs,gtk,qt]"`
+ Gui string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"`
GuiDebug bool `arg:"--gui-debug" help:"open the GUI debugger"`
GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
}
diff --git a/toolkit/gocui/add.go b/toolkit/gocui/add.go
index 3020c83..97d65d3 100644
--- a/toolkit/gocui/add.go
+++ b/toolkit/gocui/add.go
@@ -1,88 +1,67 @@
package main
import (
-// "github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
-// TODO: make these defaults in config struct definition
-var fakeStartWidth int = me.DevelOffsetW
+var fakeStartWidth int = me.FakeW
var fakeStartHeight int = me.TabH + me.FramePadH
-func (w *cuiWidget) setFake() {
+// setup fake labels for non-visible things off screen
+func (n *node) setFake() {
+ w := n.tk
w.isFake = true
- t := len(w.name)
- // setup fake labels for non-visable things off screen
- w.gocuiSize.w0 = fakeStartWidth
- w.gocuiSize.h0 = fakeStartHeight
- w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.PadW
- w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.PadH
+ n.gocuiSetWH(fakeStartWidth, fakeStartHeight)
- w.realWidth = w.gocuiSize.Width() + me.FramePadW
- w.realHeight = w.gocuiSize.Height() + me.FramePadH
-
- fakeStartHeight += w.realHeight
+ fakeStartHeight += w.gocuiSize.Height()
// TODO: use the actual max hight of the terminal window
if (fakeStartHeight > 24) {
- fakeStartHeight = me.TabH + me.FramePadH
- fakeStartWidth += me.DevelOffsetW
+ fakeStartHeight = me.TabH
+ fakeStartWidth += me.FakeW
}
if (logInfo) {
- w.showView()
+ n.showView()
}
}
// set the widget start width & height
-func (w *cuiWidget) addWidget() {
- log(logInfo, "setStartWH() w.id =", w.id, "w.name", w.name)
- switch w.widgetType {
+func (n *node) addWidget() {
+ nw := n.tk
+ log(logInfo, "setStartWH() w.id =", n.WidgetId, "n.name", n.Name)
+ switch n.WidgetType {
case toolkit.Root:
- log(logInfo, "setStartWH() rootNode w.id =", w.id, "w.name", w.name)
- w.setFake()
+ log(logInfo, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.Name)
+ n.setFake()
return
case toolkit.Flag:
- w.setFake()
+ n.setFake()
return
case toolkit.Window:
- me.current = w
- updateCurrentTabs()
- setCurrentWindow(w)
+ nw.frame = false
+ redoWindows(0,0)
return
case toolkit.Tab:
- // if this is the first tab, set it to the current one and stay here
- if (me.current != nil) {
- // there is already a current tab. just redraw the tabs
- updateCurrentTabs()
- return
- }
- setCurrentTab(w)
return
case toolkit.Box:
- w.isFake = true
- w.setFake()
- w.startW = w.parent.startW
- w.startH = w.parent.startH
+ nw.isFake = true
+ n.setFake()
return
case toolkit.Grid:
- w.isFake = true
- w.setFake()
- w.startW = w.parent.startW
- w.startH = w.parent.startH
+ nw.isFake = true
+ n.setFake()
return
case toolkit.Group:
- w.startW = w.parent.startW + 4
- w.startH = w.parent.startH + me.DefaultHeight + me.FramePadH
-
- t := len(w.text)
- w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.FramePadW
- w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.FramePadH
+ nw.frame = false
+ return
+ case toolkit.Label:
+ nw.frame = false
return
default:
- w.startW = w.parent.startW
- w.startH = w.parent.startH
- if w.IsCurrent() {
- w.updateCurrent()
+ /*
+ if n.IsCurrent() {
+ n.updateCurrent()
}
+ */
}
- w.showWidgetPlacement(logInfo, "addWidget()")
+ n.showWidgetPlacement(logInfo, "addWidget()")
}
diff --git a/toolkit/gocui/checkbox.go b/toolkit/gocui/checkbox.go
index 5568ee3..a1fe27c 100644
--- a/toolkit/gocui/checkbox.go
+++ b/toolkit/gocui/checkbox.go
@@ -5,28 +5,29 @@ import (
"git.wit.org/wit/gui/toolkit"
)
-func (w *cuiWidget) setCheckbox(b bool) {
- if (w.widgetType != toolkit.Checkbox) {
+func (n *node) setCheckbox(b bool) {
+ w := n.tk
+ if (n.WidgetType != toolkit.Checkbox) {
return
}
if (b) {
- w.b = b
- w.text = "X " + w.name
+ n.B = b
+ n.Text = "X " + n.Name
} else {
- w.b = b
- w.text = " " + w.name
+ n.B = b
+ n.Text = " " + n.Name
}
- t := len(w.text) + 1
+ t := len(n.Text) + 1
w.gocuiSize.w1 = w.gocuiSize.w0 + t
- w.realWidth = w.gocuiSize.Width() + me.PadW
- w.realHeight = w.gocuiSize.Height() + me.PadH
+// w.realWidth = w.gocuiSize.Width() + me.PadW
+// w.realHeight = w.gocuiSize.Height() + me.PadH
- if w.frame {
- w.realWidth += me.FramePadW
- w.realHeight += me.FramePadH
- }
+// if w.frame {
+// w.realWidth += me.FramePadW
+// w.realHeight += me.FramePadH
+// }
- w.deleteView()
- w.showView()
+ n.deleteView()
+ n.showView()
}
diff --git a/toolkit/gocui/click.go b/toolkit/gocui/click.go
index 8802674..380b0a3 100644
--- a/toolkit/gocui/click.go
+++ b/toolkit/gocui/click.go
@@ -1,278 +1,275 @@
package main
import (
- // "fmt"
- // "errors"
- "strconv"
- "strings"
-
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
// set isCurrent = false everywhere
-func UnsetCurrent(w *cuiWidget) {
+func UnsetCurrent(n *node) {
+ w := n.tk
w.isCurrent = false
- for _, child := range w.children {
+ for _, child := range n.children {
UnsetCurrent(child)
}
}
-func updateCurrentTabs() {
- me.rootNode.nextW = 0
- me.rootNode.nextH = 0
- me.rootNode.redoTabs(true)
-}
-
// 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 *cuiWidget) updateCurrent() {
- if w.widgetType == toolkit.Tab {
- if w.IsCurrent() {
- setCurrentTab(w)
+func (n *node) updateCurrent() {
+ log("updateCurrent()", n.Name)
+ if n.WidgetType == toolkit.Tab {
+ if n.IsCurrent() {
+ setCurrentTab(n)
}
return
}
- if w.widgetType == toolkit.Window {
- if w.IsCurrent() {
- setCurrentWindow(w)
+ if n.WidgetType == toolkit.Window {
+ if n.IsCurrent() {
+ // setCurrentWindow(n)
}
return
}
- if w.widgetType == toolkit.Root {
+ if n.WidgetType == toolkit.Root {
return
}
- w.parent.updateCurrent()
+ n.parent.updateCurrent()
}
// shows the widgets in a window
-func setCurrentWindow(w *cuiWidget) {
- if w.widgetType != toolkit.Window {
+func setCurrentWindow(n *node) {
+ if n.IsCurrent() {
+ return
+ }
+ w := n.tk
+ if n.WidgetType != toolkit.Window {
return
}
UnsetCurrent(me.rootNode)
- me.rootNode.hideWidgets()
-
- // THIS IS THE BEGINING OF THE LAYOUT
- me.rootNode.nextW = 0
- me.rootNode.nextH = 0
- w.isCurrent = true
- if w.hasTabs {
+ if n.hasTabs {
// set isCurrent = true on the first tab
- for _, child := range w.children {
- child.isCurrent = true
+ for _, child := range n.children {
+ child.tk.isCurrent = true
break
}
+ } else {
+ w.isCurrent = true
}
- me.rootNode.redoTabs(true)
-
- w.placeWidgets()
- w.showWidgets()
}
// shows the widgets in a tab
-func setCurrentTab(w *cuiWidget) {
- if w.widgetType != toolkit.Tab {
+func setCurrentTab(n *node) {
+ w := n.tk
+ if n.WidgetType != toolkit.Tab {
return
}
- me.current = w
UnsetCurrent(me.rootNode)
- me.rootNode.hideWidgets()
w.isCurrent = true
- w.parent.isCurrent = true
- updateCurrentTabs()
- w.placeWidgets()
- w.showWidgets()
+ p := n.parent.tk
+ p.isCurrent = true
+ log("setCurrent()", n.Name)
}
-func (w *cuiWidget) doWidgetClick() {
- switch w.widgetType {
+func (n *node) doWidgetClick() {
+ switch n.WidgetType {
case toolkit.Root:
// THIS IS THE BEGINING OF THE LAYOUT
- me.rootNode.nextW = 0
- me.rootNode.nextH = 0
- me.rootNode.redoTabs(true)
+ log("doWidgetClick()", n.Name)
+ redoWindows(0,0)
case toolkit.Flag:
// me.rootNode.redoColor(true)
me.rootNode.dumpTree(true)
case toolkit.Window:
- setCurrentWindow(w)
+ me.rootNode.hideWidgets()
+ n.redoTabs(me.TabW, me.TabH)
+ if ! n.hasTabs {
+ setCurrentWindow(n)
+ n.placeWidgets(me.RawW, me.RawH)
+ n.showWidgets()
+ }
case toolkit.Tab:
- setCurrentTab(w)
+ setCurrentTab(n)
+ n.placeWidgets(me.RawW, me.RawH)
+ n.showWidgets()
case toolkit.Group:
- w.placeWidgets()
- w.toggleTree()
+ // n.placeWidgets(p.tk.startH, newH)
+ n.toggleTree()
case toolkit.Checkbox:
- if (w.b) {
- w.setCheckbox(false)
+ if (n.B) {
+ n.setCheckbox(false)
} else {
- w.setCheckbox(true)
+ n.setCheckbox(true)
}
- w.doUserEvent()
+ n.doUserEvent()
case toolkit.Grid:
- me.rootNode.hideWidgets()
- w.placeGrid()
- w.showWidgets()
+ n.placeGrid(n.tk.size.w0, n.tk.size.h0)
+ n.showWidgets()
case toolkit.Box:
// w.showWidgetPlacement(logNow, "drawTree()")
- if (w.horizontal) {
- log("BOX IS HORIZONTAL", w.name)
+ if (n.horizontal) {
+ log("BOX IS HORIZONTAL", n.Name)
} else {
- log("BOX IS VERTICAL", w.name)
+ log("BOX IS VERTICAL", n.Name)
}
- w.placeWidgets()
- w.toggleTree()
+ // n.placeWidgets()
+ n.toggleTree()
case toolkit.Button:
- w.doUserEvent()
+ n.doUserEvent()
default:
}
}
-// this passes the user event back from the plugin
-func (w *cuiWidget) doUserEvent() {
- if (me.callback == nil) {
- log(logError, "doUserEvent() no callback channel was configured")
- return
- }
- var a toolkit.Action
- a.WidgetId = w.id
- a.Name = w.name
- a.Text = w.text
- a.B = w.b
- a.ActionType = toolkit.User
- me.callback <- a
- log(logNow, "END: sent a button click callback()")
-}
-
var toggle bool = true
-func (w *cuiWidget) toggleTree() {
+func (n *node) toggleTree() {
if (toggle) {
- w.drawTree(toggle)
+ n.drawTree(toggle)
toggle = false
} else {
- w.hideWidgets()
+ n.hideWidgets()
toggle = true
}
}
// display the widgets in the binary tree
-func (w *cuiWidget) drawTree(draw bool) {
+func (n *node) drawTree(draw bool) {
+ w := n.tk
if (w == nil) {
return
}
- w.showWidgetPlacement(logNow, "drawTree()")
+ n.showWidgetPlacement(logNow, "drawTree()")
if (draw) {
// w.textResize()
- w.showView()
+ n.showView()
} else {
- w.deleteView()
+ n.deleteView()
}
- for _, child := range w.children {
+ for _, child := range n.children {
child.drawTree(draw)
}
}
func click(g *gocui.Gui, v *gocui.View) error {
// var l string
- var err error
+ // var err error
- log(logNow, "click() START", v.Name())
+ log(logVerbose, "click() START", v.Name())
+ // n := me.rootNode.findWidgetName(v.Name())
+ n := findUnderMouse()
+ if (n != nil) {
+ log(logNow, "click() Found widget =", n.WidgetId, n.Name, ",", n.Text)
+ n.doWidgetClick()
+ } else {
+ log(logNow, "click() could not find node name =", v.Name())
+ }
+ /*
i, err := strconv.Atoi(v.Name())
if (err != nil) {
- log(logNow, "click() Can't find widget. error =", err)
+ log(logError, "click() Can't find widget. error =", err)
} else {
- log(logNow, "click() ok v.Name() =", v.Name())
- w := findWidget(i, me.rootNode)
- if (w == nil) {
+ log(logVerbose, "click() ok v.Name() =", v.Name())
+ n := me.rootNode.findWidgetId(i)
+ if (n == nil) {
log(logError, "click() CANT FIND VIEW in binary tree. v.Name =", v.Name())
return nil
}
- log(logNow, "click() Found widget =", w.id, w.name, ",", w.text)
- w.doWidgetClick()
+ log(logNow, "click() Found widget =", n.WidgetId, n.Name, ",", n.Text)
+ n.doWidgetClick()
return nil
}
+ */
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
- /*
- _, cy := v.Cursor()
- if l, err = v.Line(cy); err != nil {
- l = ""
- }
-
- maxX, maxY := g.Size()
- if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
- v.Clear()
- v.SelBgColor = gocui.ColorCyan
- v.SelFgColor = gocui.ColorBlack
- fmt.Fprintln(v, l)
- }
- */
-
- // this seems to delete the button(?)
- // g.SetViewOnBottom(v.Name())
- log(logNow, "click() END")
+ log(logVerbose, "click() END")
return nil
}
+func findUnderMouse() *node {
+ var found *node
+ var widgets []*node
+ var f func (n *node)
+ w, h := me.baseGui.MousePosition()
-// display the widgets in the binary tree
+ // find buttons that are below where the mouse button click
+ f = func(n *node) {
+ widget := n.tk
+ // ignore widgets that are not visible
+ if n.Visible() {
+ if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
+ (widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1)) {
+ widgets = append(widgets, n)
+ found = n
+ }
+ }
+ for _, child := range n.children {
+ f(child)
+ }
+ }
+ f(me.rootNode)
+ // widgets has everything that matches
+ // TODO: pop up menu with a list of them
+ for _, n := range widgets {
+ //log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
+ n.showWidgetPlacement(logNow, "ctrlDown() FOUND")
+ }
+ return found
+}
+
+// find the widget under the mouse click
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
- var found *cuiWidget
- var widgets []*cuiWidget
- var f func (widget *cuiWidget)
+ var found *node
+ // var widgets []*node
+ // var f func (n *node)
+ found = findUnderMouse()
+ /*
w, h := g.MousePosition()
// find buttons that are below where the mouse button click
- f = func(widget *cuiWidget) {
- // if ((widget.logicalSize.w0 < w) && (w < widget.logicalSize.w1)) {
- if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
- (widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1)) {
- widgets = append(widgets, widget)
- found = widget
+ f = func(n *node) {
+ widget := n.tk
+ // ignore widgets that are not visible
+ if n.Visible() {
+ if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
+ (widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1)) {
+ widgets = append(widgets, n)
+ found = n
+ }
}
- for _, child := range widget.children {
+ for _, child := range n.children {
f(child)
}
}
f(me.rootNode)
- var t string
- for _, widget := range widgets {
- // log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
- t += widget.cuiName + " " + widget.name + "\n"
- widget.showWidgetPlacement(logNow, "ctrlDown() FOUND")
- }
- t = strings.TrimSpace(t)
+ */
if (me.ctrlDown == nil) {
setupCtrlDownWidget()
- me.ctrlDown.text = "ctrlDown" // t
- me.ctrlDown.cuiName = "ctrlDown"
- me.ctrlDown.parent = me.rootNode
+ me.ctrlDown.Text = found.Name
+ me.ctrlDown.tk.cuiName = "ctrlDown"
+ // me.ctrlDown.parent = me.rootNode
}
+ cd := me.ctrlDown.tk
if (found == nil) {
found = me.rootNode
}
- // ? TODO: found.setRealSize()
- me.ctrlDown.gocuiSize.w0 = found.startW
- me.ctrlDown.gocuiSize.h0 = found.startH
- me.ctrlDown.gocuiSize.w1 = me.ctrlDown.gocuiSize.w0 + found.realWidth
- me.ctrlDown.gocuiSize.h1 = me.ctrlDown.gocuiSize.h0 + found.realHeight
- if (me.ctrlDown.v == nil) {
- me.ctrlDown.text = found.text
- me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
- me.ctrlDown.showView()
- } else {
+ me.ctrlDown.Text = found.Name
+ newR := found.realGocuiSize()
+ cd.gocuiSize.w0 = newR.w0
+ cd.gocuiSize.h0 = newR.h0
+ cd.gocuiSize.w1 = newR.w1
+ cd.gocuiSize.h1 = newR.h1
+ if me.ctrlDown.Visible() {
me.ctrlDown.deleteView()
+ } else {
+ me.ctrlDown.updateView()
}
-
- log(logNow, "ctrlDown()", w, h)
+ me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
return nil
}
diff --git a/toolkit/gocui/color.go b/toolkit/gocui/color.go
index c1216f0..5dbed05 100644
--- a/toolkit/gocui/color.go
+++ b/toolkit/gocui/color.go
@@ -8,8 +8,9 @@ import (
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
// gocui.GetColor("#FFAA55") // Dark Purple
-func (w *cuiWidget) setDefaultWidgetColor() {
- log(logInfo, "setDefaultWidgetColor() on", w.widgetType, w.name)
+func (n *node) setDefaultWidgetColor() {
+ w := n.tk
+ log(logInfo, "setDefaultWidgetColor() on", n.WidgetType, n.Name)
v, _ := me.baseGui.View(w.cuiName)
if (v == nil) {
log(logError, "setDefaultWidgetColor() failed on view == nil")
@@ -24,7 +25,7 @@ func (w *cuiWidget) setDefaultWidgetColor() {
// v.BgColor = gocui.GetColor("#55AAFF") // super light grey
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
- switch w.widgetType {
+ switch n.WidgetType {
case toolkit.Root:
v.FrameColor = gocui.ColorRed
v.BgColor = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
@@ -84,7 +85,8 @@ func (w *cuiWidget) SetColor(c string) {
}
}
-func (w *cuiWidget) setDefaultHighlight() {
+func (n *node) setDefaultHighlight() {
+ w := n.tk
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
@@ -100,16 +102,17 @@ func randColor() gocui.Attribute {
return gocui.GetColor(colors[i])
}
-func (w *cuiWidget) redoColor(draw bool) {
+func (n *node) redoColor(draw bool) {
+ w := n.tk
if (w == nil) {
return
}
sleep(.05)
- w.setDefaultHighlight()
- // w.setDefaultWidgetColor()
+ n.setDefaultHighlight()
+ n.setDefaultWidgetColor()
- for _, child := range w.children {
+ for _, child := range n.children {
child.redoColor(draw)
}
}
diff --git a/toolkit/gocui/common.go b/toolkit/gocui/common.go
index 325a556..05de64b 100644
--- a/toolkit/gocui/common.go
+++ b/toolkit/gocui/common.go
@@ -3,118 +3,182 @@ package main
import (
"strconv"
"git.wit.org/wit/gui/toolkit"
-// "github.com/awesome-gocui/gocui"
)
-func makeWidget(a *toolkit.Action) *cuiWidget {
+func makeWidget(n *node) *cuiWidget {
var w *cuiWidget
w = new(cuiWidget)
+ // Set(w, "default")
- w.name = a.Name
- w.text = a.Text
- w.b = a.B
- w.i = a.I
- w.s = a.S
-
- w.X = a.X
- w.Y = a.Y
-
- t := len(w.text)
- w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.PadW
- w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.PadH
-
- w.realWidth = w.gocuiSize.Width()
- w.realHeight = w.gocuiSize.Height()
-
- // set the gocui view.Frame = true by default
w.frame = true
- if (w.frame) {
- w.realHeight += me.FramePadH
- w.gocuiSize.height += me.FramePadH
- }
- w.widgetType = a.WidgetType
- w.id = a.WidgetId
// set the name used by gocui to the id
- w.cuiName = strconv.Itoa(w.id)
+ w.cuiName = strconv.Itoa(n.WidgetId)
- if w.widgetType == toolkit.Root {
- log(logInfo, "setupWidget() FOUND ROOT w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
- w.id = 0
- me.rootNode = w
+ if n.WidgetType == toolkit.Root {
+ log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
+ n.WidgetId = 0
+ me.rootNode = n
return w
}
- w.parent = findWidget(a.ParentId, me.rootNode)
- log(logInfo, "setupWidget() w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
- if (w.parent == nil) {
- log(logError, "setupWidget() ERROR: PARENT = NIL w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
- // just use the rootNode (hopefully it's not nil)
- w.parent = me.rootNode
- // return w
- }
-
- // add this widget as a child for the parent
- w.parent.Append(w)
-
- if (a.WidgetType == toolkit.Box) {
- if (a.B) {
- w.horizontal = true
+ if (n.WidgetType == toolkit.Box) {
+ if (n.B) {
+ n.horizontal = true
} else {
- w.horizontal = false
+ n.horizontal = false
}
}
- if (a.WidgetType == toolkit.Grid) {
+
+ if (n.WidgetType == toolkit.Grid) {
w.widths = make(map[int]int) // how tall each row in the grid is
w.heights = make(map[int]int) // how wide each column in the grid is
}
+
return w
}
func setupCtrlDownWidget() {
- var w *cuiWidget
- w = new(cuiWidget)
+ a := new(toolkit.Action)
+ a.Name = "ctrlDown"
+ a.WidgetType = toolkit.Dialog
+ a.WidgetId = -1
+ a.ParentId = 0
+ n := addNode(a)
- w.name = "ctrlDown"
-
- w.widgetType = toolkit.Flag
- w.id = -1
- me.ctrlDown = w
- // me.rootNode.Append(w)
+ me.ctrlDown = n
}
-func (w *cuiWidget) deleteView() {
+func (n *node) deleteView() {
+ w := n.tk
if (w.v != nil) {
- me.baseGui.DeleteView(w.cuiName)
+ w.v.Visible = false
+ return
}
+ // make sure the view isn't really there
+ me.baseGui.DeleteView(w.cuiName)
w.v = nil
}
-func (n *cuiWidget) Append(child *cuiWidget) {
- n.children = append(n.children, child)
- // child.parent = n
+// searches the binary tree for a WidgetId
+func (n *node) findWidgetId(id int) *node {
+ if (n == nil) {
+ return nil
+ }
+
+ if n.WidgetId == id {
+ return n
+ }
+
+ for _, child := range n.children {
+ newN := child.findWidgetId(id)
+ if (newN != nil) {
+ return newN
+ }
+ }
+ return nil
}
-// find widget by number
-func findWidget(i int, w *cuiWidget) (*cuiWidget) {
- if (w == nil) {
- log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against w.id = nil")
+// searches the binary tree for a WidgetId
+func (n *node) findWidgetName(name string) *node {
+ if (n == nil) {
return nil
}
- log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against w.id =", w.id)
- if (w.id == i) {
- log(logInfo, "findWidget() FOUND w.id ==", i, w.widgetType, w.name)
- return w
+ if n.tk.cuiName == name {
+ return n
}
- for _, child := range w.children {
- newW := findWidget(i, child)
- log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against child.id =", child.id)
- if (newW != nil) {
- return newW
+ for _, child := range n.children {
+ newN := child.findWidgetName(name)
+ if (newN != nil) {
+ return newN
}
}
return nil
}
+func addNode(a *toolkit.Action) *node {
+ n := new(node)
+ n.WidgetType = a.WidgetType
+ n.WidgetId = a.WidgetId
+ n.ParentId = a.ParentId
+
+ // copy the data from the action message
+ n.Name = a.Name
+ n.Text = a.Text
+ n.I = a.I
+ n.S = a.S
+ n.B = a.B
+
+ n.X = a.X
+ n.Y = a.Y
+
+ n.W = a.W
+ n.H = a.H
+ n.AtW = a.AtW
+ n.AtH = a.AtH
+
+ // store the internal toolkit information
+ n.tk = makeWidget(n)
+
+ if (a.WidgetType == toolkit.Root) {
+ log(logInfo, "addNode() Root")
+ return n
+ }
+
+ if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
+ log(logError, "addNode() WidgetId already exists", a.WidgetId)
+ return me.rootNode.findWidgetId(a.WidgetId)
+ }
+
+ // add this new widget on the binary tree
+ n.parent = me.rootNode.findWidgetId(a.ParentId)
+ if n.parent != nil {
+ n.parent.children = append(n.parent.children, n)
+ //w := n.tk
+ //w.parent = n.parent.tk
+ //w.parent.children = append(w.parent.children, w)
+ }
+ return n
+}
+
+func (n *node) IsCurrent() bool {
+ w := n.tk
+ if (n.WidgetType == toolkit.Tab) {
+ return w.isCurrent
+ }
+ if (n.WidgetType == toolkit.Window) {
+ return w.isCurrent
+ }
+ if (n.WidgetType == toolkit.Root) {
+ return false
+ }
+ return n.parent.IsCurrent()
+}
+
+func (n *node) Visible() bool {
+ if (n == nil) {
+ return false
+ }
+ if (n.tk == nil) {
+ return false
+ }
+ if (n.tk.v == nil) {
+ return false
+ }
+ return n.tk.v.Visible
+}
+
+func (n *node) SetVisible(b bool) {
+ if (n == nil) {
+ return
+ }
+ if (n.tk == nil) {
+ return
+ }
+ if (n.tk.v == nil) {
+ return
+ }
+ n.tk.v.Visible = b
+}
diff --git a/toolkit/gocui/debug.go b/toolkit/gocui/debug.go
index e3f3586..3ea31b0 100644
--- a/toolkit/gocui/debug.go
+++ b/toolkit/gocui/debug.go
@@ -2,37 +2,72 @@ package main
import (
"fmt"
+ "git.wit.org/wit/gui/toolkit"
)
-func (w *cuiWidget) dumpTree(draw bool) {
+func (n *node) dumpTree(draw bool) {
+ w := n.tk
if (w == nil) {
return
}
- w.showWidgetPlacement(logNow, "Tree:")
+ n.showWidgetPlacement(logNow, "Tree:")
- for _, child := range w.children {
+ for _, child := range n.children {
child.dumpTree(draw)
}
}
-func (w *cuiWidget) showWidgetPlacement(b bool, s string) {
- var s1 string
- var pId int
- if (w == nil) {
+func (n *node) showWidgetPlacement(b bool, s string) {
+ if (n == nil) {
log(logError, "WTF w == nil")
return
}
- if (w.parent == nil) {
- log(logVerbose, "showWidgetPlacement() parent == nil", w.id, w.cuiName)
+ w := n.tk
+
+ var s1 string
+ var pId int
+ if (n.parent == nil) {
+ log(logVerbose, "showWidgetPlacement() parent == nil", n.WidgetId, w.cuiName)
pId = 0
} else {
- pId = w.parent.id
+ pId = n.parent.WidgetId
+ }
+ s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", n.WidgetId, pId)
+ s1 += fmt.Sprintf("size=(%2d,%2d)(%2d,%2d,%2d,%2d)",
+ w.size.Width(), w.size.Height(),
+ w.size.w0, w.size.h0, w.size.w1, w.size.h1)
+ if n.Visible() {
+ s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
+ w.gocuiSize.Width(), w.gocuiSize.Height(),
+ w.gocuiSize.w0, w.gocuiSize.h0, w.gocuiSize.w1, w.gocuiSize.h1)
+ }
+ if (n.parent != nil) {
+ if (n.parent.WidgetType == toolkit.Grid) {
+ s1 += fmt.Sprintf("At(%2d,%2d) ", n.AtW, n.AtH)
+ }
+ }
+ log(b, s1, s, n.WidgetType, ",", n.Name) // , "text=", w.text)
+}
+
+func (n *node) dumpWidget(pad string) {
+ log(true, "node:", pad, n.WidgetId, "At(", n.AtW, n.AtH, ") ,", n.WidgetType, ",", n.Name)
+}
+
+func (n *node) listWidgets() {
+ if (n == nil) {
+ return
+ }
+
+ var pad string
+ for i := 0; i < me.depth; i++ {
+ pad = pad + " "
+ }
+ n.dumpWidget(pad)
+
+ for _, child := range n.children {
+ me.depth += 1
+ child.listWidgets()
+ me.depth -= 1
}
- s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", w.id, pId)
- s1 += fmt.Sprintf("s/n (%2d,%2d) (%2d,%2d) ", w.startW, w.startH, w.nextW, w.nextH)
- s1 += fmt.Sprintf("size (%2d,%2d) ", w.realWidth, w.realHeight)
- s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
- w.gocuiSize.Width(), w.gocuiSize.Height(),
- w.gocuiSize.w0, w.gocuiSize.h0, w.gocuiSize.w1, w.gocuiSize.h1)
- log(b, s1, s, w.widgetType, ",", w.name) // , "text=", w.text)
+ return
}
diff --git a/toolkit/gocui/globalDown.go b/toolkit/gocui/globalDown.go
deleted file mode 100644
index e9d6b13..0000000
--- a/toolkit/gocui/globalDown.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright 2014 The gocui Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package main
-
-import (
- "errors"
- "fmt"
-
- "github.com/awesome-gocui/gocui"
-)
-
-func globalDown(g *gocui.Gui, v *gocui.View) error {
- mx, my := g.MousePosition()
- if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil {
- if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 {
- return msgDown(g, v)
- }
- }
- globalMouseDown = true
- maxX, _ := g.Size()
- msg := fmt.Sprintf("Mouse really down at: %d,%d", mx, my) + "foo\n" + "bar\n"
- x := mx - len(msg)/2
- if x < 0 {
- x = 0
- } else if x+len(msg)+1 > maxX-1 {
- x = maxX - 1 - len(msg) - 1
- }
- if v, err := g.SetView("globalDown", x, my-1, x+len(msg)+1, my+1, 0); err != nil {
- if !errors.Is(err, gocui.ErrUnknownView) {
- return err
- }
- v.WriteString(msg)
- }
- return nil
-}
diff --git a/toolkit/gocui/gocui.go b/toolkit/gocui/gocui.go
new file mode 100644
index 0000000..85e6ea5
--- /dev/null
+++ b/toolkit/gocui/gocui.go
@@ -0,0 +1,100 @@
+// Copyright 2014 The gocui Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "errors"
+ "github.com/awesome-gocui/gocui"
+)
+
+// This initializes the gocui package
+// it runs SetManagerFunc which passes every input
+// event (keyboard, mouse, etc) to the function "gocuiEvent()"
+func gocuiMain() {
+ g, err := gocui.NewGui(gocui.OutputNormal, true)
+ if err != nil {
+ panic(err)
+ }
+ defer g.Close()
+
+ me.baseGui = g
+
+ g.Cursor = true
+ g.Mouse = true
+
+ // this sets the function that is run on every event. For example:
+ // When you click the mouse, move the mouse, or press a key on the keyboard
+ // This is equivalent to xev or similar to cat /dev/input on linux
+ g.SetManagerFunc(gocuiEvent)
+
+ if err := defaultKeybindings(g); err != nil {
+ panic(err)
+ }
+
+ if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
+ panic(err)
+ }
+}
+
+// Thanks to the gocui developers -- your package kicks ass
+// This function is called on every event. It is a callback function from the gocui package
+// which has an excellent implementation. While gocui handles things like text highlighting
+// and the layout of the text areas -- also things like handling SIGWINCH and lots of really
+// complicated console handling, it sends events here in a clean way.
+// This is equivalent to the linux command xev (apt install x11-utils)
+func gocuiEvent(g *gocui.Gui) error {
+ maxX, maxY := g.Size()
+ mx, my := g.MousePosition()
+ log(logVerbose, "handleEvent() START", maxX, maxY, mx, my, msgMouseDown)
+ if _, err := g.View("msg"); msgMouseDown && err == nil {
+ moveMsg(g)
+ }
+ if widgetView, _ := g.View("msg"); widgetView == nil {
+ log(logNow, "handleEvent() create output widget now", maxX, maxY, mx, my)
+ makeOutputWidget(g, "this is a create before a mouse click")
+ if (me.logStdout != nil) {
+ // setOutput(me.logStdout)
+ }
+ } else {
+ log(logInfo, "output widget already exists", maxX, maxY, mx, my)
+ }
+ mouseMove(g)
+ log(logVerbose, "handleEvent() END ", maxX, maxY, mx, my, msgMouseDown)
+ return nil
+}
+
+func dragOutputWindow() {
+}
+
+// turns off the frame on the global window
+func setFrame(b bool) {
+ // TODO: figure out what this might be useful for
+ // what is this do? I made it just 2 lines for now. Is this useful for something?
+ v := SetView("global", 15, 5, 80, 8, 10)
+ if (v == nil) {
+ log(logError, "setFrame() global failed")
+ }
+ v.Frame = b
+}
+
+func quit(g *gocui.Gui, v *gocui.View) error {
+ return gocui.ErrQuit
+}
+
+func SetView(name string, x0, y0, x1, y1 int, overlaps byte) *gocui.View {
+ if (me.baseGui == nil) {
+ log(logError, "SetView() ERROR: me.baseGui == nil")
+ return nil
+ }
+
+ v, err := me.baseGui.SetView(name, x0, y0, x1, y1, overlaps)
+ if err != nil {
+ if !errors.Is(err, gocui.ErrUnknownView) {
+ log(logError, "SetView() global failed on name =", name)
+ }
+ return nil
+ }
+ return v
+}
diff --git a/toolkit/gocui/help.go b/toolkit/gocui/help.go
index 74143a2..66719bb 100644
--- a/toolkit/gocui/help.go
+++ b/toolkit/gocui/help.go
@@ -12,25 +12,23 @@ import (
"github.com/awesome-gocui/gocui"
)
-func addHelp() {
- me.baseGui.SetManagerFunc(helplayout)
-}
-
var helpText []string = []string{"KEYBINDINGS",
"",
"d: show/hide debugging",
- "h: hide widgets",
- "s: show all widgets",
+ "s/h: show/hide all widgets",
+ "L: list all widgets",
"q: quit()",
"p: panic()",
"o: show Stdout",
"l: log to /tmp/witgui.log",
- "Ctrl-D: Enable Debugging",
+ "Ctrl-D: Toggle Debugging",
+ "Ctrl-V: Toggle Verbose Debugging",
"Ctrl-C: Exit",
"",
}
-func helplayout(g *gocui.Gui) error {
+func helplayout() error {
+ g := me.baseGui
var err error
maxX, _ := g.Size()
diff --git a/toolkit/gocui/keybindings.go b/toolkit/gocui/keybindings.go
index cf948fe..dbe1fe2 100644
--- a/toolkit/gocui/keybindings.go
+++ b/toolkit/gocui/keybindings.go
@@ -5,6 +5,7 @@
package main
import (
+ "os"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
@@ -21,7 +22,7 @@ func defaultKeybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
return err
}
- if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
+ if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown); err != nil {
@@ -47,7 +48,7 @@ func addDebugKeys(g *gocui.Gui) {
func(g *gocui.Gui, v *gocui.View) error {
log(logNow, "gocui.SetKeyBinding() dumpTree() START")
// me.rootNode.dumpTree(true)
- fakeStartWidth = me.DevelOffsetW
+ fakeStartWidth = me.FakeW
fakeStartHeight = me.TabH + me.FramePadH
if (showDebug) {
me.rootNode.showFake()
@@ -59,6 +60,12 @@ func addDebugKeys(g *gocui.Gui) {
return nil
})
+ // display the help menu
+ g.SetKeybinding("", '?', gocui.ModNone,
+ func(g *gocui.Gui, v *gocui.View) error {
+ helplayout()
+ return nil
+ })
// hide all widgets
g.SetKeybinding("", 'h', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
@@ -73,6 +80,26 @@ func addDebugKeys(g *gocui.Gui) {
return nil
})
+ // list all widgets
+ g.SetKeybinding("", 'L', gocui.ModNone,
+ func(g *gocui.Gui, v *gocui.View) error {
+ me.rootNode.listWidgets()
+ return nil
+ })
+
+ // log to output window
+ g.SetKeybinding("", 'o', gocui.ModNone,
+ func(g *gocui.Gui, v *gocui.View) error {
+ if me.logStdout.Visible() {
+ me.logStdout.SetVisible(false)
+ setOutput(os.Stdout)
+ } else {
+ me.logStdout.SetVisible(true)
+ setOutput(me.logStdout.tk)
+ }
+ return nil
+ })
+
// exit
g.SetKeybinding("", 'q', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
@@ -86,9 +113,28 @@ func addDebugKeys(g *gocui.Gui) {
})
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
- var a toolkit.Action
- a.ActionType = toolkit.EnableDebug
- me.callback <- a
+ if (showDebug) {
+ var a toolkit.Action
+ a.B = true
+ a.ActionType = toolkit.EnableDebug
+ me.callback <- a
+ logInfo = true
+ logVerbose = true
+ } else {
+ logInfo = false
+ logVerbose = false
+ }
+ return nil
+ })
+ g.SetKeybinding("", gocui.KeyCtrlV, gocui.ModNone,
+ func(g *gocui.Gui, v *gocui.View) error {
+ if (logVerbose) {
+ logInfo = false
+ logVerbose = false
+ } else {
+ logInfo = true
+ logVerbose = true
+ }
return nil
})
diff --git a/toolkit/gocui/main.go b/toolkit/gocui/main.go
index 20e85ac..6214fcb 100644
--- a/toolkit/gocui/main.go
+++ b/toolkit/gocui/main.go
@@ -96,7 +96,7 @@ func main() {
ferr, _ := os.OpenFile("/tmp/witgui.err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
os.Stderr = ferr
- MouseMain()
+ gocuiMain()
log(true, "MouseMain() closed")
standardExit()
diff --git a/toolkit/gocui/mouse.go b/toolkit/gocui/mouse.go
index 2cba5c6..dbe2c6d 100644
--- a/toolkit/gocui/mouse.go
+++ b/toolkit/gocui/mouse.go
@@ -6,68 +6,13 @@ package main
import (
"errors"
-
+ "fmt"
"github.com/awesome-gocui/gocui"
)
-func MouseMain() {
- g, err := gocui.NewGui(gocui.OutputNormal, true)
- if err != nil {
- panic(err)
- }
- defer g.Close()
-
- me.baseGui = g
-
- g.Cursor = true
- g.Mouse = true
-
- g.SetManagerFunc(layout)
-
- if err := defaultKeybindings(g); err != nil {
- panic(err)
- }
-
- if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
- panic(err)
- }
-}
-
-func layout(g *gocui.Gui) error {
- maxX, maxY := g.Size()
- mx, my := g.MousePosition()
- if _, err := g.View("msg"); msgMouseDown && err == nil {
- moveMsg(g)
- }
- // TODO: figure out what this might be useful for
- // what is this do? I made it just 2 lines for now. Is this useful for something?
- if v, err := g.SetView("global", 15, 5, maxX, 8, 10); err != nil {
- if !errors.Is(err, gocui.ErrUnknownView) {
- log("global failed", maxX, maxY)
- return err
- }
- v.Frame = false
- }
- helplayout(g)
- if widgetView, _ := g.View("msg"); widgetView == nil {
- log(logInfo, "create output widget now", maxX, maxY, mx, my)
- makeOutputWidget(g, "this is a create before a mouse click")
- if (me.logStdout != nil) {
- setOutput(me.logStdout)
- }
- } else {
- log(logInfo, "output widget already exists", maxX, maxY, mx, my)
- }
- updateHighlightedView(g)
- log(logInfo, "layout() END", maxX, maxY, mx, my)
- return nil
-}
-
-func quit(g *gocui.Gui, v *gocui.View) error {
- return gocui.ErrQuit
-}
-
-func updateHighlightedView(g *gocui.Gui) {
+// this function uses the mouse position to highlight & unhighlight things
+// this is run every time the user moves the mouse over the terminal window
+func mouseMove(g *gocui.Gui) {
mx, my := g.MousePosition()
for _, view := range g.Views() {
view.Highlight = false
@@ -102,3 +47,28 @@ func mouseUp(g *gocui.Gui, v *gocui.View) error {
}
return nil
}
+
+func mouseDown(g *gocui.Gui, v *gocui.View) error {
+ mx, my := g.MousePosition()
+ if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil {
+ if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 {
+ return msgDown(g, v)
+ }
+ }
+ globalMouseDown = true
+ maxX, _ := g.Size()
+ msg := fmt.Sprintf("Mouse really down at: %d,%d", mx, my) + "foo\n" + "bar\n"
+ x := mx - len(msg)/2
+ if x < 0 {
+ x = 0
+ } else if x+len(msg)+1 > maxX-1 {
+ x = maxX - 1 - len(msg) - 1
+ }
+ if v, err := g.SetView("globalDown", x, my-1, x+len(msg)+1, my+1, 0); err != nil {
+ if !errors.Is(err, gocui.ErrUnknownView) {
+ return err
+ }
+ v.WriteString(msg)
+ }
+ return nil
+}
diff --git a/toolkit/gocui/place.go b/toolkit/gocui/place.go
index 0919308..d02624e 100644
--- a/toolkit/gocui/place.go
+++ b/toolkit/gocui/place.go
@@ -1,263 +1,196 @@
package main
import (
- "fmt"
-// "github.com/awesome-gocui/gocui"
+ "strings"
"git.wit.org/wit/gui/toolkit"
)
-func (w *cuiWidget) placeBox() {
- if (w.widgetType != toolkit.Box) {
+func (n *node) placeBox(startW int, startH int) {
+ if (n.WidgetType != toolkit.Box) {
return
}
- w.startW = w.parent.nextW
- w.startH = w.parent.nextH
- w.nextW = w.parent.nextW
- w.nextH = w.parent.nextH
- w.realWidth = 0
- w.realHeight = 0
+ n.tk.size.w0 = startW
+ n.tk.size.h0 = startH
+ n.showWidgetPlacement(logNow, "boxS()")
- var maxW int
- var maxH int
- for _, child := range w.children {
- w.showWidgetPlacement(logNow, "boxS()")
- child.placeWidgets()
- if (w.horizontal) {
- log(logVerbose, "BOX IS HORIZONTAL")
+ newW := startW
+ newH := startH
+ for _, child := range n.children {
+ child.placeWidgets(newW, newH)
+ // n.showWidgetPlacement(logNow, "boxS()")
+ // w,h := child.logicalSize()
+ newR := child.realGocuiSize()
+ w := newR.w1 - newR.w0
+ h := newR.h1 - newR.h0
+ if (n.horizontal) {
+ log(logNow, "BOX IS HORIZONTAL", n.Name, "newWH()", newW, newH, "child()", w, h, child.Name)
// expand based on the child width
- w.nextW += child.realWidth
- w.realWidth += child.realWidth
+ newW += w
} else {
- log(logVerbose, "BOX IS VERTICAL")
+ log(logNow, "BOX IS VERTICAL ", n.Name, "newWH()", newW, newH, "child()", w, h, child.Name)
// expand based on the child height
- w.nextH += child.realHeight
- w.realHeight += child.realHeight
+ newH += h
}
- if (maxW < child.realWidth) {
- maxW = child.realWidth
- }
- if (maxH < child.realHeight) {
- maxH = child.realHeight
- }
- }
- if (w.horizontal) {
- w.realHeight = maxH
- } else {
- w.realWidth = maxW
}
- w.showWidgetPlacement(logNow, "boxE()")
+ // w,h := n.logicalSize()
+ newR := n.realGocuiSize()
+ w := newR.w1 - newR.w0
+ h := newR.h1 - newR.h0
+
+ n.tk.size.w1 = n.tk.size.w0 + w
+ n.tk.size.h1 = n.tk.size.h0 + h
+ n.showWidgetPlacement(logNow, "boxE()")
}
-func (w *cuiWidget) placeWidgets() {
- if (w == nil) {
+func (n *node) placeWidgets(startW int, startH int) {
+ if (n == nil) {
return
}
if (me.rootNode == nil) {
return
}
- p := w.parent
- if (p == nil) {
- log(logInfo, "place()", w.id, "parent == nil")
- return
- }
- switch w.widgetType {
+ switch n.WidgetType {
case toolkit.Window:
- for _, child := range w.children {
- w.startW = me.RawW
- w.startH = me.RawH
- w.nextW = me.RawW
- w.nextH = me.RawH
- w.showWidgetPlacement(logNow, "place()")
- child.placeWidgets()
- if (w.realWidth < child.realWidth) {
- w.realWidth = child.realWidth
- }
- if (w.realHeight < child.realHeight) {
- w.realHeight = child.realHeight
- }
- w.showWidgetPlacement(logNow, "place()")
+ for _, child := range n.children {
+ child.placeWidgets(me.RawW, me.RawH)
+ return
}
case toolkit.Tab:
- for _, child := range w.children {
- w.startW = me.RawW
- w.startH = me.RawH
- w.nextW = me.RawW
- w.nextH = me.RawH
- w.showWidgetPlacement(logNow, "place()")
- child.placeWidgets()
- if (w.realWidth < child.realWidth) {
- w.realWidth = child.realWidth
- }
- if (w.realHeight < child.realHeight) {
- w.realHeight = child.realHeight
- }
- w.showWidgetPlacement(logNow, "place()")
+ for _, child := range n.children {
+ child.placeWidgets(me.RawW, me.RawH)
+ return
}
case toolkit.Grid:
- w.showWidgetPlacement(logNow, "placeGrid() START")
- w.placeGrid()
- w.showWidgetPlacement(logNow, "placeGrid() END")
+ n.placeGrid(startW, startH)
case toolkit.Box:
- w.showWidgetPlacement(logNow, "placeBox() START")
- w.placeBox()
- w.showWidgetPlacement(logNow, "placeBox() END")
+ n.placeBox(startW, startH)
case toolkit.Group:
// move the group to the parent's next location
- w.startW = p.nextW
- w.startH = p.nextH
- w.nextW = p.nextW
- w.nextH = p.nextH
- w.moveTo(p.nextW, p.nextH)
-
- // initialize the real width to just the group gocui view
- w.realWidth = w.gocuiSize.Width() + me.FramePadW
- w.realHeight = w.gocuiSize.Height() + me.FramePadH
+ n.gocuiSetWH(startW, startH)
+ n.showWidgetPlacement(logNow, "group()")
- // indent the widgets for a group
- w.nextW = p.nextW + me.GroupPadW
- w.nextH = p.nextH + w.realHeight
- w.showWidgetPlacement(logNow, "place()")
-
- // mow move all the children aka: run place() on them
- var maxW int
- for _, child := range w.children {
- child.showWidgetPlacement(logNow, "place()")
- child.placeWidgets()
- child.showWidgetPlacement(logNow, "place()")
+ newW := startW + me.GroupPadW
+ newH := startH + 3 // normal hight of the group label
+ // now move all the children aka: run place() on them
+ for _, child := range n.children {
+ child.placeWidgets(newW, newH)
+ // _,h := child.logicalSize()
+ newR := child.realGocuiSize()
+ // w := newR.w1 - newR.w0
+ h := newR.h1 - newR.h0
// increment straight down
- w.nextH += child.realHeight
- w.realHeight += child.realHeight
-
- // track largest width
- if (maxW < child.realWidth) {
- maxW = child.realWidth
- }
-
+ newH += h
}
- // add real width of largest child
- w.realWidth += maxW
- w.showWidgetPlacement(logNow, "place()")
default:
- w.startW = p.nextW
- w.startH = p.nextH
- w.nextW = p.nextW
- w.nextH = p.nextH
- newW := w.gocuiSize.Width()
- newH := w.gocuiSize.Height()
- w.gocuiSize.w0 = w.startW
- w.gocuiSize.h0 = w.startH
- w.gocuiSize.w1 = w.gocuiSize.w0 + newW
- w.gocuiSize.h1 = w.gocuiSize.h0 + newH
-
- // the realSize should not be smaller than the gocui view (?)
- // this might not be a needed check? Maybe there are legit exceptions?
- if (w.realWidth < newW) {
- w.realWidth = newW
- }
- if (w.realHeight < newH) {
- w.realHeight = newH
- }
- w.showWidgetPlacement(logNow, "place()")
+ n.gocuiSetWH(startW, startH)
+ // n.moveTo(startW, startH)
}
}
-/*
-func (w *cuiWidget) setWH() {
- w.gocuiSize.w1 = w.gocuiSize.w0 + w.gocuiSize.width
- w.gocuiSize.h1 = w.gocuiSize.h0 + w.gocuiSize.height
-}
-*/
-
-func (w *cuiWidget) moveTo(leftW int, topH int) {
- if (w.isFake) {
+func (n *node) placeGrid(startW int, startH int) {
+ w := n.tk
+ w.size.w0 = startW
+ w.size.h0 = startH
+ n.showWidgetPlacement(logInfo, "grid0:")
+ if (n.WidgetType != toolkit.Grid) {
return
}
- newW := w.gocuiSize.Width()
- newH := w.gocuiSize.Height()
- w.gocuiSize.w0 = leftW
- w.gocuiSize.h0 = topH
- w.gocuiSize.w1 = w.gocuiSize.w0 + newW
- w.gocuiSize.h1 = w.gocuiSize.h0 + newH
- w.showWidgetPlacement(logInfo, "moveTo()")
-}
-func (w *cuiWidget) placeGrid() {
- w.showWidgetPlacement(logNow, "grid0:")
- if (w.widgetType != toolkit.Grid) {
- return
- }
- w.startW = w.parent.nextW
- w.startH = w.parent.nextH
- w.nextW = w.parent.nextW
- w.nextH = w.parent.nextH
-
- var wCount int = 0
- var hCount int = 0
- for _, child := range w.children {
- // increment for the next child
- w.nextW = w.startW + wCount * 20
- w.nextH = w.startH + hCount * 2
+ // first compute the max sizes of the rows and columns
+ for _, child := range n.children {
+ // childW, childH := child.logicalSize()
+ newR := child.realGocuiSize()
+ childW := newR.w1 - newR.w0
+ childH := newR.h1 - newR.h0
// set the child's realWidth, and grid offset
- child.parentH = hCount
- child.parentW = wCount
- if (w.widths[wCount] < child.realWidth) {
- w.widths[wCount] = child.realWidth
- }
- if (w.heights[hCount] < child.realHeight) {
- w.heights[hCount] = child.realHeight
+ if (w.widths[child.AtW] < childW) {
+ w.widths[child.AtW] = childW
}
- log(logVerbose, "grid1: (w,h count)", wCount, hCount, "(X,Y)", w.X, w.Y, w.name)
- child.showWidgetPlacement(logNow, "grid1: " + fmt.Sprintf("next()=(%2d,%2d)", w.nextW, w.nextH))
-
- if ((wCount + 1) < w.X) {
- wCount += 1
- } else {
- wCount = 0
- hCount += 1
+ if (w.heights[child.AtH] < childH) {
+ w.heights[child.AtH] = childH
}
+ // child.showWidgetPlacement(logInfo, "grid: ")
+ log(logVerbose, "placeGrid:", child.Name, "child()", childW, childH, "At()", child.AtW, child.AtH)
}
- // reset the size of the whole grid
- w.realWidth = 0
- w.realHeight = 0
- for _, val := range w.widths {
- w.realWidth += val
- }
- for _, val := range w.heights {
- w.realHeight += val
- }
+ // find the width and height offset of the grid for AtW,AtH
+ for _, child := range n.children {
+ child.showWidgetPlacement(logInfo, "grid1:")
- for _, child := range w.children {
- child.showWidgetPlacement(logVerbose, "grid2:")
var totalW, totalH int
- for i, val := range w.widths {
- if (i < child.parentW) {
- log(logVerbose, "grid2: (w, widths[])", i, val)
- totalW += w.widths[i]
+ for i, w := range w.widths {
+ if (i < child.AtW) {
+ totalW += w
}
}
for i, h := range w.heights {
- if (i < child.parentH) {
+ if (i < child.AtH) {
totalH += h
}
}
// the new corner to move the child to
- w.nextW = w.startW + totalW
- w.nextH = w.startH + totalH
+ newW := startW + totalW
+ newH := startH + totalH
- child.placeWidgets()
+ log(logVerbose, "placeGrid:", child.Name, "new()", newW, newH, "At()", child.AtW, child.AtH)
+ child.placeWidgets(newW, newH)
child.showWidgetPlacement(logInfo, "grid2:")
- log(logInfo)
}
- // w.updateLogicalSizes()
- w.showWidgetPlacement(logNow, "grid3:")
+ n.showWidgetPlacement(logInfo, "grid3:")
}
-/*
-func (w *cuiWidget) setRealSize() {
+// computes the real, actual size of all the gocli objects in a widget
+func (n *node) realGocuiSize() *rectType {
+ var f func (n *node, 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(n *node, r *rectType) {
+ newR := n.tk.gocuiSize
+ if ! n.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 n.children {
+ f(child, r)
+ }
+ }
+ f(n, newR)
+ return newR
+}
+
+func (n *node) textSize() (int, int) {
+ var width, height int
+
+ for _, s := range strings.Split(n.Text, "\n") {
+ if (width < len(s)) {
+ width = len(s)
+ }
+ height += 1
+ }
+ return width, height
}
-*/
diff --git a/toolkit/gocui/plugin.go b/toolkit/gocui/plugin.go
index 27d96b9..6d597b4 100644
--- a/toolkit/gocui/plugin.go
+++ b/toolkit/gocui/plugin.go
@@ -8,12 +8,17 @@ import (
func action(a *toolkit.Action) {
log(logInfo, "action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
- w := findWidget(a.WidgetId, me.rootNode)
+ n := me.rootNode.findWidgetId(a.WidgetId)
+ var w *cuiWidget
+ if (n != nil) {
+ w = n.tk
+ }
switch a.ActionType {
case toolkit.Add:
if (w == nil) {
- w = makeWidget(a)
- w.addWidget()
+ n := addNode(a)
+ // w = n.tk
+ n.addWidget()
} else {
// this is done to protect the plugin being 'refreshed' with the
// widget binary tree. TODO: find a way to keep them in sync
@@ -22,16 +27,25 @@ func action(a *toolkit.Action) {
}
case toolkit.Show:
if (a.B) {
- w.showView()
+ n.showView()
} else {
- w.hideWidgets()
+ n.hideWidgets()
}
case toolkit.Set:
- w.Set(a.A)
+ if a.WidgetType == toolkit.Flag {
+ log(logNow, "TODO: set flag here", a.ActionType, a.WidgetType, a.Name)
+ log(logNow, "TODO: n.WidgetType =", n.WidgetType, "n.Name =", a.Name)
+ } else {
+ if (a.A == nil) {
+ log(logError, "TODO: Set here. a == nil", a.ActionType, "WidgetType =", a.WidgetType, "Name =", a.Name)
+ } else {
+ n.Set(a.A)
+ }
+ }
case toolkit.SetText:
- w.SetText(a.S)
+ n.SetText(a.S)
case toolkit.AddText:
- w.AddText(a.S)
+ n.AddText(a.S)
case toolkit.Move:
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
case toolkit.CloseToolkit:
@@ -43,42 +57,61 @@ func action(a *toolkit.Action) {
log(logInfo, "action() END")
}
-func (w *cuiWidget) AddText(text string) {
- if (w == nil) {
+func (n *node) AddText(text string) {
+ if (n == nil) {
log(logNow, "widget is nil")
return
}
- w.vals = append(w.vals, text)
- for i, s := range w.vals {
- log(logNow, "AddText()", w.name, i, s)
+ n.vals = append(n.vals, text)
+ for i, s := range n.vals {
+ log(logNow, "AddText()", n.Name, i, s)
}
- w.SetText(text)
+ n.SetText(text)
}
-func (w *cuiWidget) SetText(text string) {
- if (w == nil) {
+func (n *node) SetText(text string) {
+ if (n == nil) {
log(logNow, "widget is nil")
return
}
- w.text = text
- w.s = text
- w.textResize()
- w.deleteView()
- w.showView()
+ n.S = text
+ n.Text = text
+
+ n.textResize()
+ n.deleteView()
+ n.showView()
}
-func (w *cuiWidget) Set(val any) {
+func (n *node) Set(val any) {
+ // w := n.tk
log(logInfo, "Set() value =", val)
switch v := val.(type) {
case bool:
- w.b = val.(bool)
- w.setCheckbox(val.(bool))
+ n.B = val.(bool)
+ n.setCheckbox(val.(bool))
case string:
- w.SetText(val.(string))
+ n.SetText(val.(string))
case int:
- w.i = val.(int)
+ n.I = val.(int)
default:
log(logError, "Set() unknown type =", val, v)
}
}
+
+// this passes the user event back from the plugin
+func (n *node) doUserEvent() {
+ if (me.callback == nil) {
+ log(logError, "doUserEvent() no callback channel was configured")
+ return
+ }
+ var a toolkit.Action
+ a.WidgetId = n.WidgetId
+ a.Name = n.Name
+ a.Text = n.Text
+ a.B = n.B
+ a.ActionType = toolkit.User
+ log(logInfo, "doUserEvent() START: send a button click callback()", a.WidgetId, a.Name)
+ me.callback <- a
+ log(logInfo, "doUserEvent() END: sent a button click callback()", a.WidgetId, a.Name)
+}
diff --git a/toolkit/gocui/showStdout.go b/toolkit/gocui/showStdout.go
index 32fb9f3..22e95d3 100644
--- a/toolkit/gocui/showStdout.go
+++ b/toolkit/gocui/showStdout.go
@@ -52,14 +52,12 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
a.WidgetType = toolkit.Stdout
a.WidgetId = -3
a.ParentId = 0
- me.logStdout = makeWidget(a)
- me.logStdout.gocuiSize.w0 = maxX - 32
- me.logStdout.gocuiSize.h0 = maxY/2
- me.logStdout.gocuiSize.w1 = me.logStdout.gocuiSize.w0 + outputW
- me.logStdout.gocuiSize.h1 = me.logStdout.gocuiSize.h0 + outputH
-
- me.logStdout.realWidth = me.logStdout.gocuiSize.Width()
- me.logStdout.realHeight = me.logStdout.gocuiSize.Height()
+ n := addNode(a)
+ me.logStdout = n
+ me.logStdout.tk.gocuiSize.w0 = maxX - 32
+ me.logStdout.tk.gocuiSize.h0 = maxY/2
+ me.logStdout.tk.gocuiSize.w1 = me.logStdout.tk.gocuiSize.w0 + outputW
+ me.logStdout.tk.gocuiSize.h1 = me.logStdout.tk.gocuiSize.h0 + outputH
}
v, err := g.View("msg")
if (v == nil) {
@@ -78,19 +76,19 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
if (err != nil) {
log("create output window failed", err)
- // return nil
+ return nil
}
if (v == nil) {
log("msg == nil. WTF now? err =", err)
return nil
} else {
- me.logStdout.v = v
+ me.logStdout.tk.v = v
}
- me.logStdout.v.Clear()
- me.logStdout.v.SelBgColor = gocui.ColorCyan
- me.logStdout.v.SelFgColor = gocui.ColorBlack
+ v.Clear()
+ v.SelBgColor = gocui.ColorCyan
+ v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n" + stringFromMouseClick)
g.SetViewOnBottom("msg")
// g.SetViewOnBottom(v.Name())
diff --git a/toolkit/gocui/structs.go b/toolkit/gocui/structs.go
index 1fa6692..06a2266 100644
--- a/toolkit/gocui/structs.go
+++ b/toolkit/gocui/structs.go
@@ -23,11 +23,12 @@ var me config
type config struct {
baseGui *gocui.Gui // the main gocui handle
- rootNode *cuiWidget // the base of the binary tree. it should have id == 0
- ctrlDown *cuiWidget // shown if you click the mouse when the ctrl key is pressed
- current *cuiWidget // this is the current tab or window to show
- logStdout *cuiWidget // where to show STDOUT
- logStdoutV *gocui.View // where to show STDOUT
+ rootNode *node // the base of the binary tree. it should have id == 0
+
+ ctrlDown *node // shown if you click the mouse when the ctrl key is pressed
+// current *cuiWidget // this is the current tab or window to show
+ logStdout *node // where to show STDOUT
+ helpLabel *gocui.View
// this is the channel we send user events like
// mouse clicks or keyboard events back to the program
@@ -36,53 +37,47 @@ type config struct {
// this is the channel we get requests to make widgets
pluginChan chan toolkit.Action
- helpLabel *gocui.View
-
- DefaultBehavior bool `default:"true"`
-
- // Buttons, Group, Tabs, Windows, etc are by default assumed to be a single line
- // as a default, we make buttons 8 chars wide
- DefaultWidth int `default:"8"`
- DefaultHeight int `default:"1"`
-
// When the widget has a frame, like a button, it adds 2 lines runes on each side
// so you need 3 char spacing in each direction to not have them overlap
// the amount of padding when there is a frame
- FramePadW int `default:"4" dense:"0"`
+ FramePadW int `default:"1" dense:"0"`
FramePadH int `default:"1" dense:"0"`
PadW int `default:"1" dense:"0"`
PadH int `default:"1" dense:"0"`
- // additional amount of space to put between window & tab widgets
- WindowPadW int `default:"8" dense:"0"`
- TabPadW int `default:"4" dense:"0"`
-
// how far down to start Window or Tab headings
WindowW int `default:"8" dense:"0"`
WindowH int `default:"-1"`
- TabW int `default:"2" dense:"0"`
+ TabW int `default:"5" dense:"0"`
TabH int `default:"1" dense:"0"`
+ // additional amount of space to put between window & tab widgets
+ WindowPadW int `default:"8" dense:"0"`
+ TabPadW int `default:"4" dense:"0"`
+
// additional amount of space to indent on a group
GroupPadW int `default:"6" dense:"2"`
// the raw beginning of each window (or tab)
- RawW int `default:"7"`
- RawH int `default:"3"`
+ RawW int `default:"1"`
+ RawH int `default:"5"`
// offset for the hidden widgets
- DevelOffsetW int `default:"20"`
+ FakeW int `default:"20"`
+ padded bool // add space between things like buttons
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
canvas bool // if set to true, the windows are a raw canvas
menubar bool // for windows
stretchy bool // expand things like buttons to the maximum size
- padded bool // add space between things like buttons
margin bool // add space around the frames of windows
// writeMutex protects locks the write process
writeMutex sync.Mutex
+
+ // used for listWidgets() debugging
+ depth int
}
// deprecate these
@@ -121,23 +116,21 @@ type node struct {
AtW int
AtH int
+ vals []string // dropdown menu items
+
+ // horizontal=true means layout widgets like books on a bookshelf
+ // horizontal=false means layout widgets like books in a stack
+ horizontal bool `default:false`
+
+ hasTabs bool // does the window have tabs?
+
// the internal plugin toolkit structure
tk *cuiWidget
}
-// the gocui way
-// the logical size of the widget
+// this is the gocui way
// corner starts at in the upper left corner
type rectType struct {
- // where the widget should calculate it's existance from
- // startW int
- // startH int
-
- // the is a shortcut to access
-// width int // this is always w1 - w0
- height int // this is always h1 - h0
-
- // this is the gocui way
w0, h0, w1, h1 int // left top right bottom
}
@@ -150,82 +143,27 @@ func (r *rectType) Height() int {
}
type cuiWidget struct {
- id int // widget ID
- // parentId int
- widgetType toolkit.WidgetType
-
- name string // a descriptive name of the widget
- text string // the current text being displayed
+ // the gocui package variables
+ v *gocui.View // this is nil if the widget is not displayed
cuiName string // what gocui uses to reference the widget
- vals []string // dropdown menu options
+ // the logical size of the widget
+ // For example, 40x12 would be the center of a normal terminal
+ size rectType
+
+ // the actual gocui display view of this widget
+ // sometimes this isn't visable like with a Box or Grid
+ gocuiSize rectType
isCurrent bool // is this the currently displayed Window or Tab?
- hasTabs bool // does the window have tabs?
isFake bool // widget types like 'box' are 'false'
- // where the widget's real corner is
- // should we always compute this?
- startW int
- startH int
-
- // where the next child should be placed
- nextW int
- nextH int
-
- // the widget size to reserve or things will overlap
- realWidth int
- realHeight int
-
- gocuiSize rectType // the display size of this widget
- // logicalSize rectType // the logical size. Includes all the child widgets
-
// used to track the size of grids
widths map[int]int // how tall each row in the grid is
heights map[int]int // how wide each column in the grid is
- // deprecate // where in the parent grid this widget should go
- parentW int
- parentH int
-
- // things from toolkit/action
- b bool
- i int
- s string
- X int
- Y int
- width int
- height int
-
- // horizontal=true means layout widgets like books on a bookshelf
- // horizontal=false means layout widgets like books in a stack
- horizontal bool `default:false`
-
tainted bool
- v *gocui.View
frame bool
-
- parent *cuiWidget
- children []*cuiWidget
-}
-
-func (w *cuiWidget) IsCurrent() bool {
- if (w.widgetType == toolkit.Tab) {
- return w.isCurrent
- }
- if (w.widgetType == toolkit.Window) {
- return w.isCurrent
- }
- if (w.widgetType == toolkit.Root) {
- return false
- }
- return w.parent.IsCurrent()
-}
-
-func (w *cuiWidget) StartW() {
-}
-
-func (w *cuiWidget) StartH() {
}
// from the gocui devs:
@@ -238,7 +176,7 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
w.tainted = true
me.writeMutex.Lock()
defer me.writeMutex.Unlock()
- if (me.logStdout.v == nil) {
+ if (me.logStdout.tk.v == nil) {
// optionally write the output to /tmp
s := fmt.Sprint(string(p))
s = strings.TrimSuffix(s, "\n")
@@ -246,11 +184,11 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
v, _ := me.baseGui.View("msg")
if (v != nil) {
// fmt.Fprintln(outf, "found msg")
- me.logStdout.v = v
+ me.logStdout.tk.v = v
}
} else {
// display the output in the gocui window
- me.logStdout.v.Clear()
+ me.logStdout.tk.v.Clear()
s := fmt.Sprint(string(p))
s = strings.TrimSuffix(s, "\n")
@@ -260,7 +198,7 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
l := len(outputS) - outputH
outputS = outputS[l:]
}
- fmt.Fprintln(me.logStdout.v, strings.Join(outputS, "\n"))
+ fmt.Fprintln(me.logStdout.tk.v, strings.Join(outputS, "\n"))
}
return len(p), nil
diff --git a/toolkit/gocui/tab.go b/toolkit/gocui/tab.go
index 8c5b11b..60ee6b3 100644
--- a/toolkit/gocui/tab.go
+++ b/toolkit/gocui/tab.go
@@ -3,136 +3,111 @@ package main
// implements widgets 'Window' and 'Tab'
import (
+ "strings"
"git.wit.org/wit/gui/toolkit"
-// "github.com/awesome-gocui/gocui"
)
-func (w *cuiWidget) hideWidgets() {
- w.isCurrent = false
- switch w.widgetType {
- case toolkit.Root:
- case toolkit.Flag:
- case toolkit.Window:
- // case toolkit.Tab:
- case toolkit.Box:
- case toolkit.Grid:
- default:
- w.deleteView()
- }
- for _, child := range w.children {
- child.hideWidgets()
+func (w *cuiWidget) Width() int {
+ if w.frame {
+ return w.gocuiSize.w1 - w.gocuiSize.w0
}
+ return w.gocuiSize.w1 - w.gocuiSize.w0 - 1
}
-func (w *cuiWidget) hideFake() {
- if (w.isFake) {
- w.deleteView()
- }
- for _, child := range w.children {
- child.hideFake()
+func (w *cuiWidget) Height() int {
+ if w.frame {
+ return w.gocuiSize.h1 - w.gocuiSize.h0
}
+ return w.gocuiSize.h1 - w.gocuiSize.h0 - 1
}
-func (w *cuiWidget) showFake() {
- if (w.isFake) {
- w.setFake()
- w.showWidgetPlacement(logNow, "showFake:")
- w.showView()
- }
- for _, child := range w.children {
- child.showFake()
+func (n *node) gocuiSetWH(sizeW, sizeH int) {
+ w := len(n.Text)
+ lines := strings.Split(n.Text, "\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
}
-}
-func (w *cuiWidget) showWidgets() {
- if (w.isFake) {
- // don't display by default
+ if tk.frame {
+ tk.size.w0 = sizeW
+ tk.size.h0 = sizeH
+ tk.gocuiSize.w0 = tk.size.w0
+ tk.gocuiSize.h0 = tk.size.h0
+ tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
+ tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
} else {
- if w.IsCurrent() {
- w.showWidgetPlacement(logInfo, "current:")
- w.showView()
- } else {
- w.showWidgetPlacement(logInfo, "not:")
- // w.drawView()
- }
- }
- for _, child := range w.children {
- child.showWidgets()
+ tk.size.w0 = sizeW - 1
+ tk.size.h0 = sizeH - 1
+ tk.gocuiSize.w0 = tk.size.w0
+ tk.gocuiSize.h0 = tk.size.h0
+ tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + 1
+ tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + 1
}
}
-func (w *cuiWidget) setWindowWH() {
- w.gocuiSize.w0 = me.rootNode.nextW
- w.gocuiSize.h0 = me.WindowH
-
- t := len(w.text)
- w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.PadW
- w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.PadH
-
- w.realWidth = w.gocuiSize.Width()
- w.realHeight = w.gocuiSize.Height()
-
- // move the rootNode width over for the next window
- me.rootNode.nextW += w.realWidth + me.WindowPadW
-
- w.nextW = 4
- w.nextH = 2
-
- w.showWidgetPlacement(logNow, "setWindowWH:")
-}
-
-func (w *cuiWidget) setTabWH() {
- // set the start and size of the tab gocui button
-
- w.gocuiSize.w0 = w.parent.nextW
- w.gocuiSize.h0 = me.TabH
-
- t := len(w.text)
- w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.PadW
- w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.PadH
-
- w.realWidth = w.gocuiSize.Width()
- w.realHeight = w.gocuiSize.Height()
-
- w.realWidth += me.FramePadW
- w.realHeight += me.FramePadH
-
- w.parent.nextW += w.realWidth + me.TabPadW
-
- w.showWidgetPlacement(logNow, "setTabWH:")
-}
-
-func (w *cuiWidget) redoTabs(draw bool) {
- if (w.widgetType == toolkit.Window) {
- var tabs bool = false
- // figure out if the window is just a bunch of tabs
- for _, child := range w.children {
- if (child.widgetType == toolkit.Tab) {
+func redoWindows(nextW int, nextH int) {
+ for _, n := range me.rootNode.children {
+ if n.WidgetType != toolkit.Window {
+ continue
+ }
+ w := n.tk
+ var tabs bool
+ for _, child := range n.children {
+ if (child.WidgetType == toolkit.Tab) {
tabs = true
}
}
if (tabs) {
// window is tabs. Don't show it as a standard button
w.frame = false
- w.hasTabs = true
+ n.hasTabs = true
} else {
- w.frame = true
- w.hasTabs = false
+ w.frame = false
+ n.hasTabs = false
}
- w.setWindowWH()
- w.deleteView()
- w.showView()
- }
- if (w.widgetType == toolkit.Tab) {
- w.setTabWH()
- w.deleteView()
- // show all the tabs for the current window
- if w.parent.isCurrent {
- w.showView()
+
+ w.size.w0 = nextW
+ w.size.h0 = nextH
+ n.gocuiSetWH(nextW, nextH)
+ n.deleteView()
+ n.showView()
+
+ sizeW := w.Width() + me.WindowPadW
+ sizeH := w.Height()
+ nextW += sizeW
+ log(logNow, "redoWindows() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, n.Name)
+
+ if n.hasTabs {
+ n.redoTabs(me.TabW, me.TabH)
}
}
+}
+
+func (p *node) redoTabs(nextW int, nextH int) {
+ for _, n := range p.children {
+ if n.WidgetType != toolkit.Tab {
+ continue
+ }
+ w := n.tk
+ w.frame = true
+
+ w.size.w0 = nextW
+ w.size.h0 = nextH
+ n.gocuiSetWH(nextW, nextH)
+ n.deleteView()
+ // setCurrentTab(n)
+ n.showView()
- for _, child := range w.children {
- child.redoTabs(draw)
+ sizeW := w.Width() + me.TabPadW
+ sizeH := w.Height()
+ log(logNow, "redoTabs() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, n.Name)
+ nextW += sizeW
}
}
diff --git a/toolkit/gocui/view.go b/toolkit/gocui/view.go
index b47c075..e2c76aa 100644
--- a/toolkit/gocui/view.go
+++ b/toolkit/gocui/view.go
@@ -20,10 +20,11 @@ func splitLines(s string) []string {
return lines
}
-func (w *cuiWidget) textResize() {
+func (n *node) textResize() {
+ w := n.tk
var width, height int
- for i, s := range splitLines(w.text) {
+ for i, s := range splitLines(n.Text) {
log(logNow, "textResize() len =", len(s), i, s)
if (width < len(s)) {
width = len(s)
@@ -32,38 +33,52 @@ func (w *cuiWidget) textResize() {
}
w.gocuiSize.w1 = w.gocuiSize.w0 + width + me.FramePadW
w.gocuiSize.h1 = w.gocuiSize.h0 + height + me.FramePadH
- w.showWidgetPlacement(logNow, "textResize()")
+ n.showWidgetPlacement(logNow, "textResize()")
}
// display's the text of the widget in gocui
-func (w *cuiWidget) showView() {
+func (n *node) showView() {
var err error
+ w := n.tk
+
if (w.cuiName == "") {
- log(logError, "drawView() w.cuiName was not set for widget", w)
- w.cuiName = strconv.Itoa(w.id)
+ log(logError, "showView() w.cuiName was not set for widget", w)
+ w.cuiName = strconv.Itoa(n.WidgetId)
}
- if (w.v != nil) {
- log(logInfo, "drawView() w.v already defined for widget", w)
- v, _ := me.baseGui.View(w.cuiName)
- if (v == nil) {
- log(logError, "drawView() ERROR view does not really exist", w)
- w.v = nil
- } else {
- return
- }
+ if (w.v == nil) {
+ n.updateView()
+ }
+ x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName)
+ log(logInfo, "showView() w.v already defined for widget", n.Name, err)
+ if (x0 != w.gocuiSize.w0) || (y0 != w.gocuiSize.h0) {
+ log(logError, "showView() w.v.w0 != x0", n.Name, w.gocuiSize.w0, x0)
+ log(logError, "showView() w.v.h0 != y0", n.Name, w.gocuiSize.h0, y0)
+ n.updateView()
+ return
}
-
- if (me.baseGui == nil) {
- log(logError, "drawView() ERROR: me.baseGui == nil", w)
+ if (x1 != w.gocuiSize.w1) || (y1 != w.gocuiSize.h1) {
+ log(logError, "showView() w.v.w1 != x1", n.Name, w.gocuiSize.w1, x1)
+ log(logError, "showView() w.v.h1 != y1", n.Name, w.gocuiSize.h1, y1)
+ n.updateView()
return
}
- v, _ := me.baseGui.View(w.cuiName)
- if (v != nil) {
- log(logError, "drawView() already defined for name", w.cuiName)
- w.v = v
+
+ if (w.v.Visible == false) {
+ log(logInfo, "showView() w.v.Visible set to true ", n.Name)
+ w.v.Visible = true
+ }
+}
+
+func (n *node) updateView() {
+ var err error
+ w := n.tk
+ if (me.baseGui == nil) {
+ log(logError, "showView() ERROR: me.baseGui == nil", w)
return
}
+ me.baseGui.DeleteView(w.cuiName)
+ w.v = nil
a := w.gocuiSize.w0
b := w.gocuiSize.h0
@@ -72,12 +87,12 @@ func (w *cuiWidget) showView() {
w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
if err == nil {
- w.showWidgetPlacement(logError, "drawView()")
+ n.showWidgetPlacement(logError, "drawView()")
log(logError, "drawView() internal plugin error err = nil")
return
}
if !errors.Is(err, gocui.ErrUnknownView) {
- w.showWidgetPlacement(logError, "drawView()")
+ n.showWidgetPlacement(logError, "drawView()")
log(logError, "drawView() internal plugin error error.IS()", err)
return
}
@@ -85,13 +100,68 @@ func (w *cuiWidget) showView() {
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
w.v.Wrap = true
- if (w.widgetType == toolkit.Window) {
- w.v.Frame = w.frame
- w.v.Clear()
- fmt.Fprint(w.v, w.text)
- } else {
- fmt.Fprintln(w.v, w.text)
+ w.v.Frame = w.frame
+ w.v.Clear()
+ fmt.Fprint(w.v, n.Text)
+ n.showWidgetPlacement(logNow, "Window: " + n.Text)
+
+ n.setDefaultHighlight()
+ n.setDefaultWidgetColor()
+}
+
+func (n *node) hideWidgets() {
+ w := n.tk
+ w.isCurrent = false
+ switch n.WidgetType {
+ case toolkit.Root:
+ case toolkit.Flag:
+ case toolkit.Window:
+ case toolkit.Box:
+ case toolkit.Grid:
+ default:
+ n.deleteView()
}
+ for _, child := range n.children {
+ child.hideWidgets()
+ }
+}
+
+func (n *node) hideFake() {
+ w := n.tk
+ if (w.isFake) {
+ n.deleteView()
+ }
+ for _, child := range n.children {
+ child.hideFake()
+ }
+}
- w.setDefaultWidgetColor()
+func (n *node) showFake() {
+ w := n.tk
+ if (w.isFake) {
+ n.setFake()
+ n.showWidgetPlacement(logNow, "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 {
+ if n.IsCurrent() {
+ n.showWidgetPlacement(logInfo, "current:")
+ n.showView()
+ } else {
+ n.showWidgetPlacement(logInfo, "not:")
+ // w.drawView()
+ }
+ }
+ for _, child := range n.children {
+ child.showWidgets()
+ }
}