gocui plugin refactor to a *node binary tree
rename arg '--gui <toolkit>' add a cloudflare example fixes since go v1.21 didn't compile anymore due to argv order more place() changes recursive size computation gocui: Major refactor to use the *node binary tree gocui: refactor place() and size() gocui: better place() and spacing (tab, buttons, etc) gocui: better mouse click handling gocui: switch to using tk.gocuiSize & tk.size gocui: event handling cleanups gocui: add window labels work gocui: struct cleanups gocui: duplicate binary tree structs removed gocui: deprecate old children Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
603d5ba7de
commit
fe6a8dd969
|
@ -8,6 +8,7 @@ cmds/console-ui-helloworld/console-ui-helloworld
|
||||||
cmds/debug/debug
|
cmds/debug/debug
|
||||||
cmds/helloworld/helloworld
|
cmds/helloworld/helloworld
|
||||||
cmds/textbox/textbox
|
cmds/textbox/textbox
|
||||||
|
cmds/cloudflare/cloudflare
|
||||||
cmds/*/helloconsole
|
cmds/*/helloconsole
|
||||||
|
|
||||||
# temporary files when building debian packages
|
# temporary files when building debian packages
|
||||||
|
|
7
Makefile
7
Makefile
|
@ -8,6 +8,7 @@ all: README.md
|
||||||
@echo
|
@echo
|
||||||
make clean
|
make clean
|
||||||
make plugins
|
make plugins
|
||||||
|
make cmds-buttonplugin
|
||||||
|
|
||||||
build-dep:
|
build-dep:
|
||||||
apt install -f libgtk-3-dev
|
apt install -f libgtk-3-dev
|
||||||
|
@ -82,11 +83,11 @@ clean:
|
||||||
plugins: plugins-gocui plugins-andlabs
|
plugins: plugins-gocui plugins-andlabs
|
||||||
|
|
||||||
plugins-gocui:
|
plugins-gocui:
|
||||||
GO111MODULE="off" go build -v -x -C toolkit/gocui -buildmode=plugin -o ../gocui.so
|
GO111MODULE="off" go build -C toolkit/gocui -v -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/nocui -v -buildmode=plugin -o ../nocui.so
|
||||||
|
|
||||||
plugins-andlabs:
|
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:
|
||||||
objdump -t toolkit/andlabs.so |less
|
objdump -t toolkit/andlabs.so |less
|
||||||
|
|
|
@ -139,7 +139,7 @@ Creates a window helpful for debugging this package
|
||||||
|
|
||||||
`func ShowDebugValues()`
|
`func ShowDebugValues()`
|
||||||
|
|
||||||
### func [StandardExit](/main.go#L149)
|
### func [StandardExit](/main.go#L153)
|
||||||
|
|
||||||
`func StandardExit()`
|
`func StandardExit()`
|
||||||
|
|
||||||
|
@ -158,13 +158,19 @@ This goroutine can be used like a watchdog timer
|
||||||
|
|
||||||
## Types
|
## Types
|
||||||
|
|
||||||
### type [GuiArgs](/structs.go#L27)
|
### type [GuiArgs](/structs.go#L29)
|
||||||
|
|
||||||
`type GuiArgs struct { ... }`
|
`type GuiArgs struct { ... }`
|
||||||
|
|
||||||
This struct can be used with the go-arg package
|
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 { ... }`
|
`type Node struct { ... }`
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
run: build
|
run: build
|
||||||
./buttonplugin --gui-toolkit gocui >/tmp/witgui.log.stderr 2>&1
|
./buttonplugin --gui gocui >/tmp/witgui.log.stderr 2>&1
|
||||||
|
|
||||||
build-release:
|
build-release:
|
||||||
go get -v -u -x .
|
go get -v -u -x .
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
arg "github.com/alexflint/go-arg"
|
arg "github.com/alexflint/go-arg"
|
||||||
"git.wit.org/wit/gui"
|
"git.wit.org/wit/gui"
|
||||||
|
log "git.wit.org/wit/gui/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ var args struct {
|
||||||
User string `arg:"env:USER"`
|
User string `arg:"env:USER"`
|
||||||
Demo bool `help:"run a demo"`
|
Demo bool `help:"run a demo"`
|
||||||
gui.GuiArgs
|
gui.GuiArgs
|
||||||
|
log.LogArgs
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,6 +28,11 @@ func init() {
|
||||||
arg.MustParse(&args)
|
arg.MustParse(&args)
|
||||||
fmt.Println(args.Foo, args.Bar, args.User)
|
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()
|
||||||
log.Println("STDOUT is now at /tmp/guilogfile")
|
log.Println("STDOUT is now at /tmp/guilogfile")
|
||||||
|
|
|
@ -20,14 +20,7 @@ func main() {
|
||||||
// This will turn on all debugging
|
// This will turn on all debugging
|
||||||
// gui.SetDebug(true)
|
// gui.SetDebug(true)
|
||||||
|
|
||||||
// myGui = gui.New().LoadToolkit("gocui")
|
myGui = gui.New().Default()
|
||||||
// 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])
|
|
||||||
}
|
|
||||||
buttonWindow()
|
buttonWindow()
|
||||||
|
|
||||||
// This is just a optional goroutine to watch that things are alive
|
// This is just a optional goroutine to watch that things are alive
|
||||||
|
|
|
@ -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
|
|
@ -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)
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
|
@ -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"))
|
||||||
|
}
|
|
@ -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]"`
|
||||||
|
}
|
4
main.go
4
main.go
|
@ -123,6 +123,10 @@ func New() *Node {
|
||||||
|
|
||||||
// try to load andlabs, if that doesn't work, fall back to the console
|
// try to load andlabs, if that doesn't work, fall back to the console
|
||||||
func (n *Node) Default() *Node {
|
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
|
// if DISPLAY isn't set, return since gtk can't load
|
||||||
// TODO: figure out how to check what to do in macos and mswindows
|
// TODO: figure out how to check what to do in macos and mswindows
|
||||||
if (os.Getenv("DISPLAY") == "") {
|
if (os.Getenv("DISPLAY") == "") {
|
||||||
|
|
|
@ -119,8 +119,15 @@ func searchPaths(name string) *aplug {
|
||||||
filename = "plugins/" + name + ".so"
|
filename = "plugins/" + name + ".so"
|
||||||
pfile, err = me.resFS.ReadFile(filename)
|
pfile, err = me.resFS.ReadFile(filename)
|
||||||
if (err == nil) {
|
if (err == nil) {
|
||||||
|
filename = "/tmp/" + name + ".so"
|
||||||
log(logError, "write out file here", name, filename, len(pfile))
|
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 {
|
} else {
|
||||||
log(logError, filename, "was not embedded. Error:", err)
|
log(logError, filename, "was not embedded. Error:", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,11 @@ import (
|
||||||
|
|
||||||
var me guiConfig
|
var me guiConfig
|
||||||
|
|
||||||
|
var GuiArg GuiArgs
|
||||||
|
|
||||||
// This struct can be used with the go-arg package
|
// This struct can be used with the go-arg package
|
||||||
type GuiArgs struct {
|
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"`
|
GuiDebug bool `arg:"--gui-debug" help:"open the GUI debugger"`
|
||||||
GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
|
GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,88 +1,67 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "github.com/awesome-gocui/gocui"
|
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make these defaults in config struct definition
|
var fakeStartWidth int = me.FakeW
|
||||||
var fakeStartWidth int = me.DevelOffsetW
|
|
||||||
var fakeStartHeight int = me.TabH + me.FramePadH
|
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
|
w.isFake = true
|
||||||
t := len(w.name)
|
|
||||||
// setup fake labels for non-visable things off screen
|
|
||||||
|
|
||||||
w.gocuiSize.w0 = fakeStartWidth
|
n.gocuiSetWH(fakeStartWidth, fakeStartHeight)
|
||||||
w.gocuiSize.h0 = fakeStartHeight
|
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.PadW
|
|
||||||
w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.PadH
|
|
||||||
|
|
||||||
w.realWidth = w.gocuiSize.Width() + me.FramePadW
|
fakeStartHeight += w.gocuiSize.Height()
|
||||||
w.realHeight = w.gocuiSize.Height() + me.FramePadH
|
|
||||||
|
|
||||||
fakeStartHeight += w.realHeight
|
|
||||||
// TODO: use the actual max hight of the terminal window
|
// TODO: use the actual max hight of the terminal window
|
||||||
if (fakeStartHeight > 24) {
|
if (fakeStartHeight > 24) {
|
||||||
fakeStartHeight = me.TabH + me.FramePadH
|
fakeStartHeight = me.TabH
|
||||||
fakeStartWidth += me.DevelOffsetW
|
fakeStartWidth += me.FakeW
|
||||||
}
|
}
|
||||||
if (logInfo) {
|
if (logInfo) {
|
||||||
w.showView()
|
n.showView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the widget start width & height
|
// set the widget start width & height
|
||||||
func (w *cuiWidget) addWidget() {
|
func (n *node) addWidget() {
|
||||||
log(logInfo, "setStartWH() w.id =", w.id, "w.name", w.name)
|
nw := n.tk
|
||||||
switch w.widgetType {
|
log(logInfo, "setStartWH() w.id =", n.WidgetId, "n.name", n.Name)
|
||||||
|
switch n.WidgetType {
|
||||||
case toolkit.Root:
|
case toolkit.Root:
|
||||||
log(logInfo, "setStartWH() rootNode w.id =", w.id, "w.name", w.name)
|
log(logInfo, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.Name)
|
||||||
w.setFake()
|
n.setFake()
|
||||||
return
|
return
|
||||||
case toolkit.Flag:
|
case toolkit.Flag:
|
||||||
w.setFake()
|
n.setFake()
|
||||||
return
|
return
|
||||||
case toolkit.Window:
|
case toolkit.Window:
|
||||||
me.current = w
|
nw.frame = false
|
||||||
updateCurrentTabs()
|
redoWindows(0,0)
|
||||||
setCurrentWindow(w)
|
|
||||||
return
|
return
|
||||||
case toolkit.Tab:
|
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
|
return
|
||||||
case toolkit.Box:
|
case toolkit.Box:
|
||||||
w.isFake = true
|
nw.isFake = true
|
||||||
w.setFake()
|
n.setFake()
|
||||||
w.startW = w.parent.startW
|
|
||||||
w.startH = w.parent.startH
|
|
||||||
return
|
return
|
||||||
case toolkit.Grid:
|
case toolkit.Grid:
|
||||||
w.isFake = true
|
nw.isFake = true
|
||||||
w.setFake()
|
n.setFake()
|
||||||
w.startW = w.parent.startW
|
|
||||||
w.startH = w.parent.startH
|
|
||||||
return
|
return
|
||||||
case toolkit.Group:
|
case toolkit.Group:
|
||||||
w.startW = w.parent.startW + 4
|
nw.frame = false
|
||||||
w.startH = w.parent.startH + me.DefaultHeight + me.FramePadH
|
return
|
||||||
|
case toolkit.Label:
|
||||||
t := len(w.text)
|
nw.frame = false
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + t + me.FramePadW
|
|
||||||
w.gocuiSize.h1 = w.gocuiSize.h0 + me.DefaultHeight + me.FramePadH
|
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
w.startW = w.parent.startW
|
/*
|
||||||
w.startH = w.parent.startH
|
if n.IsCurrent() {
|
||||||
if w.IsCurrent() {
|
n.updateCurrent()
|
||||||
w.updateCurrent()
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
w.showWidgetPlacement(logInfo, "addWidget()")
|
n.showWidgetPlacement(logInfo, "addWidget()")
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,28 +5,29 @@ import (
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *cuiWidget) setCheckbox(b bool) {
|
func (n *node) setCheckbox(b bool) {
|
||||||
if (w.widgetType != toolkit.Checkbox) {
|
w := n.tk
|
||||||
|
if (n.WidgetType != toolkit.Checkbox) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
w.b = b
|
n.B = b
|
||||||
w.text = "X " + w.name
|
n.Text = "X " + n.Name
|
||||||
} else {
|
} else {
|
||||||
w.b = b
|
n.B = b
|
||||||
w.text = " " + w.name
|
n.Text = " " + n.Name
|
||||||
}
|
}
|
||||||
t := len(w.text) + 1
|
t := len(n.Text) + 1
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + t
|
w.gocuiSize.w1 = w.gocuiSize.w0 + t
|
||||||
|
|
||||||
w.realWidth = w.gocuiSize.Width() + me.PadW
|
// w.realWidth = w.gocuiSize.Width() + me.PadW
|
||||||
w.realHeight = w.gocuiSize.Height() + me.PadH
|
// w.realHeight = w.gocuiSize.Height() + me.PadH
|
||||||
|
|
||||||
if w.frame {
|
// if w.frame {
|
||||||
w.realWidth += me.FramePadW
|
// w.realWidth += me.FramePadW
|
||||||
w.realHeight += me.FramePadH
|
// w.realHeight += me.FramePadH
|
||||||
}
|
// }
|
||||||
|
|
||||||
w.deleteView()
|
n.deleteView()
|
||||||
w.showView()
|
n.showView()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,278 +1,275 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// "fmt"
|
|
||||||
// "errors"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// set isCurrent = false everywhere
|
// set isCurrent = false everywhere
|
||||||
func UnsetCurrent(w *cuiWidget) {
|
func UnsetCurrent(n *node) {
|
||||||
|
w := n.tk
|
||||||
w.isCurrent = false
|
w.isCurrent = false
|
||||||
|
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
UnsetCurrent(child)
|
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
|
// when adding a new widget, this will update the display
|
||||||
// of the current widgets if that widget is supposed
|
// of the current widgets if that widget is supposed
|
||||||
// to be in current display
|
// to be in current display
|
||||||
func (w *cuiWidget) updateCurrent() {
|
func (n *node) updateCurrent() {
|
||||||
if w.widgetType == toolkit.Tab {
|
log("updateCurrent()", n.Name)
|
||||||
if w.IsCurrent() {
|
if n.WidgetType == toolkit.Tab {
|
||||||
setCurrentTab(w)
|
if n.IsCurrent() {
|
||||||
|
setCurrentTab(n)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if w.widgetType == toolkit.Window {
|
if n.WidgetType == toolkit.Window {
|
||||||
if w.IsCurrent() {
|
if n.IsCurrent() {
|
||||||
setCurrentWindow(w)
|
// setCurrentWindow(n)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if w.widgetType == toolkit.Root {
|
if n.WidgetType == toolkit.Root {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.parent.updateCurrent()
|
n.parent.updateCurrent()
|
||||||
}
|
}
|
||||||
|
|
||||||
// shows the widgets in a window
|
// shows the widgets in a window
|
||||||
func setCurrentWindow(w *cuiWidget) {
|
func setCurrentWindow(n *node) {
|
||||||
if w.widgetType != toolkit.Window {
|
if n.IsCurrent() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w := n.tk
|
||||||
|
if n.WidgetType != toolkit.Window {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
UnsetCurrent(me.rootNode)
|
UnsetCurrent(me.rootNode)
|
||||||
me.rootNode.hideWidgets()
|
|
||||||
|
|
||||||
// THIS IS THE BEGINING OF THE LAYOUT
|
if n.hasTabs {
|
||||||
me.rootNode.nextW = 0
|
|
||||||
me.rootNode.nextH = 0
|
|
||||||
|
|
||||||
w.isCurrent = true
|
|
||||||
if w.hasTabs {
|
|
||||||
// set isCurrent = true on the first tab
|
// set isCurrent = true on the first tab
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
child.isCurrent = true
|
child.tk.isCurrent = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
w.isCurrent = true
|
||||||
}
|
}
|
||||||
me.rootNode.redoTabs(true)
|
|
||||||
|
|
||||||
w.placeWidgets()
|
|
||||||
w.showWidgets()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shows the widgets in a tab
|
// shows the widgets in a tab
|
||||||
func setCurrentTab(w *cuiWidget) {
|
func setCurrentTab(n *node) {
|
||||||
if w.widgetType != toolkit.Tab {
|
w := n.tk
|
||||||
|
if n.WidgetType != toolkit.Tab {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
me.current = w
|
|
||||||
UnsetCurrent(me.rootNode)
|
UnsetCurrent(me.rootNode)
|
||||||
me.rootNode.hideWidgets()
|
|
||||||
w.isCurrent = true
|
w.isCurrent = true
|
||||||
w.parent.isCurrent = true
|
p := n.parent.tk
|
||||||
updateCurrentTabs()
|
p.isCurrent = true
|
||||||
w.placeWidgets()
|
log("setCurrent()", n.Name)
|
||||||
w.showWidgets()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) doWidgetClick() {
|
func (n *node) doWidgetClick() {
|
||||||
switch w.widgetType {
|
switch n.WidgetType {
|
||||||
case toolkit.Root:
|
case toolkit.Root:
|
||||||
// THIS IS THE BEGINING OF THE LAYOUT
|
// THIS IS THE BEGINING OF THE LAYOUT
|
||||||
me.rootNode.nextW = 0
|
log("doWidgetClick()", n.Name)
|
||||||
me.rootNode.nextH = 0
|
redoWindows(0,0)
|
||||||
me.rootNode.redoTabs(true)
|
|
||||||
case toolkit.Flag:
|
case toolkit.Flag:
|
||||||
// me.rootNode.redoColor(true)
|
// me.rootNode.redoColor(true)
|
||||||
me.rootNode.dumpTree(true)
|
me.rootNode.dumpTree(true)
|
||||||
case toolkit.Window:
|
case toolkit.Window:
|
||||||
setCurrentWindow(w)
|
|
||||||
case toolkit.Tab:
|
|
||||||
setCurrentTab(w)
|
|
||||||
case toolkit.Group:
|
|
||||||
w.placeWidgets()
|
|
||||||
w.toggleTree()
|
|
||||||
case toolkit.Checkbox:
|
|
||||||
if (w.b) {
|
|
||||||
w.setCheckbox(false)
|
|
||||||
} else {
|
|
||||||
w.setCheckbox(true)
|
|
||||||
}
|
|
||||||
w.doUserEvent()
|
|
||||||
case toolkit.Grid:
|
|
||||||
me.rootNode.hideWidgets()
|
me.rootNode.hideWidgets()
|
||||||
w.placeGrid()
|
n.redoTabs(me.TabW, me.TabH)
|
||||||
w.showWidgets()
|
if ! n.hasTabs {
|
||||||
|
setCurrentWindow(n)
|
||||||
|
n.placeWidgets(me.RawW, me.RawH)
|
||||||
|
n.showWidgets()
|
||||||
|
}
|
||||||
|
case toolkit.Tab:
|
||||||
|
setCurrentTab(n)
|
||||||
|
n.placeWidgets(me.RawW, me.RawH)
|
||||||
|
n.showWidgets()
|
||||||
|
case toolkit.Group:
|
||||||
|
// n.placeWidgets(p.tk.startH, newH)
|
||||||
|
n.toggleTree()
|
||||||
|
case toolkit.Checkbox:
|
||||||
|
if (n.B) {
|
||||||
|
n.setCheckbox(false)
|
||||||
|
} else {
|
||||||
|
n.setCheckbox(true)
|
||||||
|
}
|
||||||
|
n.doUserEvent()
|
||||||
|
case toolkit.Grid:
|
||||||
|
n.placeGrid(n.tk.size.w0, n.tk.size.h0)
|
||||||
|
n.showWidgets()
|
||||||
case toolkit.Box:
|
case toolkit.Box:
|
||||||
// w.showWidgetPlacement(logNow, "drawTree()")
|
// w.showWidgetPlacement(logNow, "drawTree()")
|
||||||
if (w.horizontal) {
|
if (n.horizontal) {
|
||||||
log("BOX IS HORIZONTAL", w.name)
|
log("BOX IS HORIZONTAL", n.Name)
|
||||||
} else {
|
} else {
|
||||||
log("BOX IS VERTICAL", w.name)
|
log("BOX IS VERTICAL", n.Name)
|
||||||
}
|
}
|
||||||
w.placeWidgets()
|
// n.placeWidgets()
|
||||||
w.toggleTree()
|
n.toggleTree()
|
||||||
case toolkit.Button:
|
case toolkit.Button:
|
||||||
w.doUserEvent()
|
n.doUserEvent()
|
||||||
default:
|
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
|
var toggle bool = true
|
||||||
func (w *cuiWidget) toggleTree() {
|
func (n *node) toggleTree() {
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
w.drawTree(toggle)
|
n.drawTree(toggle)
|
||||||
toggle = false
|
toggle = false
|
||||||
} else {
|
} else {
|
||||||
w.hideWidgets()
|
n.hideWidgets()
|
||||||
toggle = true
|
toggle = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// display the widgets in the binary tree
|
// 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) {
|
if (w == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.showWidgetPlacement(logNow, "drawTree()")
|
n.showWidgetPlacement(logNow, "drawTree()")
|
||||||
if (draw) {
|
if (draw) {
|
||||||
// w.textResize()
|
// w.textResize()
|
||||||
w.showView()
|
n.showView()
|
||||||
} else {
|
} else {
|
||||||
w.deleteView()
|
n.deleteView()
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
child.drawTree(draw)
|
child.drawTree(draw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func click(g *gocui.Gui, v *gocui.View) error {
|
func click(g *gocui.Gui, v *gocui.View) error {
|
||||||
// var l string
|
// 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())
|
i, err := strconv.Atoi(v.Name())
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
log(logNow, "click() Can't find widget. error =", err)
|
log(logError, "click() Can't find widget. error =", err)
|
||||||
} else {
|
} else {
|
||||||
log(logNow, "click() ok v.Name() =", v.Name())
|
log(logVerbose, "click() ok v.Name() =", v.Name())
|
||||||
w := findWidget(i, me.rootNode)
|
n := me.rootNode.findWidgetId(i)
|
||||||
if (w == nil) {
|
if (n == nil) {
|
||||||
log(logError, "click() CANT FIND VIEW in binary tree. v.Name =", v.Name())
|
log(logError, "click() CANT FIND VIEW in binary tree. v.Name =", v.Name())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log(logNow, "click() Found widget =", w.id, w.name, ",", w.text)
|
log(logNow, "click() Found widget =", n.WidgetId, n.Name, ",", n.Text)
|
||||||
w.doWidgetClick()
|
n.doWidgetClick()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if _, err := g.SetCurrentView(v.Name()); err != nil {
|
if _, err := g.SetCurrentView(v.Name()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
log(logVerbose, "click() END")
|
||||||
_, 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")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
func findUnderMouse() *node {
|
||||||
// display the widgets in the binary tree
|
var found *node
|
||||||
|
var widgets []*node
|
||||||
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
|
var f func (n *node)
|
||||||
var found *cuiWidget
|
w, h := me.baseGui.MousePosition()
|
||||||
var widgets []*cuiWidget
|
|
||||||
var f func (widget *cuiWidget)
|
|
||||||
w, h := g.MousePosition()
|
|
||||||
|
|
||||||
// find buttons that are below where the mouse button click
|
// find buttons that are below where the mouse button click
|
||||||
f = func(widget *cuiWidget) {
|
f = func(n *node) {
|
||||||
// if ((widget.logicalSize.w0 < w) && (w < widget.logicalSize.w1)) {
|
widget := n.tk
|
||||||
if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
|
// ignore widgets that are not visible
|
||||||
(widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1)) {
|
if n.Visible() {
|
||||||
widgets = append(widgets, widget)
|
if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
|
||||||
found = widget
|
(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(child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
f(me.rootNode)
|
f(me.rootNode)
|
||||||
var t string
|
// widgets has everything that matches
|
||||||
for _, widget := range widgets {
|
// TODO: pop up menu with a list of them
|
||||||
// log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
|
for _, n := range widgets {
|
||||||
t += widget.cuiName + " " + widget.name + "\n"
|
//log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
|
||||||
widget.showWidgetPlacement(logNow, "ctrlDown() FOUND")
|
n.showWidgetPlacement(logNow, "ctrlDown() FOUND")
|
||||||
}
|
}
|
||||||
t = strings.TrimSpace(t)
|
return found
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the widget under the mouse click
|
||||||
|
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
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(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)
|
||||||
|
*/
|
||||||
if (me.ctrlDown == nil) {
|
if (me.ctrlDown == nil) {
|
||||||
setupCtrlDownWidget()
|
setupCtrlDownWidget()
|
||||||
me.ctrlDown.text = "ctrlDown" // t
|
me.ctrlDown.Text = found.Name
|
||||||
me.ctrlDown.cuiName = "ctrlDown"
|
me.ctrlDown.tk.cuiName = "ctrlDown"
|
||||||
me.ctrlDown.parent = me.rootNode
|
// me.ctrlDown.parent = me.rootNode
|
||||||
}
|
}
|
||||||
|
cd := me.ctrlDown.tk
|
||||||
if (found == nil) {
|
if (found == nil) {
|
||||||
found = me.rootNode
|
found = me.rootNode
|
||||||
}
|
}
|
||||||
// ? TODO: found.setRealSize()
|
me.ctrlDown.Text = found.Name
|
||||||
me.ctrlDown.gocuiSize.w0 = found.startW
|
newR := found.realGocuiSize()
|
||||||
me.ctrlDown.gocuiSize.h0 = found.startH
|
cd.gocuiSize.w0 = newR.w0
|
||||||
me.ctrlDown.gocuiSize.w1 = me.ctrlDown.gocuiSize.w0 + found.realWidth
|
cd.gocuiSize.h0 = newR.h0
|
||||||
me.ctrlDown.gocuiSize.h1 = me.ctrlDown.gocuiSize.h0 + found.realHeight
|
cd.gocuiSize.w1 = newR.w1
|
||||||
if (me.ctrlDown.v == nil) {
|
cd.gocuiSize.h1 = newR.h1
|
||||||
me.ctrlDown.text = found.text
|
if me.ctrlDown.Visible() {
|
||||||
me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
|
|
||||||
me.ctrlDown.showView()
|
|
||||||
} else {
|
|
||||||
me.ctrlDown.deleteView()
|
me.ctrlDown.deleteView()
|
||||||
|
} else {
|
||||||
|
me.ctrlDown.updateView()
|
||||||
}
|
}
|
||||||
|
me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
|
||||||
log(logNow, "ctrlDown()", w, h)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,9 @@ import (
|
||||||
|
|
||||||
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
|
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
|
||||||
// gocui.GetColor("#FFAA55") // Dark Purple
|
// gocui.GetColor("#FFAA55") // Dark Purple
|
||||||
func (w *cuiWidget) setDefaultWidgetColor() {
|
func (n *node) setDefaultWidgetColor() {
|
||||||
log(logInfo, "setDefaultWidgetColor() on", w.widgetType, w.name)
|
w := n.tk
|
||||||
|
log(logInfo, "setDefaultWidgetColor() on", n.WidgetType, n.Name)
|
||||||
v, _ := me.baseGui.View(w.cuiName)
|
v, _ := me.baseGui.View(w.cuiName)
|
||||||
if (v == nil) {
|
if (v == nil) {
|
||||||
log(logError, "setDefaultWidgetColor() failed on view == 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("#55AAFF") // super light grey
|
||||||
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
|
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
|
||||||
switch w.widgetType {
|
switch n.WidgetType {
|
||||||
case toolkit.Root:
|
case toolkit.Root:
|
||||||
v.FrameColor = gocui.ColorRed
|
v.FrameColor = gocui.ColorRed
|
||||||
v.BgColor = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
|
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) {
|
if (w.v == nil) {
|
||||||
log(logError, "SetColor() failed on view == nil")
|
log(logError, "SetColor() failed on view == nil")
|
||||||
return
|
return
|
||||||
|
@ -100,16 +102,17 @@ func randColor() gocui.Attribute {
|
||||||
return gocui.GetColor(colors[i])
|
return gocui.GetColor(colors[i])
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) redoColor(draw bool) {
|
func (n *node) redoColor(draw bool) {
|
||||||
|
w := n.tk
|
||||||
if (w == nil) {
|
if (w == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(.05)
|
sleep(.05)
|
||||||
w.setDefaultHighlight()
|
n.setDefaultHighlight()
|
||||||
// w.setDefaultWidgetColor()
|
n.setDefaultWidgetColor()
|
||||||
|
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
child.redoColor(draw)
|
child.redoColor(draw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,118 +3,182 @@ package main
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"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
|
var w *cuiWidget
|
||||||
w = new(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
|
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
|
// 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 {
|
if n.WidgetType == toolkit.Root {
|
||||||
log(logInfo, "setupWidget() FOUND ROOT w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
|
log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
||||||
w.id = 0
|
n.WidgetId = 0
|
||||||
me.rootNode = w
|
me.rootNode = n
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
w.parent = findWidget(a.ParentId, me.rootNode)
|
if (n.WidgetType == toolkit.Box) {
|
||||||
log(logInfo, "setupWidget() w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
|
if (n.B) {
|
||||||
if (w.parent == nil) {
|
n.horizontal = true
|
||||||
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
|
|
||||||
} else {
|
} 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.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
|
w.heights = make(map[int]int) // how wide each column in the grid is
|
||||||
}
|
}
|
||||||
|
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
func setupCtrlDownWidget() {
|
func setupCtrlDownWidget() {
|
||||||
var w *cuiWidget
|
a := new(toolkit.Action)
|
||||||
w = new(cuiWidget)
|
a.Name = "ctrlDown"
|
||||||
|
a.WidgetType = toolkit.Dialog
|
||||||
|
a.WidgetId = -1
|
||||||
|
a.ParentId = 0
|
||||||
|
n := addNode(a)
|
||||||
|
|
||||||
w.name = "ctrlDown"
|
me.ctrlDown = n
|
||||||
|
|
||||||
w.widgetType = toolkit.Flag
|
|
||||||
w.id = -1
|
|
||||||
me.ctrlDown = w
|
|
||||||
// me.rootNode.Append(w)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) deleteView() {
|
func (n *node) deleteView() {
|
||||||
|
w := n.tk
|
||||||
if (w.v != nil) {
|
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
|
w.v = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *cuiWidget) Append(child *cuiWidget) {
|
// searches the binary tree for a WidgetId
|
||||||
n.children = append(n.children, child)
|
func (n *node) findWidgetId(id int) *node {
|
||||||
// child.parent = n
|
if (n == 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")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against w.id =", w.id)
|
|
||||||
|
|
||||||
if (w.id == i) {
|
if n.WidgetId == id {
|
||||||
log(logInfo, "findWidget() FOUND w.id ==", i, w.widgetType, w.name)
|
return n
|
||||||
return w
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
newW := findWidget(i, child)
|
newN := child.findWidgetId(id)
|
||||||
log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against child.id =", child.id)
|
if (newN != nil) {
|
||||||
if (newW != nil) {
|
return newN
|
||||||
return newW
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// searches the binary tree for a WidgetId
|
||||||
|
func (n *node) findWidgetName(name string) *node {
|
||||||
|
if (n == nil) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.tk.cuiName == name {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -2,37 +2,72 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"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) {
|
if (w == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.showWidgetPlacement(logNow, "Tree:")
|
n.showWidgetPlacement(logNow, "Tree:")
|
||||||
|
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
child.dumpTree(draw)
|
child.dumpTree(draw)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) showWidgetPlacement(b bool, s string) {
|
func (n *node) showWidgetPlacement(b bool, s string) {
|
||||||
var s1 string
|
if (n == nil) {
|
||||||
var pId int
|
|
||||||
if (w == nil) {
|
|
||||||
log(logError, "WTF w == nil")
|
log(logError, "WTF w == nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (w.parent == nil) {
|
w := n.tk
|
||||||
log(logVerbose, "showWidgetPlacement() parent == nil", w.id, w.cuiName)
|
|
||||||
|
var s1 string
|
||||||
|
var pId int
|
||||||
|
if (n.parent == nil) {
|
||||||
|
log(logVerbose, "showWidgetPlacement() parent == nil", n.WidgetId, w.cuiName)
|
||||||
pId = 0
|
pId = 0
|
||||||
} else {
|
} else {
|
||||||
pId = w.parent.id
|
pId = n.parent.WidgetId
|
||||||
}
|
}
|
||||||
s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", w.id, pId)
|
s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", n.WidgetId, pId)
|
||||||
s1 += fmt.Sprintf("s/n (%2d,%2d) (%2d,%2d) ", w.startW, w.startH, w.nextW, w.nextH)
|
s1 += fmt.Sprintf("size=(%2d,%2d)(%2d,%2d,%2d,%2d)",
|
||||||
s1 += fmt.Sprintf("size (%2d,%2d) ", w.realWidth, w.realHeight)
|
w.size.Width(), w.size.Height(),
|
||||||
s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
|
w.size.w0, w.size.h0, w.size.w1, w.size.h1)
|
||||||
w.gocuiSize.Width(), w.gocuiSize.Height(),
|
if n.Visible() {
|
||||||
w.gocuiSize.w0, w.gocuiSize.h0, w.gocuiSize.w1, w.gocuiSize.h1)
|
s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
|
||||||
log(b, s1, s, w.widgetType, ",", w.name) // , "text=", w.text)
|
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
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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
|
||||||
|
}
|
|
@ -12,25 +12,23 @@ import (
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func addHelp() {
|
|
||||||
me.baseGui.SetManagerFunc(helplayout)
|
|
||||||
}
|
|
||||||
|
|
||||||
var helpText []string = []string{"KEYBINDINGS",
|
var helpText []string = []string{"KEYBINDINGS",
|
||||||
"",
|
"",
|
||||||
"d: show/hide debugging",
|
"d: show/hide debugging",
|
||||||
"h: hide widgets",
|
"s/h: show/hide all widgets",
|
||||||
"s: show all widgets",
|
"L: list all widgets",
|
||||||
"q: quit()",
|
"q: quit()",
|
||||||
"p: panic()",
|
"p: panic()",
|
||||||
"o: show Stdout",
|
"o: show Stdout",
|
||||||
"l: log to /tmp/witgui.log",
|
"l: log to /tmp/witgui.log",
|
||||||
"Ctrl-D: Enable Debugging",
|
"Ctrl-D: Toggle Debugging",
|
||||||
|
"Ctrl-V: Toggle Verbose Debugging",
|
||||||
"Ctrl-C: Exit",
|
"Ctrl-C: Exit",
|
||||||
"",
|
"",
|
||||||
}
|
}
|
||||||
|
|
||||||
func helplayout(g *gocui.Gui) error {
|
func helplayout() error {
|
||||||
|
g := me.baseGui
|
||||||
var err error
|
var err error
|
||||||
maxX, _ := g.Size()
|
maxX, _ := g.Size()
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"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 {
|
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
|
||||||
return err
|
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
|
return err
|
||||||
}
|
}
|
||||||
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown); err != nil {
|
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 {
|
func(g *gocui.Gui, v *gocui.View) error {
|
||||||
log(logNow, "gocui.SetKeyBinding() dumpTree() START")
|
log(logNow, "gocui.SetKeyBinding() dumpTree() START")
|
||||||
// me.rootNode.dumpTree(true)
|
// me.rootNode.dumpTree(true)
|
||||||
fakeStartWidth = me.DevelOffsetW
|
fakeStartWidth = me.FakeW
|
||||||
fakeStartHeight = me.TabH + me.FramePadH
|
fakeStartHeight = me.TabH + me.FramePadH
|
||||||
if (showDebug) {
|
if (showDebug) {
|
||||||
me.rootNode.showFake()
|
me.rootNode.showFake()
|
||||||
|
@ -59,6 +60,12 @@ func addDebugKeys(g *gocui.Gui) {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// display the help menu
|
||||||
|
g.SetKeybinding("", '?', gocui.ModNone,
|
||||||
|
func(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
helplayout()
|
||||||
|
return nil
|
||||||
|
})
|
||||||
// hide all widgets
|
// hide all widgets
|
||||||
g.SetKeybinding("", 'h', gocui.ModNone,
|
g.SetKeybinding("", 'h', gocui.ModNone,
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
func(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
@ -73,6 +80,26 @@ func addDebugKeys(g *gocui.Gui) {
|
||||||
return nil
|
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
|
// exit
|
||||||
g.SetKeybinding("", 'q', gocui.ModNone,
|
g.SetKeybinding("", 'q', gocui.ModNone,
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
func(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
@ -86,9 +113,28 @@ func addDebugKeys(g *gocui.Gui) {
|
||||||
})
|
})
|
||||||
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone,
|
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone,
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
func(g *gocui.Gui, v *gocui.View) error {
|
||||||
var a toolkit.Action
|
if (showDebug) {
|
||||||
a.ActionType = toolkit.EnableDebug
|
var a toolkit.Action
|
||||||
me.callback <- a
|
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
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ func main() {
|
||||||
|
|
||||||
ferr, _ := os.OpenFile("/tmp/witgui.err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
|
ferr, _ := os.OpenFile("/tmp/witgui.err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
|
||||||
os.Stderr = ferr
|
os.Stderr = ferr
|
||||||
MouseMain()
|
gocuiMain()
|
||||||
|
|
||||||
log(true, "MouseMain() closed")
|
log(true, "MouseMain() closed")
|
||||||
standardExit()
|
standardExit()
|
||||||
|
|
|
@ -6,68 +6,13 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
)
|
)
|
||||||
|
|
||||||
func MouseMain() {
|
// this function uses the mouse position to highlight & unhighlight things
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
// this is run every time the user moves the mouse over the terminal window
|
||||||
if err != nil {
|
func mouseMove(g *gocui.Gui) {
|
||||||
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) {
|
|
||||||
mx, my := g.MousePosition()
|
mx, my := g.MousePosition()
|
||||||
for _, view := range g.Views() {
|
for _, view := range g.Views() {
|
||||||
view.Highlight = false
|
view.Highlight = false
|
||||||
|
@ -102,3 +47,28 @@ func mouseUp(g *gocui.Gui, v *gocui.View) error {
|
||||||
}
|
}
|
||||||
return nil
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -1,263 +1,196 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"strings"
|
||||||
// "github.com/awesome-gocui/gocui"
|
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *cuiWidget) placeBox() {
|
func (n *node) placeBox(startW int, startH int) {
|
||||||
if (w.widgetType != toolkit.Box) {
|
if (n.WidgetType != toolkit.Box) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.startW = w.parent.nextW
|
n.tk.size.w0 = startW
|
||||||
w.startH = w.parent.nextH
|
n.tk.size.h0 = startH
|
||||||
w.nextW = w.parent.nextW
|
n.showWidgetPlacement(logNow, "boxS()")
|
||||||
w.nextH = w.parent.nextH
|
|
||||||
w.realWidth = 0
|
|
||||||
w.realHeight = 0
|
|
||||||
|
|
||||||
var maxW int
|
newW := startW
|
||||||
var maxH int
|
newH := startH
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
w.showWidgetPlacement(logNow, "boxS()")
|
child.placeWidgets(newW, newH)
|
||||||
child.placeWidgets()
|
// n.showWidgetPlacement(logNow, "boxS()")
|
||||||
if (w.horizontal) {
|
// w,h := child.logicalSize()
|
||||||
log(logVerbose, "BOX IS HORIZONTAL")
|
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
|
// expand based on the child width
|
||||||
w.nextW += child.realWidth
|
newW += w
|
||||||
w.realWidth += child.realWidth
|
|
||||||
} else {
|
} 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
|
// expand based on the child height
|
||||||
w.nextH += child.realHeight
|
newH += h
|
||||||
w.realHeight += child.realHeight
|
|
||||||
}
|
|
||||||
if (maxW < child.realWidth) {
|
|
||||||
maxW = child.realWidth
|
|
||||||
}
|
|
||||||
if (maxH < child.realHeight) {
|
|
||||||
maxH = child.realHeight
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (w.horizontal) {
|
// w,h := n.logicalSize()
|
||||||
w.realHeight = maxH
|
newR := n.realGocuiSize()
|
||||||
} else {
|
w := newR.w1 - newR.w0
|
||||||
w.realWidth = maxW
|
h := newR.h1 - newR.h0
|
||||||
}
|
|
||||||
w.showWidgetPlacement(logNow, "boxE()")
|
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() {
|
func (n *node) placeWidgets(startW int, startH int) {
|
||||||
if (w == nil) {
|
if (n == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (me.rootNode == nil) {
|
if (me.rootNode == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
p := w.parent
|
|
||||||
if (p == nil) {
|
|
||||||
log(logInfo, "place()", w.id, "parent == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch w.widgetType {
|
switch n.WidgetType {
|
||||||
case toolkit.Window:
|
case toolkit.Window:
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
w.startW = me.RawW
|
child.placeWidgets(me.RawW, me.RawH)
|
||||||
w.startH = me.RawH
|
return
|
||||||
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()")
|
|
||||||
}
|
}
|
||||||
case toolkit.Tab:
|
case toolkit.Tab:
|
||||||
for _, child := range w.children {
|
for _, child := range n.children {
|
||||||
w.startW = me.RawW
|
child.placeWidgets(me.RawW, me.RawH)
|
||||||
w.startH = me.RawH
|
return
|
||||||
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()")
|
|
||||||
}
|
}
|
||||||
case toolkit.Grid:
|
case toolkit.Grid:
|
||||||
w.showWidgetPlacement(logNow, "placeGrid() START")
|
n.placeGrid(startW, startH)
|
||||||
w.placeGrid()
|
|
||||||
w.showWidgetPlacement(logNow, "placeGrid() END")
|
|
||||||
case toolkit.Box:
|
case toolkit.Box:
|
||||||
w.showWidgetPlacement(logNow, "placeBox() START")
|
n.placeBox(startW, startH)
|
||||||
w.placeBox()
|
|
||||||
w.showWidgetPlacement(logNow, "placeBox() END")
|
|
||||||
case toolkit.Group:
|
case toolkit.Group:
|
||||||
// move the group to the parent's next location
|
// move the group to the parent's next location
|
||||||
w.startW = p.nextW
|
n.gocuiSetWH(startW, startH)
|
||||||
w.startH = p.nextH
|
n.showWidgetPlacement(logNow, "group()")
|
||||||
w.nextW = p.nextW
|
|
||||||
w.nextH = p.nextH
|
|
||||||
w.moveTo(p.nextW, p.nextH)
|
|
||||||
|
|
||||||
// initialize the real width to just the group gocui view
|
newW := startW + me.GroupPadW
|
||||||
w.realWidth = w.gocuiSize.Width() + me.FramePadW
|
newH := startH + 3 // normal hight of the group label
|
||||||
w.realHeight = w.gocuiSize.Height() + me.FramePadH
|
// now move all the children aka: run place() on them
|
||||||
|
for _, child := range n.children {
|
||||||
// indent the widgets for a group
|
child.placeWidgets(newW, newH)
|
||||||
w.nextW = p.nextW + me.GroupPadW
|
// _,h := child.logicalSize()
|
||||||
w.nextH = p.nextH + w.realHeight
|
newR := child.realGocuiSize()
|
||||||
w.showWidgetPlacement(logNow, "place()")
|
// w := newR.w1 - newR.w0
|
||||||
|
h := newR.h1 - newR.h0
|
||||||
// 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()")
|
|
||||||
|
|
||||||
// increment straight down
|
// increment straight down
|
||||||
w.nextH += child.realHeight
|
newH += h
|
||||||
w.realHeight += child.realHeight
|
|
||||||
|
|
||||||
// track largest width
|
|
||||||
if (maxW < child.realWidth) {
|
|
||||||
maxW = child.realWidth
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// add real width of largest child
|
|
||||||
w.realWidth += maxW
|
|
||||||
w.showWidgetPlacement(logNow, "place()")
|
|
||||||
default:
|
default:
|
||||||
w.startW = p.nextW
|
n.gocuiSetWH(startW, startH)
|
||||||
w.startH = p.nextH
|
// n.moveTo(startW, startH)
|
||||||
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()")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func (n *node) placeGrid(startW int, startH int) {
|
||||||
func (w *cuiWidget) setWH() {
|
w := n.tk
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + w.gocuiSize.width
|
w.size.w0 = startW
|
||||||
w.gocuiSize.h1 = w.gocuiSize.h0 + w.gocuiSize.height
|
w.size.h0 = startH
|
||||||
}
|
n.showWidgetPlacement(logInfo, "grid0:")
|
||||||
*/
|
if (n.WidgetType != toolkit.Grid) {
|
||||||
|
|
||||||
func (w *cuiWidget) moveTo(leftW int, topH int) {
|
|
||||||
if (w.isFake) {
|
|
||||||
return
|
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() {
|
// first compute the max sizes of the rows and columns
|
||||||
w.showWidgetPlacement(logNow, "grid0:")
|
for _, child := range n.children {
|
||||||
if (w.widgetType != toolkit.Grid) {
|
// childW, childH := child.logicalSize()
|
||||||
return
|
newR := child.realGocuiSize()
|
||||||
}
|
childW := newR.w1 - newR.w0
|
||||||
w.startW = w.parent.nextW
|
childH := newR.h1 - newR.h0
|
||||||
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
|
|
||||||
|
|
||||||
// set the child's realWidth, and grid offset
|
// set the child's realWidth, and grid offset
|
||||||
child.parentH = hCount
|
if (w.widths[child.AtW] < childW) {
|
||||||
child.parentW = wCount
|
w.widths[child.AtW] = childW
|
||||||
if (w.widths[wCount] < child.realWidth) {
|
|
||||||
w.widths[wCount] = child.realWidth
|
|
||||||
}
|
}
|
||||||
if (w.heights[hCount] < child.realHeight) {
|
if (w.heights[child.AtH] < childH) {
|
||||||
w.heights[hCount] = child.realHeight
|
w.heights[child.AtH] = childH
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
// child.showWidgetPlacement(logInfo, "grid: ")
|
||||||
|
log(logVerbose, "placeGrid:", child.Name, "child()", childW, childH, "At()", child.AtW, child.AtH)
|
||||||
}
|
}
|
||||||
|
|
||||||
// reset the size of the whole grid
|
// find the width and height offset of the grid for AtW,AtH
|
||||||
w.realWidth = 0
|
for _, child := range n.children {
|
||||||
w.realHeight = 0
|
child.showWidgetPlacement(logInfo, "grid1:")
|
||||||
for _, val := range w.widths {
|
|
||||||
w.realWidth += val
|
|
||||||
}
|
|
||||||
for _, val := range w.heights {
|
|
||||||
w.realHeight += val
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range w.children {
|
|
||||||
child.showWidgetPlacement(logVerbose, "grid2:")
|
|
||||||
var totalW, totalH int
|
var totalW, totalH int
|
||||||
for i, val := range w.widths {
|
for i, w := range w.widths {
|
||||||
if (i < child.parentW) {
|
if (i < child.AtW) {
|
||||||
log(logVerbose, "grid2: (w, widths[])", i, val)
|
totalW += w
|
||||||
totalW += w.widths[i]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for i, h := range w.heights {
|
for i, h := range w.heights {
|
||||||
if (i < child.parentH) {
|
if (i < child.AtH) {
|
||||||
totalH += h
|
totalH += h
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// the new corner to move the child to
|
// the new corner to move the child to
|
||||||
w.nextW = w.startW + totalW
|
newW := startW + totalW
|
||||||
w.nextH = w.startH + totalH
|
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:")
|
child.showWidgetPlacement(logInfo, "grid2:")
|
||||||
log(logInfo)
|
|
||||||
}
|
}
|
||||||
// w.updateLogicalSizes()
|
n.showWidgetPlacement(logInfo, "grid3:")
|
||||||
w.showWidgetPlacement(logNow, "grid3:")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// computes the real, actual size of all the gocli objects in a widget
|
||||||
func (w *cuiWidget) setRealSize() {
|
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
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -8,12 +8,17 @@ import (
|
||||||
|
|
||||||
func action(a *toolkit.Action) {
|
func action(a *toolkit.Action) {
|
||||||
log(logInfo, "action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
|
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 {
|
switch a.ActionType {
|
||||||
case toolkit.Add:
|
case toolkit.Add:
|
||||||
if (w == nil) {
|
if (w == nil) {
|
||||||
w = makeWidget(a)
|
n := addNode(a)
|
||||||
w.addWidget()
|
// w = n.tk
|
||||||
|
n.addWidget()
|
||||||
} else {
|
} else {
|
||||||
// this is done to protect the plugin being 'refreshed' with the
|
// this is done to protect the plugin being 'refreshed' with the
|
||||||
// widget binary tree. TODO: find a way to keep them in sync
|
// widget binary tree. TODO: find a way to keep them in sync
|
||||||
|
@ -22,16 +27,25 @@ func action(a *toolkit.Action) {
|
||||||
}
|
}
|
||||||
case toolkit.Show:
|
case toolkit.Show:
|
||||||
if (a.B) {
|
if (a.B) {
|
||||||
w.showView()
|
n.showView()
|
||||||
} else {
|
} else {
|
||||||
w.hideWidgets()
|
n.hideWidgets()
|
||||||
}
|
}
|
||||||
case toolkit.Set:
|
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:
|
case toolkit.SetText:
|
||||||
w.SetText(a.S)
|
n.SetText(a.S)
|
||||||
case toolkit.AddText:
|
case toolkit.AddText:
|
||||||
w.AddText(a.S)
|
n.AddText(a.S)
|
||||||
case toolkit.Move:
|
case toolkit.Move:
|
||||||
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
|
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
|
||||||
case toolkit.CloseToolkit:
|
case toolkit.CloseToolkit:
|
||||||
|
@ -43,42 +57,61 @@ func action(a *toolkit.Action) {
|
||||||
log(logInfo, "action() END")
|
log(logInfo, "action() END")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) AddText(text string) {
|
func (n *node) AddText(text string) {
|
||||||
if (w == nil) {
|
if (n == nil) {
|
||||||
log(logNow, "widget is nil")
|
log(logNow, "widget is nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.vals = append(w.vals, text)
|
n.vals = append(n.vals, text)
|
||||||
for i, s := range w.vals {
|
for i, s := range n.vals {
|
||||||
log(logNow, "AddText()", w.name, i, s)
|
log(logNow, "AddText()", n.Name, i, s)
|
||||||
}
|
}
|
||||||
w.SetText(text)
|
n.SetText(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) SetText(text string) {
|
func (n *node) SetText(text string) {
|
||||||
if (w == nil) {
|
if (n == nil) {
|
||||||
log(logNow, "widget is nil")
|
log(logNow, "widget is nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
w.text = text
|
n.S = text
|
||||||
w.s = text
|
n.Text = text
|
||||||
w.textResize()
|
|
||||||
w.deleteView()
|
n.textResize()
|
||||||
w.showView()
|
n.deleteView()
|
||||||
|
n.showView()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) Set(val any) {
|
func (n *node) Set(val any) {
|
||||||
|
// w := n.tk
|
||||||
log(logInfo, "Set() value =", val)
|
log(logInfo, "Set() value =", val)
|
||||||
|
|
||||||
switch v := val.(type) {
|
switch v := val.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
w.b = val.(bool)
|
n.B = val.(bool)
|
||||||
w.setCheckbox(val.(bool))
|
n.setCheckbox(val.(bool))
|
||||||
case string:
|
case string:
|
||||||
w.SetText(val.(string))
|
n.SetText(val.(string))
|
||||||
case int:
|
case int:
|
||||||
w.i = val.(int)
|
n.I = val.(int)
|
||||||
default:
|
default:
|
||||||
log(logError, "Set() unknown type =", val, v)
|
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)
|
||||||
|
}
|
||||||
|
|
|
@ -52,14 +52,12 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||||
a.WidgetType = toolkit.Stdout
|
a.WidgetType = toolkit.Stdout
|
||||||
a.WidgetId = -3
|
a.WidgetId = -3
|
||||||
a.ParentId = 0
|
a.ParentId = 0
|
||||||
me.logStdout = makeWidget(a)
|
n := addNode(a)
|
||||||
me.logStdout.gocuiSize.w0 = maxX - 32
|
me.logStdout = n
|
||||||
me.logStdout.gocuiSize.h0 = maxY/2
|
me.logStdout.tk.gocuiSize.w0 = maxX - 32
|
||||||
me.logStdout.gocuiSize.w1 = me.logStdout.gocuiSize.w0 + outputW
|
me.logStdout.tk.gocuiSize.h0 = maxY/2
|
||||||
me.logStdout.gocuiSize.h1 = me.logStdout.gocuiSize.h0 + outputH
|
me.logStdout.tk.gocuiSize.w1 = me.logStdout.tk.gocuiSize.w0 + outputW
|
||||||
|
me.logStdout.tk.gocuiSize.h1 = me.logStdout.tk.gocuiSize.h0 + outputH
|
||||||
me.logStdout.realWidth = me.logStdout.gocuiSize.Width()
|
|
||||||
me.logStdout.realHeight = me.logStdout.gocuiSize.Height()
|
|
||||||
}
|
}
|
||||||
v, err := g.View("msg")
|
v, err := g.View("msg")
|
||||||
if (v == nil) {
|
if (v == nil) {
|
||||||
|
@ -78,19 +76,19 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||||
|
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
log("create output window failed", err)
|
log("create output window failed", err)
|
||||||
// return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v == nil) {
|
if (v == nil) {
|
||||||
log("msg == nil. WTF now? err =", err)
|
log("msg == nil. WTF now? err =", err)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
me.logStdout.v = v
|
me.logStdout.tk.v = v
|
||||||
}
|
}
|
||||||
|
|
||||||
me.logStdout.v.Clear()
|
v.Clear()
|
||||||
me.logStdout.v.SelBgColor = gocui.ColorCyan
|
v.SelBgColor = gocui.ColorCyan
|
||||||
me.logStdout.v.SelFgColor = gocui.ColorBlack
|
v.SelFgColor = gocui.ColorBlack
|
||||||
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n" + stringFromMouseClick)
|
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n" + stringFromMouseClick)
|
||||||
g.SetViewOnBottom("msg")
|
g.SetViewOnBottom("msg")
|
||||||
// g.SetViewOnBottom(v.Name())
|
// g.SetViewOnBottom(v.Name())
|
||||||
|
|
|
@ -23,11 +23,12 @@ var me config
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
baseGui *gocui.Gui // the main gocui handle
|
baseGui *gocui.Gui // the main gocui handle
|
||||||
rootNode *cuiWidget // the base of the binary tree. it should have id == 0
|
rootNode *node // 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
|
ctrlDown *node // shown if you click the mouse when the ctrl key is pressed
|
||||||
logStdout *cuiWidget // where to show STDOUT
|
// current *cuiWidget // this is the current tab or window to show
|
||||||
logStdoutV *gocui.View // where to show STDOUT
|
logStdout *node // where to show STDOUT
|
||||||
|
helpLabel *gocui.View
|
||||||
|
|
||||||
// this is the channel we send user events like
|
// this is the channel we send user events like
|
||||||
// mouse clicks or keyboard events back to the program
|
// 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
|
// this is the channel we get requests to make widgets
|
||||||
pluginChan chan toolkit.Action
|
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
|
// 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
|
// so you need 3 char spacing in each direction to not have them overlap
|
||||||
// the amount of padding when there is a frame
|
// 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"`
|
FramePadH int `default:"1" dense:"0"`
|
||||||
|
|
||||||
PadW int `default:"1" dense:"0"`
|
PadW int `default:"1" dense:"0"`
|
||||||
PadH 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
|
// how far down to start Window or Tab headings
|
||||||
WindowW int `default:"8" dense:"0"`
|
WindowW int `default:"8" dense:"0"`
|
||||||
WindowH int `default:"-1"`
|
WindowH int `default:"-1"`
|
||||||
TabW int `default:"2" dense:"0"`
|
TabW int `default:"5" dense:"0"`
|
||||||
TabH int `default:"1" 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
|
// additional amount of space to indent on a group
|
||||||
GroupPadW int `default:"6" dense:"2"`
|
GroupPadW int `default:"6" dense:"2"`
|
||||||
|
|
||||||
// the raw beginning of each window (or tab)
|
// the raw beginning of each window (or tab)
|
||||||
RawW int `default:"7"`
|
RawW int `default:"1"`
|
||||||
RawH int `default:"3"`
|
RawH int `default:"5"`
|
||||||
|
|
||||||
// offset for the hidden widgets
|
// 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?
|
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
|
canvas bool // if set to true, the windows are a raw canvas
|
||||||
menubar bool // for windows
|
menubar bool // for windows
|
||||||
stretchy bool // expand things like buttons to the maximum size
|
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
|
margin bool // add space around the frames of windows
|
||||||
|
|
||||||
// writeMutex protects locks the write process
|
// writeMutex protects locks the write process
|
||||||
writeMutex sync.Mutex
|
writeMutex sync.Mutex
|
||||||
|
|
||||||
|
// used for listWidgets() debugging
|
||||||
|
depth int
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecate these
|
// deprecate these
|
||||||
|
@ -121,23 +116,21 @@ type node struct {
|
||||||
AtW int
|
AtW int
|
||||||
AtH 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
|
// the internal plugin toolkit structure
|
||||||
tk *cuiWidget
|
tk *cuiWidget
|
||||||
}
|
}
|
||||||
|
|
||||||
// the gocui way
|
// this is the gocui way
|
||||||
// the logical size of the widget
|
|
||||||
// corner starts at in the upper left corner
|
// corner starts at in the upper left corner
|
||||||
type rectType struct {
|
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
|
w0, h0, w1, h1 int // left top right bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,82 +143,27 @@ func (r *rectType) Height() int {
|
||||||
}
|
}
|
||||||
|
|
||||||
type cuiWidget struct {
|
type cuiWidget struct {
|
||||||
id int // widget ID
|
// the gocui package variables
|
||||||
// parentId int
|
v *gocui.View // this is nil if the widget is not displayed
|
||||||
widgetType toolkit.WidgetType
|
|
||||||
|
|
||||||
name string // a descriptive name of the widget
|
|
||||||
text string // the current text being displayed
|
|
||||||
cuiName string // what gocui uses to reference the widget
|
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?
|
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'
|
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
|
// used to track the size of grids
|
||||||
widths map[int]int // how tall each row in the grid is
|
widths map[int]int // how tall each row in the grid is
|
||||||
heights map[int]int // how wide each column 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
|
tainted bool
|
||||||
v *gocui.View
|
|
||||||
frame bool
|
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:
|
// from the gocui devs:
|
||||||
|
@ -238,7 +176,7 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
|
||||||
w.tainted = true
|
w.tainted = true
|
||||||
me.writeMutex.Lock()
|
me.writeMutex.Lock()
|
||||||
defer me.writeMutex.Unlock()
|
defer me.writeMutex.Unlock()
|
||||||
if (me.logStdout.v == nil) {
|
if (me.logStdout.tk.v == nil) {
|
||||||
// optionally write the output to /tmp
|
// optionally write the output to /tmp
|
||||||
s := fmt.Sprint(string(p))
|
s := fmt.Sprint(string(p))
|
||||||
s = strings.TrimSuffix(s, "\n")
|
s = strings.TrimSuffix(s, "\n")
|
||||||
|
@ -246,11 +184,11 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
|
||||||
v, _ := me.baseGui.View("msg")
|
v, _ := me.baseGui.View("msg")
|
||||||
if (v != nil) {
|
if (v != nil) {
|
||||||
// fmt.Fprintln(outf, "found msg")
|
// fmt.Fprintln(outf, "found msg")
|
||||||
me.logStdout.v = v
|
me.logStdout.tk.v = v
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// display the output in the gocui window
|
// display the output in the gocui window
|
||||||
me.logStdout.v.Clear()
|
me.logStdout.tk.v.Clear()
|
||||||
|
|
||||||
s := fmt.Sprint(string(p))
|
s := fmt.Sprint(string(p))
|
||||||
s = strings.TrimSuffix(s, "\n")
|
s = strings.TrimSuffix(s, "\n")
|
||||||
|
@ -260,7 +198,7 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
|
||||||
l := len(outputS) - outputH
|
l := len(outputS) - outputH
|
||||||
outputS = outputS[l:]
|
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
|
return len(p), nil
|
||||||
|
|
|
@ -3,136 +3,111 @@ package main
|
||||||
// implements widgets 'Window' and 'Tab'
|
// implements widgets 'Window' and 'Tab'
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"strings"
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
// "github.com/awesome-gocui/gocui"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (w *cuiWidget) hideWidgets() {
|
func (w *cuiWidget) Width() int {
|
||||||
w.isCurrent = false
|
if w.frame {
|
||||||
switch w.widgetType {
|
return w.gocuiSize.w1 - w.gocuiSize.w0
|
||||||
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()
|
|
||||||
}
|
}
|
||||||
|
return w.gocuiSize.w1 - w.gocuiSize.w0 - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) hideFake() {
|
func (w *cuiWidget) Height() int {
|
||||||
if (w.isFake) {
|
if w.frame {
|
||||||
w.deleteView()
|
return w.gocuiSize.h1 - w.gocuiSize.h0
|
||||||
}
|
|
||||||
for _, child := range w.children {
|
|
||||||
child.hideFake()
|
|
||||||
}
|
}
|
||||||
|
return w.gocuiSize.h1 - w.gocuiSize.h0 - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) showFake() {
|
func (n *node) gocuiSetWH(sizeW, sizeH int) {
|
||||||
if (w.isFake) {
|
w := len(n.Text)
|
||||||
w.setFake()
|
lines := strings.Split(n.Text, "\n")
|
||||||
w.showWidgetPlacement(logNow, "showFake:")
|
h := len(lines)
|
||||||
w.showView()
|
|
||||||
}
|
|
||||||
for _, child := range w.children {
|
|
||||||
child.showFake()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *cuiWidget) showWidgets() {
|
tk := n.tk
|
||||||
if (w.isFake) {
|
if tk.isFake {
|
||||||
// don't display by default
|
tk.gocuiSize.w0 = sizeW
|
||||||
|
tk.gocuiSize.h0 = sizeH
|
||||||
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
|
||||||
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if tk.frame {
|
||||||
|
tk.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 {
|
} else {
|
||||||
if w.IsCurrent() {
|
tk.size.w0 = sizeW - 1
|
||||||
w.showWidgetPlacement(logInfo, "current:")
|
tk.size.h0 = sizeH - 1
|
||||||
w.showView()
|
tk.gocuiSize.w0 = tk.size.w0
|
||||||
} else {
|
tk.gocuiSize.h0 = tk.size.h0
|
||||||
w.showWidgetPlacement(logInfo, "not:")
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + 1
|
||||||
// w.drawView()
|
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func redoWindows(nextW int, nextH int) {
|
||||||
|
for _, n := range me.rootNode.children {
|
||||||
|
if n.WidgetType != toolkit.Window {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
w := n.tk
|
||||||
for _, child := range w.children {
|
var tabs bool
|
||||||
child.showWidgets()
|
for _, child := range n.children {
|
||||||
}
|
if (child.WidgetType == toolkit.Tab) {
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
tabs = true
|
tabs = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (tabs) {
|
if (tabs) {
|
||||||
// window is tabs. Don't show it as a standard button
|
// window is tabs. Don't show it as a standard button
|
||||||
w.frame = false
|
w.frame = false
|
||||||
w.hasTabs = true
|
n.hasTabs = true
|
||||||
} else {
|
} else {
|
||||||
w.frame = true
|
w.frame = false
|
||||||
w.hasTabs = 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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range w.children {
|
w.size.w0 = nextW
|
||||||
child.redoTabs(draw)
|
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()
|
||||||
|
|
||||||
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,11 @@ func splitLines(s string) []string {
|
||||||
return lines
|
return lines
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *cuiWidget) textResize() {
|
func (n *node) textResize() {
|
||||||
|
w := n.tk
|
||||||
var width, height int
|
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)
|
log(logNow, "textResize() len =", len(s), i, s)
|
||||||
if (width < len(s)) {
|
if (width < len(s)) {
|
||||||
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.w1 = w.gocuiSize.w0 + width + me.FramePadW
|
||||||
w.gocuiSize.h1 = w.gocuiSize.h0 + height + me.FramePadH
|
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
|
// display's the text of the widget in gocui
|
||||||
func (w *cuiWidget) showView() {
|
func (n *node) showView() {
|
||||||
var err error
|
var err error
|
||||||
|
w := n.tk
|
||||||
|
|
||||||
if (w.cuiName == "") {
|
if (w.cuiName == "") {
|
||||||
log(logError, "drawView() w.cuiName was not set for widget", w)
|
log(logError, "showView() w.cuiName was not set for widget", w)
|
||||||
w.cuiName = strconv.Itoa(w.id)
|
w.cuiName = strconv.Itoa(n.WidgetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (w.v != nil) {
|
if (w.v == nil) {
|
||||||
log(logInfo, "drawView() w.v already defined for widget", w)
|
n.updateView()
|
||||||
v, _ := me.baseGui.View(w.cuiName)
|
}
|
||||||
if (v == nil) {
|
x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName)
|
||||||
log(logError, "drawView() ERROR view does not really exist", w)
|
log(logInfo, "showView() w.v already defined for widget", n.Name, err)
|
||||||
w.v = nil
|
if (x0 != w.gocuiSize.w0) || (y0 != w.gocuiSize.h0) {
|
||||||
} else {
|
log(logError, "showView() w.v.w0 != x0", n.Name, w.gocuiSize.w0, x0)
|
||||||
return
|
log(logError, "showView() w.v.h0 != y0", n.Name, w.gocuiSize.h0, y0)
|
||||||
}
|
n.updateView()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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) {
|
if (me.baseGui == nil) {
|
||||||
log(logError, "drawView() ERROR: me.baseGui == nil", w)
|
log(logError, "showView() ERROR: me.baseGui == nil", w)
|
||||||
return
|
|
||||||
}
|
|
||||||
v, _ := me.baseGui.View(w.cuiName)
|
|
||||||
if (v != nil) {
|
|
||||||
log(logError, "drawView() already defined for name", w.cuiName)
|
|
||||||
w.v = v
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
me.baseGui.DeleteView(w.cuiName)
|
||||||
|
w.v = nil
|
||||||
|
|
||||||
a := w.gocuiSize.w0
|
a := w.gocuiSize.w0
|
||||||
b := w.gocuiSize.h0
|
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)
|
w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
w.showWidgetPlacement(logError, "drawView()")
|
n.showWidgetPlacement(logError, "drawView()")
|
||||||
log(logError, "drawView() internal plugin error err = nil")
|
log(logError, "drawView() internal plugin error err = nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||||
w.showWidgetPlacement(logError, "drawView()")
|
n.showWidgetPlacement(logError, "drawView()")
|
||||||
log(logError, "drawView() internal plugin error error.IS()", err)
|
log(logError, "drawView() internal plugin error error.IS()", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -85,13 +100,68 @@ func (w *cuiWidget) showView() {
|
||||||
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
|
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
|
||||||
|
|
||||||
w.v.Wrap = true
|
w.v.Wrap = true
|
||||||
if (w.widgetType == toolkit.Window) {
|
w.v.Frame = w.frame
|
||||||
w.v.Frame = w.frame
|
w.v.Clear()
|
||||||
w.v.Clear()
|
fmt.Fprint(w.v, n.Text)
|
||||||
fmt.Fprint(w.v, w.text)
|
n.showWidgetPlacement(logNow, "Window: " + n.Text)
|
||||||
} else {
|
|
||||||
fmt.Fprintln(w.v, w.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
w.setDefaultWidgetColor()
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue