reorg to final resting place at go.wit.com/gui/gui
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
3c26b3843f
commit
d1d9c20168
2
box.go
2
box.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewBox(name string, b bool) *Node {
|
func (parent *Node) NewBox(name string, b bool) *Node {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/toolkit"
|
import "go.wit.com/gui/gui/toolkit"
|
||||||
|
|
||||||
func (parent *Node) NewButton(name string, custom func()) *Node {
|
func (parent *Node) NewButton(name string, custom func()) *Node {
|
||||||
newNode := parent.newNode(name, toolkit.Button)
|
newNode := parent.newNode(name, toolkit.Button)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/toolkit"
|
import "go.wit.com/gui/gui/toolkit"
|
||||||
|
|
||||||
func (n *Node) Checked() bool {
|
func (n *Node) Checked() bool {
|
||||||
return n.B
|
return n.B
|
||||||
|
|
|
@ -4,7 +4,7 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
newlog "go.wit.com/log"
|
newlog "go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
8
debug.go
8
debug.go
|
@ -5,7 +5,7 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// various debugging flags
|
// various debugging flags
|
||||||
|
@ -159,9 +159,9 @@ func (n *Node) ListChildren(dump bool) {
|
||||||
if (listChildrenParent != nil) {
|
if (listChildrenParent != nil) {
|
||||||
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
|
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
|
||||||
if (listChildrenParent.id != n.parent.id) {
|
if (listChildrenParent.id != n.parent.id) {
|
||||||
log("parent =",n.parent.id, n.parent.Name)
|
log(true, "parent =",n.parent.id, n.parent.Name)
|
||||||
log("listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
|
log(true, "listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
|
||||||
log(listChildrenParent.id, "!=", n.parent.id)
|
log(true, listChildrenParent.id, "!=", n.parent.id)
|
||||||
exit("parent.child does not match child.parent")
|
exit("parent.child does not match child.parent")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,18 +67,22 @@ func (n *Node) DebugFlags() {
|
||||||
for _, lf := range logGadgets {
|
for _, lf := range logGadgets {
|
||||||
lf.Set(true)
|
lf.Set(true)
|
||||||
}
|
}
|
||||||
|
newlog.All(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.NewButton("log.All(false)", func () {
|
g.NewButton("log.All(false)", func () {
|
||||||
for _, lf := range logGadgets {
|
for _, lf := range logGadgets {
|
||||||
lf.Set(false)
|
lf.Set(false)
|
||||||
}
|
}
|
||||||
|
newlog.All(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.NewButton("Dump Flags", func () {
|
g.NewButton("Dump Flags", func () {
|
||||||
ShowDebugValues()
|
// ShowDebugValues()
|
||||||
|
newlog.ListFlags()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/*
|
||||||
g.NewButton("All On", func () {
|
g.NewButton("All On", func () {
|
||||||
SetDebug(true)
|
SetDebug(true)
|
||||||
})
|
})
|
||||||
|
@ -86,6 +90,7 @@ func (n *Node) DebugFlags() {
|
||||||
g.NewButton("All Off", func () {
|
g.NewButton("All Off", func () {
|
||||||
SetDebug(false)
|
SetDebug(false)
|
||||||
})
|
})
|
||||||
|
*/
|
||||||
|
|
||||||
g = w.NewGroup("List")
|
g = w.NewGroup("List")
|
||||||
g = g.NewGrid("flags grid", 2, 2)
|
g = g.NewGrid("flags grid", 2, 2)
|
||||||
|
|
|
@ -22,10 +22,10 @@ func (n *Node) DebugGoChannels() {
|
||||||
// var debugWG sync.WaitGroup
|
// var debugWG sync.WaitGroup
|
||||||
g.NewButton("init()", func () {
|
g.NewButton("init()", func () {
|
||||||
if (debugNumberChan == nil) {
|
if (debugNumberChan == nil) {
|
||||||
log("making debugNumberChan channel")
|
log(true, "making debugNumberChan channel")
|
||||||
debugNumberChan = make(chan int)
|
debugNumberChan = make(chan int)
|
||||||
} else {
|
} else {
|
||||||
log("debugNumberChan already made")
|
log(true, "debugNumberChan already made")
|
||||||
}
|
}
|
||||||
debugWG = new(sync.WaitGroup)
|
debugWG = new(sync.WaitGroup)
|
||||||
})
|
})
|
||||||
|
@ -46,32 +46,32 @@ func (n *Node) DebugGoChannels() {
|
||||||
go sendNumber(7)
|
go sendNumber(7)
|
||||||
})
|
})
|
||||||
g.NewButton("send 4 numbers (chan <- int)", func () {
|
g.NewButton("send 4 numbers (chan <- int)", func () {
|
||||||
log("generateNumbers(4)")
|
log(true, "generateNumbers(4)")
|
||||||
go generateNumbers(4)
|
go generateNumbers(4)
|
||||||
})
|
})
|
||||||
g.NewButton("debugWG.Done()", func () {
|
g.NewButton("debugWG.Done()", func () {
|
||||||
log("ran debugWG.Done()")
|
log(true, "ran debugWG.Done()")
|
||||||
debugWG.Done()
|
debugWG.Done()
|
||||||
})
|
})
|
||||||
g.NewButton("close chan", func () {
|
g.NewButton("close chan", func () {
|
||||||
log("close() on", debugNumberChan)
|
log(true, "close() on", debugNumberChan)
|
||||||
close(debugNumberChan)
|
close(debugNumberChan)
|
||||||
})
|
})
|
||||||
g.NewButton("print", func () {
|
g.NewButton("print", func () {
|
||||||
log("waitgroup counter is ?")
|
log(true, "waitgroup counter is ?")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
func sendNumber(i int) {
|
func sendNumber(i int) {
|
||||||
log("START debugNumberChan <-", i, " (sending", i, "to channel)")
|
log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)")
|
||||||
debugNumberChan <- i
|
debugNumberChan <- i
|
||||||
debugWG.Wait()
|
debugWG.Wait()
|
||||||
log("END debugNumberChan sendNumber() done", i)
|
log(true, "END debugNumberChan sendNumber() done", i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func generateNumbers(total int) {
|
func generateNumbers(total int) {
|
||||||
fmt.Printf("START generateNumbers()\n")
|
fmt.Printf("START generateNumbers()\n")
|
||||||
for idx := 1; idx <= total; idx++ {
|
for idx := 1; idx <= total; idx++ {
|
||||||
log("ran debugNumberChan <= idx where idx =", idx)
|
log(true, "ran debugNumberChan <= idx where idx =", idx)
|
||||||
fmt.Printf("S generateNumbers() sending %d to channel\n", idx)
|
fmt.Printf("S generateNumbers() sending %d to channel\n", idx)
|
||||||
debugNumberChan <- idx
|
debugNumberChan <- idx
|
||||||
// res, err := (<-r)()
|
// res, err := (<-r)()
|
||||||
|
@ -84,9 +84,9 @@ func generateNumbers(total int) {
|
||||||
// i equals the number of times to read values from the channel
|
// i equals the number of times to read values from the channel
|
||||||
func printInt(i int, name string) {
|
func printInt(i int, name string) {
|
||||||
tmp := 1
|
tmp := 1
|
||||||
log("START printInt", name, "read debugNumberChan()")
|
log(true, "START printInt", name, "read debugNumberChan()")
|
||||||
for num := range debugNumberChan {
|
for num := range debugNumberChan {
|
||||||
log("printInt()",name, "read", num, "from channel")
|
log(true, "printInt()",name, "read", num, "from channel")
|
||||||
debugWG.Done()
|
debugWG.Done()
|
||||||
if (tmp == i) {
|
if (tmp == i) {
|
||||||
return
|
return
|
||||||
|
|
|
@ -69,7 +69,7 @@ func (n *Node) DebugGolangWindow() {
|
||||||
var tmp debug.GCStats
|
var tmp debug.GCStats
|
||||||
var out string
|
var out string
|
||||||
debug.ReadGCStats(&tmp)
|
debug.ReadGCStats(&tmp)
|
||||||
log(tmp)
|
log(true, tmp)
|
||||||
out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection")
|
out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection")
|
||||||
out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections")
|
out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections")
|
||||||
out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
|
out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
|
||||||
|
@ -121,7 +121,7 @@ func (n *Node) DebugGolangWindow() {
|
||||||
og = w.NewGroup("output")
|
og = w.NewGroup("output")
|
||||||
outputTextbox = og.NewTextbox("outputBox")
|
outputTextbox = og.NewTextbox("outputBox")
|
||||||
outputTextbox.Custom = func () {
|
outputTextbox.Custom = func () {
|
||||||
log("custom TextBox() for golang output a =", outputTextbox.S, outputTextbox.id)
|
log(true, "custom TextBox() for golang output a =", outputTextbox.S, outputTextbox.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ func (n *Node) debugAddWidgetButtons() {
|
||||||
a.AddText("make something for tim for qflow")
|
a.AddText("make something for tim for qflow")
|
||||||
a.AddText("and for riscv")
|
a.AddText("and for riscv")
|
||||||
a.Custom = func () {
|
a.Custom = func () {
|
||||||
log("custom dropdown() a =", a.Name, a.S, "id=", a.id)
|
log(true, "custom dropdown() a =", a.Name, a.S, "id=", a.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
n.NewButton("Combobox", func () {
|
n.NewButton("Combobox", func () {
|
||||||
|
@ -173,7 +173,7 @@ func (n *Node) debugAddWidgetButtons() {
|
||||||
a.AddText("mirrors.wit.com")
|
a.AddText("mirrors.wit.com")
|
||||||
a.AddText("go.wit.com")
|
a.AddText("go.wit.com")
|
||||||
a.Custom = func () {
|
a.Custom = func () {
|
||||||
log("custom combobox() a =", a.Name, a.S, "id=", a.id)
|
log(true, "custom combobox() a =", a.Name, a.S, "id=", a.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
n.NewButton("Grid", func () {
|
n.NewButton("Grid", func () {
|
||||||
|
@ -247,12 +247,12 @@ func (n *Node) debugAddWidgetButton() {
|
||||||
activeWidget.SetNext(newX, newY)
|
activeWidget.SetNext(newX, newY)
|
||||||
name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")"
|
name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")"
|
||||||
}
|
}
|
||||||
log("New Name =", name)
|
log(true, "New Name =", name)
|
||||||
log("New Type =", activeLabelNewType.S)
|
log(true, "New Type =", activeLabelNewType.S)
|
||||||
log("New X =", newX)
|
log(true, "New X =", newX)
|
||||||
log("New Y =", newY)
|
log(true, "New Y =", newY)
|
||||||
log("activeWidget.NextW =", activeWidget.NextW)
|
log(true, "activeWidget.NextW =", activeWidget.NextW)
|
||||||
log("activeWidget.NextH =", activeWidget.NextH)
|
log(true, "activeWidget.NextH =", activeWidget.NextH)
|
||||||
log(debugNow, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH)
|
log(debugNow, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH)
|
||||||
activeWidget.Dump()
|
activeWidget.Dump()
|
||||||
|
|
||||||
|
@ -269,19 +269,19 @@ func (n *Node) debugAddWidgetButton() {
|
||||||
case "Button":
|
case "Button":
|
||||||
var n *Node
|
var n *Node
|
||||||
n = activeWidget.NewButton(name, func () {
|
n = activeWidget.NewButton(name, func () {
|
||||||
log("got to button", name, n.id)
|
log(true, "got to button", name, n.id)
|
||||||
})
|
})
|
||||||
case "Checkbox":
|
case "Checkbox":
|
||||||
a := activeWidget.NewCheckbox(name)
|
a := activeWidget.NewCheckbox(name)
|
||||||
a.Custom = func () {
|
a.Custom = func () {
|
||||||
log("custom checkox func a=", a.B, "id=", a.id)
|
log(true, "custom checkox func a=", a.B, "id=", a.id)
|
||||||
}
|
}
|
||||||
case "Dropdown":
|
case "Dropdown":
|
||||||
a := activeWidget.NewDropdown(name)
|
a := activeWidget.NewDropdown(name)
|
||||||
a.AddText(name + " yay")
|
a.AddText(name + " yay")
|
||||||
a.AddText(name + " haha")
|
a.AddText(name + " haha")
|
||||||
a.Custom = func () {
|
a.Custom = func () {
|
||||||
log("WTF a=", a.B, "id=", a.id)
|
log(true, "WTF a=", a.B, "id=", a.id)
|
||||||
}
|
}
|
||||||
case "Combobox":
|
case "Combobox":
|
||||||
a := activeWidget.NewCombobox(name)
|
a := activeWidget.NewCombobox(name)
|
||||||
|
|
|
@ -16,10 +16,15 @@ var myButton *Node
|
||||||
/*
|
/*
|
||||||
Creates a window helpful for debugging this package
|
Creates a window helpful for debugging this package
|
||||||
*/
|
*/
|
||||||
|
func (n *Node) DebugWindow() {
|
||||||
|
newlog.Warn("Don't use DebugWindow() directly anymore")
|
||||||
|
DebugWindow() // todo, remove the non-binary tree access
|
||||||
|
}
|
||||||
|
|
||||||
func DebugWindow() {
|
func DebugWindow() {
|
||||||
bugWin = me.rootNode.NewWindow("go.wit.com/gui debug window").DebugTab("Debug Tab")
|
bugWin = me.rootNode.NewWindow("go.wit.com/gui debug window").DebugTab("Debug Tab")
|
||||||
bugWin.Custom = bugWin.StandardClose
|
bugWin.Custom = bugWin.StandardClose
|
||||||
if newlog.ArgDebug() {
|
if ArgDebug() {
|
||||||
newlog.SetTmp()
|
newlog.SetTmp()
|
||||||
bugWin.DebugFlags()
|
bugWin.DebugFlags()
|
||||||
}
|
}
|
||||||
|
@ -102,7 +107,7 @@ func (n *Node) DebugTab(title string) *Node {
|
||||||
|
|
||||||
g2.NewButton("List Plugins", func () {
|
g2.NewButton("List Plugins", func () {
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log("Loaded plugin:", aplug.name, aplug.filename)
|
log(true, "Loaded plugin:", aplug.name, aplug.filename)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ package gui
|
||||||
// since it is the same. confusing names? maybe...
|
// since it is the same. confusing names? maybe...
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// add a new entry to the dropdown name
|
// add a new entry to the dropdown name
|
||||||
|
|
|
@ -1,29 +0,0 @@
|
||||||
# with andlabs plugin loaded:
|
|
||||||
# PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
|
||||||
# 180006 jcarr 20 0 1918460 41688 31152 S 0.7 0.3 0:00.27 buttonplugin
|
|
||||||
|
|
||||||
# with gocui plugin loaded:
|
|
||||||
# 180365 jcarr 20 0 1392668 24364 12596 S 2.0 0.2 0:00.09 buttonplugin
|
|
||||||
#
|
|
||||||
|
|
||||||
run: build
|
|
||||||
./buttons
|
|
||||||
|
|
||||||
debug:
|
|
||||||
./buttons --gui andlabs --gui-debug --log-debug
|
|
||||||
|
|
||||||
build-release:
|
|
||||||
go get -v -u -x .
|
|
||||||
go build
|
|
||||||
./buttons
|
|
||||||
|
|
||||||
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
|
|
|
@ -1,89 +0,0 @@
|
||||||
// This is a simple example
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"strconv"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
arg "github.com/alexflint/go-arg"
|
|
||||||
)
|
|
||||||
|
|
||||||
var title string = "Demo Plugin Window"
|
|
||||||
var myGui *gui.Node
|
|
||||||
|
|
||||||
var buttonCounter int = 5
|
|
||||||
var gridW int = 5
|
|
||||||
var gridH int = 3
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
arg.MustParse()
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// This will turn on all debugging
|
|
||||||
// gui.SetDebug(true)
|
|
||||||
|
|
||||||
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 w, t, g, more, more2 *gui.Node
|
|
||||||
|
|
||||||
log.Println("buttonWindow() START")
|
|
||||||
|
|
||||||
w = myGui.NewWindow(title).SetText("Nueva Ventana de Botones")
|
|
||||||
t = w.NewTab("buttonTab is this thing").Pad()
|
|
||||||
g = t.NewGroup("buttonGroup").Pad()
|
|
||||||
g1 := t.NewGroup("buttonGroup 2").Pad()
|
|
||||||
more = g1.NewGroup("more").Pad()
|
|
||||||
g1.NewButton("hello2", func () {
|
|
||||||
log.Println("world2")
|
|
||||||
})
|
|
||||||
more2 = g1.NewGrid("gridnuts", gridW, gridH).Pad()
|
|
||||||
|
|
||||||
more2.NewLabel("more2")
|
|
||||||
|
|
||||||
g.NewButton("hello", func () {
|
|
||||||
log.Println("world")
|
|
||||||
})
|
|
||||||
|
|
||||||
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).Pad()
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
run: build
|
|
||||||
./console-ui-helloworld
|
|
||||||
reset
|
|
||||||
ldd ./console-ui-helloworld
|
|
||||||
|
|
||||||
build-release:
|
|
||||||
go get -v -u -x .
|
|
||||||
go build
|
|
||||||
|
|
||||||
build:
|
|
||||||
GO111MODULE="off" go get -v -x .
|
|
||||||
GO111MODULE="off" go build
|
|
||||||
|
|
||||||
update:
|
|
||||||
GO111MODULE="off" go get -v -u -x .
|
|
|
@ -1,130 +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"
|
|
||||||
"log"
|
|
||||||
// "strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initKeybindings(g *gocui.Gui) error {
|
|
||||||
log.Println("got to initKeybindings")
|
|
||||||
if err := g.SetKeybinding("", 'q', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return gocui.ErrQuit
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", 'Q', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return gocui.ErrQuit
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return gocui.ErrQuit
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeySpace, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return newView(g)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyBackspace, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return delView(g)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyBackspace2, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return delView(g)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Println("tab", v.Name())
|
|
||||||
return nextView(g, true)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyArrowLeft, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return moveView(g, v, -delta, 0)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return moveView(g, v, delta, 0)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Println("down", v.Name())
|
|
||||||
return moveView(g, v, 0, delta)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Println("up", v.Name())
|
|
||||||
return moveView(g, v, 0, -delta)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Println("enter", v.Name())
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", 't', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
_, err := g.SetViewOnTop(views[curView])
|
|
||||||
return err
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", 'b', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
_, err := g.SetViewOnBottom(views[curView])
|
|
||||||
return err
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", 'j', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
return newJ(g)
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", 'h', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Println("help", v.Name())
|
|
||||||
tmp, _ := g.SetViewOnTop("help")
|
|
||||||
log.Println("help 2", tmp.Name())
|
|
||||||
// g.SetView("help", 2, 2, 30, 15, 0);
|
|
||||||
g.SetCurrentView("help")
|
|
||||||
// moveView(g, tmp, 0, -delta)
|
|
||||||
if err := g.DeleteView("help"); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
// This creates a simple hello world window
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"fmt"
|
|
||||||
"os"
|
|
||||||
arg "github.com/alexflint/go-arg"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
var args struct {
|
|
||||||
Foo string
|
|
||||||
Bar bool
|
|
||||||
User string `arg:"env:USER"`
|
|
||||||
Demo bool `help:"run a demo"`
|
|
||||||
}
|
|
||||||
|
|
||||||
var f *os.File
|
|
||||||
var err error
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
arg.MustParse(&args)
|
|
||||||
fmt.Println(args.Foo, args.Bar, args.User)
|
|
||||||
|
|
||||||
f, err = os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("error opening file: %v", err)
|
|
||||||
}
|
|
||||||
// hmm. is there a trick here or must this be in main()
|
|
||||||
// defer f.Close()
|
|
||||||
|
|
||||||
log.SetOutput(f)
|
|
||||||
log.Println("This is a test log entry")
|
|
||||||
}
|
|
|
@ -1,83 +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"
|
|
||||||
"log"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
const delta = 1
|
|
||||||
|
|
||||||
var (
|
|
||||||
views = []string{}
|
|
||||||
curView = -1
|
|
||||||
idxView = 0
|
|
||||||
currentX = 5
|
|
||||||
currentY = 2
|
|
||||||
groupSize = 0
|
|
||||||
baseGui *gocui.Gui
|
|
||||||
)
|
|
||||||
|
|
||||||
var helpLabel *gocui.View
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
// setup log to write to a file
|
|
||||||
// logInit()
|
|
||||||
|
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
|
||||||
baseGui = g
|
|
||||||
if err != nil {
|
|
||||||
log.Panicln(err)
|
|
||||||
}
|
|
||||||
defer g.Close()
|
|
||||||
|
|
||||||
g.Highlight = true
|
|
||||||
g.SelFgColor = gocui.ColorRed
|
|
||||||
g.SelFrameColor = gocui.ColorRed
|
|
||||||
|
|
||||||
g.SetManagerFunc(layout)
|
|
||||||
|
|
||||||
if err := initKeybindings(g); err != nil {
|
|
||||||
log.Panicln(err)
|
|
||||||
}
|
|
||||||
if err := newView(g); err != nil {
|
|
||||||
log.Panicln(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
addButton("hello")
|
|
||||||
|
|
||||||
addGroup("blank")
|
|
||||||
addButton("world")
|
|
||||||
|
|
||||||
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
|
||||||
log.Panicln(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func layout(g *gocui.Gui) error {
|
|
||||||
var err error
|
|
||||||
maxX, _ := g.Size()
|
|
||||||
helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 11, 0)
|
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
fmt.Fprintln(helpLabel, "KEYBINDINGS")
|
|
||||||
fmt.Fprintln(helpLabel, "Enter: Click Button")
|
|
||||||
fmt.Fprintln(helpLabel, "Tab/Space: Switch Buttons")
|
|
||||||
fmt.Fprintln(helpLabel, "")
|
|
||||||
fmt.Fprintln(helpLabel, "h: Help")
|
|
||||||
fmt.Fprintln(helpLabel, "Backspace: Delete Button")
|
|
||||||
fmt.Fprintln(helpLabel, "Arrow keys: Move Button")
|
|
||||||
fmt.Fprintln(helpLabel, "t: Move Button to the top")
|
|
||||||
fmt.Fprintln(helpLabel, "b: Move Button to the button")
|
|
||||||
fmt.Fprintln(helpLabel, "Ctrl-C or Q: Exit")
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,46 +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"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
var topX int = 2
|
|
||||||
var bottomX int = 20
|
|
||||||
var topY int = 2
|
|
||||||
var bottomY int = 7
|
|
||||||
|
|
||||||
func newJ(g *gocui.Gui) error {
|
|
||||||
// maxX, maxY := g.Size()
|
|
||||||
name := fmt.Sprintf("jcarr %v test ", idxView)
|
|
||||||
v, err := g.SetView(name, topX, topY, bottomX, bottomY, 0)
|
|
||||||
if err == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Wrap = true
|
|
||||||
fmt.Fprintln(v, name)
|
|
||||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
|
||||||
// fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
|
||||||
log.Println("newJ added a new view", v.Name())
|
|
||||||
|
|
||||||
if _, err := g.SetCurrentView(name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
views = append(views, name)
|
|
||||||
curView = len(views) - 1
|
|
||||||
idxView += 1
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,114 +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"
|
|
||||||
"log"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func addGroup(name string) {
|
|
||||||
log.Println("addGroup()", name)
|
|
||||||
currentY = 2
|
|
||||||
currentX += groupSize + 6
|
|
||||||
}
|
|
||||||
|
|
||||||
func addButton(name string) error {
|
|
||||||
t := len(name)
|
|
||||||
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
|
|
||||||
if err == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Wrap = true
|
|
||||||
fmt.Fprintln(v, " " + name)
|
|
||||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
|
||||||
|
|
||||||
if _, err := baseGui.SetCurrentView(name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
views = append(views, name)
|
|
||||||
curView = len(views) - 1
|
|
||||||
idxView += 1
|
|
||||||
currentY += 3
|
|
||||||
if (groupSize < len(views)) {
|
|
||||||
groupSize = len(views)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func newView(g *gocui.Gui) error {
|
|
||||||
maxX, maxY := g.Size()
|
|
||||||
name := fmt.Sprintf("v%v", idxView)
|
|
||||||
v, err := g.SetView(name, maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5, 0)
|
|
||||||
if err == nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Wrap = true
|
|
||||||
fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
|
||||||
|
|
||||||
if _, err := g.SetCurrentView(name); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
views = append(views, name)
|
|
||||||
curView = len(views) - 1
|
|
||||||
idxView += 1
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func delView(g *gocui.Gui) error {
|
|
||||||
if len(views) <= 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := g.DeleteView(views[curView]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
views = append(views[:curView], views[curView+1:]...)
|
|
||||||
|
|
||||||
return nextView(g, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func nextView(g *gocui.Gui, disableCurrent bool) error {
|
|
||||||
next := curView + 1
|
|
||||||
if next > len(views)-1 {
|
|
||||||
next = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := g.SetCurrentView(views[next]); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
curView = next
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error {
|
|
||||||
name := v.Name()
|
|
||||||
x0, y0, x1, y1, err := g.ViewPosition(name)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
log.Println(x0, y0, x1, y1)
|
|
||||||
if _, err := g.SetView(name, x0+dx, y0+dy, x1+dx, y1+dy, 0); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
x0, y0, x1, y1, err = g.ViewPosition(name)
|
|
||||||
log.Println(x0, y0, x1, y1)
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package gui_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
// This example demonstrates how to create a NewWindow()
|
|
||||||
//
|
|
||||||
// Interacting with a GUI in a cross platform fashion adds some
|
|
||||||
// unusual problems. To obvuscate those, andlabs/ui starts a
|
|
||||||
// goroutine that interacts with the native gui toolkits
|
|
||||||
// on the Linux, MacOS, Windows, etc.
|
|
||||||
//
|
|
||||||
// Because of this oddity, to initialize a new window, the
|
|
||||||
// function is not passed any arguements and instead passes
|
|
||||||
// the information via the Config type.
|
|
||||||
//
|
|
||||||
func ExampleNewWindow() {
|
|
||||||
// Define the name and size
|
|
||||||
gui.Config.Title = "WIT GUI Window 1"
|
|
||||||
gui.Config.Width = 640
|
|
||||||
gui.Config.Height = 480
|
|
||||||
|
|
||||||
// Create the Window
|
|
||||||
gui.NewWindow()
|
|
||||||
|
|
||||||
// Output:
|
|
||||||
// You get a window
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
run: build
|
|
||||||
./helloworld
|
|
||||||
|
|
||||||
build-release:
|
|
||||||
go get -v -u -x .
|
|
||||||
go build
|
|
||||||
./helloworld
|
|
||||||
|
|
||||||
build:
|
|
||||||
GO111MODULE="off" go get -v -x .
|
|
||||||
GO111MODULE="off" go build
|
|
||||||
|
|
||||||
update:
|
|
||||||
GO111MODULE="off" go get -v -u -x .
|
|
|
@ -1,23 +0,0 @@
|
||||||
// This is a simple example
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
helloworld()
|
|
||||||
// This is just a optional goroutine to watch that things are alive
|
|
||||||
gui.Watchdog()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This creates a window
|
|
||||||
func helloworld() {
|
|
||||||
myGui := gui.New().Default()
|
|
||||||
myWindow := myGui.NewWindow("helloworld golang wit/gui window")
|
|
||||||
|
|
||||||
myWindow.NewButton("hello", func () {
|
|
||||||
log.Println("world")
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
# gadgets
|
|
||||||
|
|
||||||
Package gadgets are special collections of widgets
|
|
||||||
|
|
||||||
Things to avoid or keep in mind: Also Features these might enable:
|
|
||||||
|
|
||||||
```go
|
|
||||||
* These should never bypass the binary tree
|
|
||||||
* Hide complexity internally here
|
|
||||||
* These might require corresponding toolkit implementations?
|
|
||||||
* These might allow unique/good corresponding toolkit implementations (date/time selection?)
|
|
||||||
|
|
||||||
## Warning
|
|
||||||
|
|
||||||
Doing this / adding these might be a really bad idea that I will regret later
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
A Labeled Combobox widget:
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
| | |
|
|
||||||
| Food: | <dropdown> |
|
|
||||||
| | |
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
The user can then edit the dropdown field and type anything into it
|
|
||||||
*/
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BasicCombobox struct {
|
|
||||||
ready bool
|
|
||||||
name string
|
|
||||||
|
|
||||||
parent *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
d *gui.Node // dropdown widget
|
|
||||||
|
|
||||||
value string
|
|
||||||
label string
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicCombobox) Get() string {
|
|
||||||
if ! d.Ready() {return ""}
|
|
||||||
return d.value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the status is valid
|
|
||||||
func (d *BasicCombobox) Ready() bool {
|
|
||||||
if d == nil {return false}
|
|
||||||
return d.ready
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicCombobox) Add(value string) {
|
|
||||||
if ! d.Ready() {return}
|
|
||||||
log.Println("BasicCombobox.Add() =", value)
|
|
||||||
d.d.AddDropdownName(value)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicCombobox) Set(value string) bool {
|
|
||||||
if ! d.Ready() {return false}
|
|
||||||
log.Println("BasicCombobox.Set() =", value)
|
|
||||||
d.d.SetText(value)
|
|
||||||
d.value = value
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBasicCombobox(p *gui.Node, name string) *BasicCombobox {
|
|
||||||
d := BasicCombobox {
|
|
||||||
parent: p,
|
|
||||||
name: name,
|
|
||||||
ready: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = p.NewLabel(name)
|
|
||||||
d.d = p.NewCombobox("")
|
|
||||||
d.d.Custom = func() {
|
|
||||||
d.value = d.Get()
|
|
||||||
log.Println("BasicCombobox.Custom() user changed value to =", d.value)
|
|
||||||
if d.Custom != nil {
|
|
||||||
d.Custom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.ready = true
|
|
||||||
return &d
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
A Labeled Dropdown widget:
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
| | |
|
|
||||||
| Food: | <dropdown> |
|
|
||||||
| | |
|
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
This being a 'Basic Dropdown', the dropdown names must be unique
|
|
||||||
*/
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BasicDropdown struct {
|
|
||||||
ready bool
|
|
||||||
name string
|
|
||||||
|
|
||||||
parent *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
d *gui.Node // dropdown widget
|
|
||||||
|
|
||||||
value string
|
|
||||||
label string
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicDropdown) Get() string {
|
|
||||||
if ! d.Ready() {return ""}
|
|
||||||
return d.d.GetText()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the status is valid
|
|
||||||
func (d *BasicDropdown) Ready() bool {
|
|
||||||
if d == nil {return false}
|
|
||||||
return d.ready
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicDropdown) Add(value string) {
|
|
||||||
if ! d.Ready() {return}
|
|
||||||
log.Println("BasicDropdown.Set() =", value)
|
|
||||||
d.d.AddDropdownName(value)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *BasicDropdown) Set(value string) bool {
|
|
||||||
if ! d.Ready() {return false}
|
|
||||||
log.Println("BasicDropdown.Set() =", value)
|
|
||||||
d.l.SetText(value)
|
|
||||||
d.value = value
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBasicDropdown(p *gui.Node, name string) *BasicDropdown {
|
|
||||||
d := BasicDropdown {
|
|
||||||
parent: p,
|
|
||||||
name: name,
|
|
||||||
ready: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = p.NewLabel(name)
|
|
||||||
d.d = p.NewDropdown("")
|
|
||||||
d.d.Custom = func() {
|
|
||||||
d.value = d.Get()
|
|
||||||
log.Println("BasicDropdown.Custom() user changed value to =", d.value)
|
|
||||||
if d.Custom != nil {
|
|
||||||
d.Custom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.ready = true
|
|
||||||
return &d
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
A Labeled Single Line Entry widget:
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
| | |
|
|
||||||
| Food: | <type here> |
|
|
||||||
| | |
|
|
||||||
-----------------------------
|
|
||||||
*/
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BasicEntry struct {
|
|
||||||
parent *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
v *gui.Node // value widget
|
|
||||||
|
|
||||||
value string
|
|
||||||
label string
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasicEntry) Get() string {
|
|
||||||
return n.value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasicEntry) Set(value string) *BasicEntry {
|
|
||||||
log.Println("BasicEntry.Set() =", value)
|
|
||||||
if (n.v != nil) {
|
|
||||||
n.v.Set(value)
|
|
||||||
}
|
|
||||||
n.value = value
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewBasicEntry(p *gui.Node, name string) *BasicEntry {
|
|
||||||
d := BasicEntry {
|
|
||||||
parent: p,
|
|
||||||
value: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = p.NewLabel(name)
|
|
||||||
d.v = p.NewEntryLine("")
|
|
||||||
d.v.Custom = func() {
|
|
||||||
d.value = d.v.S
|
|
||||||
log.Println("BasicEntry.Custom() user changed value to =", d.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &d
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
/*
|
|
||||||
A Labeled label:
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
| | |
|
|
||||||
| Food: | Apple |
|
|
||||||
| | |
|
|
||||||
-----------------------------
|
|
||||||
*/
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Node gui.Node
|
|
||||||
|
|
||||||
type BasicLabel struct {
|
|
||||||
p *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
v *gui.Node // value widget
|
|
||||||
|
|
||||||
value string
|
|
||||||
label string
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasicLabel) Get() string {
|
|
||||||
return n.value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *BasicLabel) Set(value string) *BasicLabel {
|
|
||||||
log.Println("BasicLabel.Set() =", value)
|
|
||||||
if (n.v != nil) {
|
|
||||||
n.v.Set(value)
|
|
||||||
}
|
|
||||||
n.value = value
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ngui *Node) NewBasicLabel(name string) *BasicLabel {
|
|
||||||
var n *gui.Node
|
|
||||||
n = (*gui.Node)(ngui)
|
|
||||||
d := BasicLabel {
|
|
||||||
p: n,
|
|
||||||
value: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = n.NewLabel(name)
|
|
||||||
d.v = n.NewLabel("")
|
|
||||||
d.v.Custom = func() {
|
|
||||||
d.value = d.v.S
|
|
||||||
log.Println("BasicLabel.Custom() user changed value to =", d.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &d
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
/*
|
|
||||||
A slider that goes between a High and Low time
|
|
||||||
*/
|
|
||||||
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Duration struct {
|
|
||||||
p *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
s *gui.Node // slider widget
|
|
||||||
|
|
||||||
Label string
|
|
||||||
Low time.Duration
|
|
||||||
High time.Duration
|
|
||||||
Duration time.Duration
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Duration) Set(d time.Duration) {
|
|
||||||
var timeRange, step, offset time.Duration
|
|
||||||
|
|
||||||
if (d > n.High) {
|
|
||||||
d = n.High
|
|
||||||
}
|
|
||||||
if (d < n.Low) {
|
|
||||||
d = n.Low
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the duration
|
|
||||||
n.Duration = d
|
|
||||||
|
|
||||||
// figure out the integer offset for the Slider GUI Widget
|
|
||||||
timeRange = n.High - n.Low
|
|
||||||
step = timeRange / 1000
|
|
||||||
if (step == 0) {
|
|
||||||
log.Println("duration.Set() division by step == 0", n.Low, n.High, timeRange, step)
|
|
||||||
n.s.Set(0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
offset = d - n.Low
|
|
||||||
i := int(offset / step)
|
|
||||||
log.Println("duration.Set() =", n.Low, n.High, d, "i =", i)
|
|
||||||
n.s.I = i
|
|
||||||
n.s.Set(i)
|
|
||||||
n.s.Custom()
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewDurationSlider(n *gui.Node, label string, low time.Duration, high time.Duration) *Duration {
|
|
||||||
d := Duration {
|
|
||||||
p: n,
|
|
||||||
Label: label,
|
|
||||||
High: high,
|
|
||||||
Low: low,
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = n.NewLabel(label)
|
|
||||||
d.s = n.NewSlider(label, 0, 1000)
|
|
||||||
d.s.Custom = func () {
|
|
||||||
d.Duration = low + (high - low) * time.Duration(d.s.I) / 1000
|
|
||||||
log.Println("d.Duration =", d.Duration)
|
|
||||||
s := fmt.Sprintf("%s (%v)", d.Label, d.Duration)
|
|
||||||
d.l.SetText(s)
|
|
||||||
if (d.Custom != nil) {
|
|
||||||
d.Custom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return &d
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
var myLogGui *LogSettings
|
|
||||||
|
|
||||||
type LogSettings struct {
|
|
||||||
ready bool
|
|
||||||
hidden bool
|
|
||||||
err error
|
|
||||||
|
|
||||||
parent *gui.Node // should be the root of the 'gui' package binary tree
|
|
||||||
window *gui.Node // our window for displaying the log package settings
|
|
||||||
group *gui.Node //
|
|
||||||
grid *gui.Node //
|
|
||||||
|
|
||||||
// Primary Directives
|
|
||||||
status *OneLiner
|
|
||||||
summary *OneLiner
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is initializes the main DO object
|
|
||||||
// You can only have one of these
|
|
||||||
func NewLogSettings(p *gui.Node) *LogSettings {
|
|
||||||
if myLogGui != nil {return myLogGui}
|
|
||||||
myLogGui = new(LogSettings)
|
|
||||||
myLogGui.parent = p
|
|
||||||
|
|
||||||
myLogGui.ready = false
|
|
||||||
|
|
||||||
myLogGui.window = p.NewWindow("Log Settings")
|
|
||||||
|
|
||||||
// make a group label and a grid
|
|
||||||
myLogGui.group = myLogGui.window.NewGroup("droplets:").Pad()
|
|
||||||
myLogGui.grid = myLogGui.group.NewGrid("grid", 2, 1).Pad()
|
|
||||||
|
|
||||||
myLogGui.ready = true
|
|
||||||
myLogGui.Hide()
|
|
||||||
return myLogGui
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns true if the status is valid
|
|
||||||
func (d *LogSettings) Ready() bool {
|
|
||||||
if d == nil {return false}
|
|
||||||
return d.ready
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LogSettings) Show() {
|
|
||||||
if ! d.Ready() {return}
|
|
||||||
log.Info("LogSettings.Show() window")
|
|
||||||
if d.hidden {
|
|
||||||
d.window.Show()
|
|
||||||
}
|
|
||||||
d.hidden = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LogSettings) Hide() {
|
|
||||||
if ! d.Ready() {return}
|
|
||||||
log.Info("LogSettings.Hide() window")
|
|
||||||
if ! d.hidden {
|
|
||||||
d.window.Hide()
|
|
||||||
}
|
|
||||||
d.hidden = true
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *LogSettings) Update() bool {
|
|
||||||
if ! d.Ready() {return false}
|
|
||||||
return true
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/*
|
|
||||||
A Labeled label:
|
|
||||||
|
|
||||||
-----------------------------
|
|
||||||
| | |
|
|
||||||
| Food: | Apple |
|
|
||||||
| | |
|
|
||||||
-----------------------------
|
|
||||||
*/
|
|
||||||
package gadgets
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui"
|
|
||||||
)
|
|
||||||
|
|
||||||
type OneLiner struct {
|
|
||||||
p *gui.Node // parent widget
|
|
||||||
l *gui.Node // label widget
|
|
||||||
v *gui.Node // value widget
|
|
||||||
|
|
||||||
value string
|
|
||||||
label string
|
|
||||||
|
|
||||||
Custom func()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *OneLiner) Get() string {
|
|
||||||
return n.value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *OneLiner) Set(value string) *OneLiner {
|
|
||||||
log.Println("OneLiner.Set() =", value)
|
|
||||||
if (n.v != nil) {
|
|
||||||
n.v.Set(value)
|
|
||||||
}
|
|
||||||
n.value = value
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewOneLiner(n *gui.Node, name string) *OneLiner {
|
|
||||||
d := OneLiner {
|
|
||||||
p: n,
|
|
||||||
value: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
// various timeout settings
|
|
||||||
d.l = n.NewLabel(name)
|
|
||||||
d.v = n.NewLabel("")
|
|
||||||
d.v.Custom = func() {
|
|
||||||
d.value = d.v.S
|
|
||||||
log.Println("OneLiner.Custom() user changed value to =", d.value)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &d
|
|
||||||
}
|
|
14
go.mod
14
go.mod
|
@ -4,23 +4,13 @@ go 1.21.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexflint/go-arg v1.4.3
|
github.com/alexflint/go-arg v1.4.3
|
||||||
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e
|
|
||||||
github.com/awesome-gocui/gocui v1.1.0
|
|
||||||
github.com/golang/protobuf v1.5.3
|
|
||||||
github.com/sourcegraph/conc v0.3.0
|
github.com/sourcegraph/conc v0.3.0
|
||||||
|
go.wit.com/log v0.0.0-20240101060000-bf41970f7793
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexflint/go-scalar v1.1.0 // indirect
|
github.com/alexflint/go-scalar v1.1.0 // indirect
|
||||||
github.com/gdamore/encoding v1.0.0 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/gdamore/tcell/v2 v2.4.0 // indirect
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
|
|
||||||
github.com/mattn/go-runewidth v0.0.10 // indirect
|
|
||||||
github.com/rivo/uniseg v0.1.0 // indirect
|
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
go.uber.org/atomic v1.7.0 // indirect
|
||||||
go.uber.org/multierr v1.9.0 // indirect
|
go.uber.org/multierr v1.9.0 // indirect
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
|
|
||||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
|
|
||||||
golang.org/x/text v0.3.3 // indirect
|
|
||||||
google.golang.org/protobuf v1.26.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
34
go.sum
34
go.sum
|
@ -2,30 +2,11 @@ github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/u
|
||||||
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
|
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
|
||||||
github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
|
github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
|
||||||
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
|
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
|
||||||
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e h1:wSQCJiig/QkoUnpvelSPbLiZNWvh2yMqQTQvIQqSUkU=
|
|
||||||
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e/go.mod h1:5G2EjwzgZUPnnReoKvPWVneT8APYbyKkihDVAHUi0II=
|
|
||||||
github.com/awesome-gocui/gocui v1.1.0 h1:db2j7yFEoHZjpQFeE2xqiatS8bm1lO3THeLwE6MzOII=
|
|
||||||
github.com/awesome-gocui/gocui v1.1.0/go.mod h1:M2BXkrp7PR97CKnPRT7Rk0+rtswChPtksw/vRAESGpg=
|
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
|
|
||||||
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
|
|
||||||
github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM=
|
|
||||||
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
|
|
||||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
|
||||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
|
||||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
|
||||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
|
||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
|
|
||||||
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
|
||||||
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
|
|
||||||
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
|
|
||||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
@ -38,19 +19,8 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
||||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
|
go.wit.com/log v0.0.0-20240101060000-bf41970f7793 h1:kLs+rU96k6b48DqpkO4n3yDZ8hjiVnYjzPSEHU+93aY=
|
||||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
go.wit.com/log v0.0.0-20240101060000-bf41970f7793/go.mod h1:uXgfF8oPx5KYhtNZel6gsFYPMr9+z6sav5lSws1mN6A=
|
||||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
|
|
||||||
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
|
||||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
|
||||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
|
||||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
|
|
||||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
|
||||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
|
||||||
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
|
|
||||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
|
2
grid.go
2
grid.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Grid numbering examples (H) or (W,H)
|
// Grid numbering examples (H) or (W,H)
|
||||||
|
|
2
group.go
2
group.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make a "Group" a "Grid" ?
|
// TODO: make a "Group" a "Grid" ?
|
||||||
|
|
2
image.go
2
image.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewImage(name string) *Node {
|
func (parent *Node) NewImage(name string) *Node {
|
||||||
|
|
2
label.go
2
label.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewLabel(text string) *Node {
|
func (parent *Node) NewLabel(text string) *Node {
|
||||||
|
|
10
log.go
10
log.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
witlog "go.wit.com/gui/log"
|
witlog "go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// various debugging flags
|
// various debugging flags
|
||||||
|
@ -13,9 +13,9 @@ var logVerbose bool = false
|
||||||
|
|
||||||
// var log interface{}
|
// var log interface{}
|
||||||
|
|
||||||
func log(a ...any) {
|
func log(b bool, a ...any) {
|
||||||
witlog.Where = "wit/gui"
|
// witlog.Where = "wit/gui"
|
||||||
witlog.Log(a...)
|
witlog.Log(b, a...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func sleep(a ...any) {
|
func sleep(a ...any) {
|
||||||
|
@ -39,5 +39,5 @@ func logindent(b bool, depth int, format string, a ...any) {
|
||||||
// array prepend(). Why isn't this a standard function. It should be:
|
// array prepend(). Why isn't this a standard function. It should be:
|
||||||
// a.prepend(debugGui, newFormat)
|
// a.prepend(debugGui, newFormat)
|
||||||
a = append([]any{b, newFormat}, a...)
|
a = append([]any{b, newFormat}, a...)
|
||||||
witlog.Log(a...)
|
witlog.Log(b, a...)
|
||||||
}
|
}
|
||||||
|
|
10
main.go
10
main.go
|
@ -3,7 +3,7 @@ package gui
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
|
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
|
||||||
|
@ -15,7 +15,7 @@ const Xaxis = 0 // stack things horizontally
|
||||||
const Yaxis = 1 // stack things vertically
|
const Yaxis = 1 // stack things vertically
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log("init() has been run")
|
log(true, "init() has been run")
|
||||||
|
|
||||||
me.counter = 0
|
me.counter = 0
|
||||||
me.prefix = "wit"
|
me.prefix = "wit"
|
||||||
|
@ -175,10 +175,10 @@ func (n *Node) StandardClose() {
|
||||||
// The window is destroyed and the application exits
|
// The window is destroyed and the application exits
|
||||||
// TODO: properly exit the plugin since Quit() doesn't do it
|
// TODO: properly exit the plugin since Quit() doesn't do it
|
||||||
func StandardExit() {
|
func StandardExit() {
|
||||||
log("wit/gui Standard Window Exit. running os.Exit()")
|
log(true, "wit/gui Standard Window Exit. running os.Exit()")
|
||||||
log("StandardExit() attempt to exit each toolkit plugin")
|
log(true, "StandardExit() attempt to exit each toolkit plugin")
|
||||||
for i, plug := range allPlugins {
|
for i, plug := range allPlugins {
|
||||||
log("NewButton()", i, plug)
|
log(true, "NewButton()", i, plug)
|
||||||
}
|
}
|
||||||
exit(0)
|
exit(0)
|
||||||
}
|
}
|
||||||
|
|
2
node.go
2
node.go
|
@ -1,6 +1,6 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/toolkit"
|
import "go.wit.com/gui/gui/toolkit"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
generic function to create a new node on the binary tree
|
generic function to create a new node on the binary tree
|
||||||
|
|
15
plugin.go
15
plugin.go
|
@ -10,7 +10,7 @@ import (
|
||||||
"embed"
|
"embed"
|
||||||
"plugin"
|
"plugin"
|
||||||
|
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
@ -143,7 +143,18 @@ func searchPaths(name string) *aplug {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log(logError, "searchPaths() error. exiting here?")
|
log(logError, "searchPaths() error. exiting here?")
|
||||||
} else {
|
} else {
|
||||||
filename = homeDir + "/go/src/go.wit.com/gui/toolkit/" + name + ".so"
|
filename = homeDir + "/go/src/go.wit.com/gui/toolkits/" + name + ".so"
|
||||||
|
p = initToolkit(name, filename)
|
||||||
|
if (p != nil) {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
homeDir, err = os.UserHomeDir()
|
||||||
|
if err != nil {
|
||||||
|
log(logError, "searchPaths() error. exiting here?")
|
||||||
|
} else {
|
||||||
|
filename = homeDir + "/go/src/go.wit.com/toolkits/" + name + ".so"
|
||||||
p = initToolkit(name, filename)
|
p = initToolkit(name, filename)
|
||||||
if (p != nil) {
|
if (p != nil) {
|
||||||
return p
|
return p
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
all:
|
|
||||||
# You must use the current protoc-gen-go
|
|
||||||
# protoc --version 3.6++ does not mean that protoc will generate version3 .go files
|
|
||||||
#
|
|
||||||
# apt remove golang-goprotobuf-dev
|
|
||||||
# apt install protobuf-compiler
|
|
||||||
#
|
|
||||||
# Then:
|
|
||||||
# go get -u github.com/golang/protobuf/protoc-gen-go
|
|
||||||
# cd ~/go/src/github.com/golang/protobuf/protoc-gen-go
|
|
||||||
# go install
|
|
||||||
#
|
|
||||||
# Then:
|
|
||||||
protoc --version
|
|
||||||
make widget.pb.go
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.pb.go
|
|
||||||
|
|
||||||
widget.pb.go: widget.proto
|
|
||||||
protoc --go_out=. widget.proto
|
|
||||||
|
|
||||||
compile:
|
|
||||||
protoc --go_out=. *.proto
|
|
||||||
|
|
||||||
deps:
|
|
||||||
apt install golang-goprotobuf-dev
|
|
||||||
apt install protobuf-compiler
|
|
||||||
|
|
||||||
push:
|
|
||||||
git pull
|
|
||||||
git add --all
|
|
||||||
git commit -a -s
|
|
||||||
git push
|
|
|
@ -1,117 +0,0 @@
|
||||||
syntax = "proto3";
|
|
||||||
package guiProtobuf;
|
|
||||||
|
|
||||||
message Action {
|
|
||||||
WidgetType widgetType = 1;
|
|
||||||
ActionType actionType = 2;
|
|
||||||
int64 widgetId = 3;
|
|
||||||
int64 parentId = 4;
|
|
||||||
string text = 5; // what is visable to the user
|
|
||||||
string name = 6; // a name useful for programming
|
|
||||||
|
|
||||||
// This is how the values are passed back and forth
|
|
||||||
// values from things like checkboxes & dropdown's
|
|
||||||
bool b = 7;
|
|
||||||
int64 i = 8;
|
|
||||||
string s = 9;
|
|
||||||
|
|
||||||
// This is used for things like a slider(0,100)
|
|
||||||
int64 x = 10;
|
|
||||||
int64 y = 11;
|
|
||||||
|
|
||||||
// This is for the grid size & widget position
|
|
||||||
int64 w = 12;
|
|
||||||
int64 h = 13;
|
|
||||||
int64 atw = 14;
|
|
||||||
int64 ath = 15;
|
|
||||||
|
|
||||||
bool margin = 16; // Put space around elements to improve look & feel
|
|
||||||
bool expand = 17; // Make widgets fill up the space available
|
|
||||||
|
|
||||||
repeated Response results = 18;
|
|
||||||
repeated Network networks = 19;
|
|
||||||
repeated VM vms = 20;
|
|
||||||
|
|
||||||
enum WidgetType {
|
|
||||||
Unknown = 0;
|
|
||||||
Root = 1; // the master 'root' node of the binary tree
|
|
||||||
Flag = 2; // used to send configuration values to plugins
|
|
||||||
Window = 3; // in certain gui's (ncurses), these are tabs
|
|
||||||
Tab = 4; // internally, this is a window
|
|
||||||
Frame = 5; // deprecate?
|
|
||||||
Grid = 6; // like drawers in a chest
|
|
||||||
Group = 7; // like the 'Appetizers' section on a menu
|
|
||||||
Box = 8; // a vertical or horizontal stack of widgets
|
|
||||||
Button = 9;
|
|
||||||
Checkbox = 10; // select 'on' or 'off'
|
|
||||||
Dropdown = 11;
|
|
||||||
Combobox = 12; // dropdown with edit=true
|
|
||||||
Label = 13;
|
|
||||||
Textbox = 14; // is this a Label with edit=true
|
|
||||||
Slider = 15; // like a progress bar
|
|
||||||
Spinner = 16; // like setting the oven temperature
|
|
||||||
Separator = 17; // TODO
|
|
||||||
Image = 18; // TODO
|
|
||||||
Area = 19; // TODO
|
|
||||||
Form = 20; // TODO
|
|
||||||
Font = 21; // TODO
|
|
||||||
Color = 22; // TODO
|
|
||||||
Dialog = 23; // TODO
|
|
||||||
Stdout = 24; // can be used to capture and display log output
|
|
||||||
}
|
|
||||||
|
|
||||||
enum ActionType {
|
|
||||||
Health = 0;
|
|
||||||
Add = 1;
|
|
||||||
Delete = 2;
|
|
||||||
Get = 3;
|
|
||||||
Set = 4;
|
|
||||||
GetText = 5;
|
|
||||||
SetText = 6;
|
|
||||||
AddText = 7;
|
|
||||||
Show = 8;
|
|
||||||
Hide = 9;
|
|
||||||
Enable = 10;
|
|
||||||
Disable = 11;
|
|
||||||
Margin = 12;
|
|
||||||
Unmargin = 13;
|
|
||||||
Pad = 14;
|
|
||||||
Unpad = 15;
|
|
||||||
Append = 16;
|
|
||||||
Move = 17;
|
|
||||||
Dump = 18;
|
|
||||||
User = 19; // the user did something (mouse, keyboard, etc)
|
|
||||||
InitToolkit = 20; // initializes the toolkit
|
|
||||||
CloseToolkit = 21; // closes the toolkit
|
|
||||||
UserQuit = 22; // the user closed the GUI
|
|
||||||
EnableDebug = 23; // open the debugging window
|
|
||||||
}
|
|
||||||
|
|
||||||
message Response {
|
|
||||||
// ActionType type = 1;
|
|
||||||
int64 id = 2;
|
|
||||||
string name = 3;
|
|
||||||
string error = 4;
|
|
||||||
repeated string snippets = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message Network {
|
|
||||||
int64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
int64 total_cpu = 3;
|
|
||||||
int64 total_mem = 4;
|
|
||||||
string login_url = 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
message VM {
|
|
||||||
int64 id = 1;
|
|
||||||
string name = 2;
|
|
||||||
string hostname = 3;
|
|
||||||
int64 cpus = 4;
|
|
||||||
int64 memory = 5;
|
|
||||||
int64 disk = 6;
|
|
||||||
string IPv6 = 7;
|
|
||||||
string role = 8;
|
|
||||||
string baseImage = 9;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This recreates the whole GUI for a plugin
|
// This recreates the whole GUI for a plugin
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSlider(name string, x int, y int) *Node {
|
func (parent *Node) NewSlider(name string, x int, y int) *Node {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSpinner(name string, x int, y int) *Node {
|
func (parent *Node) NewSpinner(name string, x int, y int) *Node {
|
||||||
|
|
|
@ -3,7 +3,7 @@ package gui
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"embed"
|
"embed"
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
2
tab.go
2
tab.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This function should make a new node with the parent and
|
// This function should make a new node with the parent and
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/toolkit"
|
"go.wit.com/gui/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewTextbox(name string) *Node {
|
func (parent *Node) NewTextbox(name string) *Node {
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
all: plugin
|
|
||||||
|
|
||||||
plugin:
|
|
||||||
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../andlabs.so
|
|
||||||
|
|
||||||
goget:
|
|
||||||
GO111MODULE="off" go get -v -t -u
|
|
|
@ -1,265 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) show(b bool) {
|
|
||||||
if n.tk == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n.tk.uiControl == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (b) {
|
|
||||||
n.tk.uiControl.Show()
|
|
||||||
} else {
|
|
||||||
n.tk.uiControl.Hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) enable(b bool) {
|
|
||||||
if n == nil {
|
|
||||||
panic("WHAT? enable was passed nil. How does this even happen?")
|
|
||||||
}
|
|
||||||
if n.tk == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n.tk.uiControl == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (b) {
|
|
||||||
n.tk.uiControl.Enable()
|
|
||||||
} else {
|
|
||||||
n.tk.uiControl.Disable()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) pad(at toolkit.ActionType) {
|
|
||||||
log(logInfo, "pad() on WidgetId =", n.WidgetId)
|
|
||||||
|
|
||||||
t := n.tk
|
|
||||||
if (t == nil) {
|
|
||||||
log(logError, "pad() toolkit struct == nil. for", n.WidgetId)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
t.uiGroup.SetMargined(true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
t.uiGroup.SetMargined(false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
t.uiGroup.SetMargined(true)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
t.uiGroup.SetMargined(false)
|
|
||||||
}
|
|
||||||
case toolkit.Tab:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
tabSetMargined(t.uiTab, true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
tabSetMargined(t.uiTab, false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
tabSetMargined(t.uiTab, true)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
tabSetMargined(t.uiTab, false)
|
|
||||||
}
|
|
||||||
case toolkit.Window:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
t.uiWindow.SetMargined(true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
t.uiWindow.SetMargined(false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
t.uiWindow.SetBorderless(false)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
t.uiWindow.SetBorderless(true)
|
|
||||||
}
|
|
||||||
case toolkit.Grid:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
t.uiGrid.SetPadded(false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
t.uiGrid.SetPadded(false)
|
|
||||||
}
|
|
||||||
case toolkit.Box:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
t.uiBox.SetPadded(true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
t.uiBox.SetPadded(false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
t.uiBox.SetPadded(true)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
t.uiBox.SetPadded(false)
|
|
||||||
}
|
|
||||||
case toolkit.Textbox:
|
|
||||||
log(debugError, "TODO: implement ActionType =", at)
|
|
||||||
default:
|
|
||||||
log(debugError, "TODO: implement pad() for", at)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) move(newParent *node) {
|
|
||||||
p := n.parent
|
|
||||||
|
|
||||||
switch p.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
case toolkit.Tab:
|
|
||||||
// tabSetMargined(tParent.uiTab, true)
|
|
||||||
case toolkit.Window:
|
|
||||||
// t.uiWindow.SetBorderless(false)
|
|
||||||
case toolkit.Grid:
|
|
||||||
// t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Box:
|
|
||||||
log(logInfo, "TODO: move() where =", p.ParentId)
|
|
||||||
log(logInfo, "TODO: move() for widget =", n.WidgetId)
|
|
||||||
|
|
||||||
stretchy = true
|
|
||||||
if (p.tk.uiBox != nil) {
|
|
||||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
|
||||||
}
|
|
||||||
// log(debugNow, "is there a tParent parent? =", tParent.parent)
|
|
||||||
// tParent.uiBox.Delete(0)
|
|
||||||
|
|
||||||
// this didn't work:
|
|
||||||
// tWidget.uiControl.Disable()
|
|
||||||
// sleep(.8)
|
|
||||||
default:
|
|
||||||
log(logError, "TODO: need to implement move() for type =", n.WidgetType)
|
|
||||||
log(logError, "TODO: need to implement move() for where =", p.ParentId)
|
|
||||||
log(logError, "TODO: need to implement move() for widget =", n.WidgetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) Delete() {
|
|
||||||
p := n.parent
|
|
||||||
log(debugNow, "uiDelete()", n.WidgetId, "to", p.WidgetId)
|
|
||||||
|
|
||||||
switch p.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
// tParent.uiGroup.SetMargined(true)
|
|
||||||
case toolkit.Tab:
|
|
||||||
// tabSetMargined(tParent.uiTab, true)
|
|
||||||
case toolkit.Window:
|
|
||||||
// t.uiWindow.SetBorderless(false)
|
|
||||||
case toolkit.Grid:
|
|
||||||
// t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Box:
|
|
||||||
log(debugNow, "tWidget.boxC =", p.Name)
|
|
||||||
log(debugNow, "is there a tParent parent? =", p.parent)
|
|
||||||
if (p.tk.boxC < 1) {
|
|
||||||
log(debugNow, "Can not delete from Box. already empty. tWidget.boxC =", p.tk.boxC)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
p.tk.uiBox.Delete(0)
|
|
||||||
p.tk.boxC -= 1
|
|
||||||
|
|
||||||
// this didn't work:
|
|
||||||
// tWidget.uiControl.Disable()
|
|
||||||
// sleep(.8)
|
|
||||||
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
|
|
||||||
default:
|
|
||||||
log(debugError, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
|
|
||||||
log(debugError, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rawAction(a *toolkit.Action) {
|
|
||||||
log(logInfo, "rawAction() START a.ActionType =", a.ActionType)
|
|
||||||
log(logInfo, "rawAction() START a.S =", a.S)
|
|
||||||
|
|
||||||
if (a.ActionType == toolkit.InitToolkit) {
|
|
||||||
// TODO: make sure to only do this once
|
|
||||||
// go uiMain.Do(func() {
|
|
||||||
// ui.Main(demoUI)
|
|
||||||
// go catchActionChannel()
|
|
||||||
// })
|
|
||||||
// try doing this on toolkit load in init()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log(logInfo, "rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
|
|
||||||
switch a.WidgetType {
|
|
||||||
case toolkit.Flag:
|
|
||||||
flag(a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n := me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
|
|
||||||
if (a.ActionType == toolkit.Add) {
|
|
||||||
ui.QueueMain(func() {
|
|
||||||
add(a)
|
|
||||||
})
|
|
||||||
// TODO: remove this artificial delay
|
|
||||||
// sleep(.001)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a.ActionType == toolkit.Dump) {
|
|
||||||
log(debugNow, "rawAction() Dump =", a.ActionType, a.WidgetType, n.Name)
|
|
||||||
me.rootNode.listChildren(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n == nil) {
|
|
||||||
me.rootNode.listChildren(true)
|
|
||||||
log(true, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
|
|
||||||
log(true, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
|
|
||||||
log(true, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
|
|
||||||
log(true, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
|
|
||||||
return
|
|
||||||
panic("findWidgetId found nil for id = " + strconv.Itoa(a.WidgetId))
|
|
||||||
}
|
|
||||||
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Show:
|
|
||||||
n.show(true)
|
|
||||||
case toolkit.Hide:
|
|
||||||
n.show(false)
|
|
||||||
case toolkit.Enable:
|
|
||||||
n.enable(true)
|
|
||||||
case toolkit.Disable:
|
|
||||||
n.enable(false)
|
|
||||||
case toolkit.Get:
|
|
||||||
n.setText(a)
|
|
||||||
case toolkit.GetText:
|
|
||||||
switch a.WidgetType {
|
|
||||||
case toolkit.Textbox:
|
|
||||||
a.S = n.S
|
|
||||||
}
|
|
||||||
case toolkit.Set:
|
|
||||||
n.setText(a)
|
|
||||||
case toolkit.SetText:
|
|
||||||
n.setText(a)
|
|
||||||
case toolkit.AddText:
|
|
||||||
n.setText(a)
|
|
||||||
case toolkit.Margin:
|
|
||||||
n.pad(toolkit.Unmargin)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
n.pad(toolkit.Margin)
|
|
||||||
case toolkit.Pad:
|
|
||||||
n.pad(toolkit.Pad)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
n.pad(toolkit.Unpad)
|
|
||||||
case toolkit.Delete:
|
|
||||||
n.Delete()
|
|
||||||
case toolkit.Move:
|
|
||||||
log(debugNow, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
|
|
||||||
newParent := me.rootNode.findWidgetId(a.ParentId)
|
|
||||||
n.move(newParent)
|
|
||||||
default:
|
|
||||||
log(debugError, "rawAction() Unknown =", a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
||||||
log(logInfo, "rawAction() END =", a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
|
@ -1,157 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func actionDump(b bool, a *toolkit.Action) {
|
|
||||||
log(b, "actionDump() Widget.Type =", a.ActionType)
|
|
||||||
log(b, "actionDump() Widget.S =", a.S)
|
|
||||||
log(b, "actionDump() Widget.I =", a.I)
|
|
||||||
log(b, "actionDump() WidgetId =", a.WidgetId)
|
|
||||||
log(b, "actionDump() ParentId =", a.ParentId)
|
|
||||||
}
|
|
||||||
|
|
||||||
func add(a *toolkit.Action) {
|
|
||||||
if (a.WidgetType == toolkit.Root) {
|
|
||||||
me.rootNode = addNode(a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n := addNode(a)
|
|
||||||
|
|
||||||
p := n.parent
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Window:
|
|
||||||
newWindow(n)
|
|
||||||
return
|
|
||||||
case toolkit.Tab:
|
|
||||||
p.newTab(n)
|
|
||||||
return
|
|
||||||
case toolkit.Label:
|
|
||||||
p.newLabel(n)
|
|
||||||
return
|
|
||||||
case toolkit.Button:
|
|
||||||
p.newButton(n)
|
|
||||||
return
|
|
||||||
case toolkit.Grid:
|
|
||||||
p.newGrid(n)
|
|
||||||
return
|
|
||||||
case toolkit.Checkbox:
|
|
||||||
p.newCheckbox(n)
|
|
||||||
return
|
|
||||||
case toolkit.Spinner:
|
|
||||||
p.newSpinner(n)
|
|
||||||
return
|
|
||||||
case toolkit.Slider:
|
|
||||||
p.newSlider(n)
|
|
||||||
return
|
|
||||||
case toolkit.Dropdown:
|
|
||||||
p.newDropdown(n)
|
|
||||||
return
|
|
||||||
case toolkit.Combobox:
|
|
||||||
p.newCombobox(n)
|
|
||||||
return
|
|
||||||
case toolkit.Textbox:
|
|
||||||
p.newTextbox(n)
|
|
||||||
return
|
|
||||||
case toolkit.Group:
|
|
||||||
p.newGroup(n)
|
|
||||||
return
|
|
||||||
case toolkit.Box:
|
|
||||||
p.newBox(n)
|
|
||||||
return
|
|
||||||
case toolkit.Image:
|
|
||||||
p.newImage(n)
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
log(debugError, "add() error TODO: ", n.WidgetType, n.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This routine is very specific to this toolkit
|
|
||||||
// It's annoying and has to be copied to each widget when there are changes
|
|
||||||
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
|
|
||||||
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
|
|
||||||
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
|
|
||||||
// -- jcarr 2023/03/09
|
|
||||||
|
|
||||||
// Grid numbering examples by (X,Y)
|
|
||||||
// ---------
|
|
||||||
// -- (1) --
|
|
||||||
// -- (2) --
|
|
||||||
// ---------
|
|
||||||
//
|
|
||||||
// -----------------------------
|
|
||||||
// -- (1,1) -- (1,2) -- (1,3) --
|
|
||||||
// -- (2,1) -- (2,2) -- (2,3) --
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// internally for andlabs/ui
|
|
||||||
// (x&y flipped and start at zero)
|
|
||||||
// -----------------------------
|
|
||||||
// -- (0,0) -- (1,0) -- (1,0) --
|
|
||||||
// -- (0,1) -- (1,1) -- (1,1) --
|
|
||||||
// -----------------------------
|
|
||||||
func (p *node) place(n *node) bool {
|
|
||||||
log(logInfo, "place() START", n.WidgetType, n.Name)
|
|
||||||
|
|
||||||
if (p.tk == nil) {
|
|
||||||
log(logError, "p.tk == nil", p.Name, p.ParentId, p.WidgetType, p.tk)
|
|
||||||
log(logError, "n = ", n.Name, n.ParentId, n.WidgetType, n.tk)
|
|
||||||
panic("p.tk == nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
log(logInfo, "place() switch", p.WidgetType)
|
|
||||||
switch p.WidgetType {
|
|
||||||
case toolkit.Grid:
|
|
||||||
log(logInfo, "place() Grid try at Parent X,Y =", n.X, n.Y)
|
|
||||||
n.tk.gridX = n.AtW - 1
|
|
||||||
n.tk.gridY = n.AtH - 1
|
|
||||||
log(logInfo, "place() Grid try at gridX,gridY", n.tk.gridX, n.tk.gridY)
|
|
||||||
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
|
|
||||||
p.tk.uiGrid.Append(n.tk.uiControl,
|
|
||||||
n.tk.gridX, n.tk.gridY, 1, 1,
|
|
||||||
false, ui.AlignFill, false, ui.AlignFill)
|
|
||||||
return true
|
|
||||||
case toolkit.Group:
|
|
||||||
if (p.tk.uiBox == nil) {
|
|
||||||
p.tk.uiGroup.SetChild(n.tk.uiControl)
|
|
||||||
log(logInfo, "place() hack Group to use this as the box?", n.Name, n.WidgetType)
|
|
||||||
p.tk.uiBox = n.tk.uiBox
|
|
||||||
} else {
|
|
||||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
case toolkit.Tab:
|
|
||||||
if (p.tk.uiTab == nil) {
|
|
||||||
log(logError, "p.tk.uiTab == nil for n.WidgetId =", n.WidgetId, "p.tk =", p.tk)
|
|
||||||
panic("p.tk.uiTab == nil")
|
|
||||||
}
|
|
||||||
if (n.tk.uiControl == nil) {
|
|
||||||
log(logError, "n.tk.uiControl == nil for n.WidgetId =", n.WidgetId, "n.tk =", n.tk)
|
|
||||||
panic("n.tk.uiControl == nil")
|
|
||||||
}
|
|
||||||
log(logError, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
|
|
||||||
// log(logError, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.Name, n.Text, n.WidgetType)
|
|
||||||
// log(logError, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.Name, p.Text, p.WidgetType)
|
|
||||||
// panic("n.tk.uiControl == nil")
|
|
||||||
p.tk.uiTab.Append(n.Text, n.tk.uiControl)
|
|
||||||
p.tk.boxC += 1
|
|
||||||
return true
|
|
||||||
case toolkit.Box:
|
|
||||||
log(logInfo, "place() uiBox =", p.tk.uiBox)
|
|
||||||
log(logInfo, "place() uiControl =", n.tk.uiControl)
|
|
||||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
|
||||||
p.tk.boxC += 1
|
|
||||||
return true
|
|
||||||
case toolkit.Window:
|
|
||||||
p.tk.uiWindow.SetChild(n.tk.uiControl)
|
|
||||||
return true
|
|
||||||
default:
|
|
||||||
log(debugError, "place() how? Parent =", p.WidgetId, p.WidgetType)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// make new Box here
|
|
||||||
func (p *node) newBox(n *node) {
|
|
||||||
log(debugToolkit, "newBox()", n.Name)
|
|
||||||
|
|
||||||
newt := new(guiWidget)
|
|
||||||
var box *ui.Box
|
|
||||||
|
|
||||||
log(debugToolkit, "rawBox() create", n.Name)
|
|
||||||
|
|
||||||
if (n.B) {
|
|
||||||
box = ui.NewHorizontalBox()
|
|
||||||
} else {
|
|
||||||
box = ui.NewVerticalBox()
|
|
||||||
}
|
|
||||||
box.SetPadded(padded)
|
|
||||||
|
|
||||||
newt.uiBox = box
|
|
||||||
newt.uiControl = box
|
|
||||||
newt.boxC = 0
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newButton(n *node) {
|
|
||||||
log(debugToolkit, "newButton() START", n.Name)
|
|
||||||
|
|
||||||
t := p.tk
|
|
||||||
if (t == nil) {
|
|
||||||
log(debugToolkit, "newButton() toolkit struct == nil. name=", n.Name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
newt := new(guiWidget)
|
|
||||||
|
|
||||||
b := ui.NewButton(n.Text)
|
|
||||||
newt.uiButton = b
|
|
||||||
newt.uiControl = b
|
|
||||||
newt.parent = t
|
|
||||||
|
|
||||||
b.OnClicked(func(*ui.Button) {
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
log(debugToolkit, "newButton() END", n.Name)
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newCheckbox(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
log(debugToolkit, "newCheckbox()", n.Name, n.WidgetType)
|
|
||||||
|
|
||||||
newt.uiCheckbox = ui.NewCheckbox(n.Text)
|
|
||||||
newt.uiControl = newt.uiCheckbox
|
|
||||||
|
|
||||||
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
|
|
||||||
n.B = newt.checked()
|
|
||||||
log(debugChange, "val =", n.B)
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) checked() bool {
|
|
||||||
return t.uiCheckbox.Checked()
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newCombobox(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
log(debugToolkit, "newCombobox() START", n.Name)
|
|
||||||
|
|
||||||
cb := ui.NewEditableCombobox()
|
|
||||||
newt.uiEditableCombobox = cb
|
|
||||||
newt.uiControl = cb
|
|
||||||
|
|
||||||
// initialize the index
|
|
||||||
newt.c = 0
|
|
||||||
newt.val = make(map[int]string)
|
|
||||||
|
|
||||||
cb.OnChanged(func(spin *ui.EditableCombobox) {
|
|
||||||
n.S = spin.Text()
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) AddComboboxName(title string) {
|
|
||||||
t.uiEditableCombobox.Append(title)
|
|
||||||
if (t.val == nil) {
|
|
||||||
log(debugToolkit, "make map didn't work")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.val[t.c] = title
|
|
||||||
|
|
||||||
// If this is the first menu added, set the dropdown to it
|
|
||||||
// if (t.c == 0) {
|
|
||||||
// }
|
|
||||||
t.c = t.c + 1
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../nocui/common.go
|
|
|
@ -1,168 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
var defaultBehavior bool = true
|
|
||||||
|
|
||||||
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
|
||||||
var canvas bool // if set to true, the windows are a raw canvas
|
|
||||||
var menubar bool // for windows
|
|
||||||
var stretchy bool // expand things like buttons to the maximum size
|
|
||||||
var padded bool // add space between things like buttons
|
|
||||||
var margin bool // add space around the frames of windows
|
|
||||||
|
|
||||||
var debugToolkit bool = false
|
|
||||||
var debugChange bool = false
|
|
||||||
var debugPlugin bool = false
|
|
||||||
var debugAction bool = false
|
|
||||||
var debugFlags bool = false
|
|
||||||
var debugGrid bool = false
|
|
||||||
var debugNow bool = true
|
|
||||||
var debugError bool = true
|
|
||||||
|
|
||||||
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
|
||||||
func setDefaultBehavior(s bool) {
|
|
||||||
defaultBehavior = s
|
|
||||||
if (defaultBehavior) {
|
|
||||||
log(debugToolkit, "Setting this toolkit to use the default behavior.")
|
|
||||||
log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
|
|
||||||
stretchy = false
|
|
||||||
padded = true
|
|
||||||
menubar = true
|
|
||||||
margin = true
|
|
||||||
canvas = false
|
|
||||||
bookshelf = true // 99% of the time, things make a vertical stack of objects
|
|
||||||
} else {
|
|
||||||
log(debugToolkit, "This toolkit is set to ignore the default behavior.")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func ShowDebug () {
|
|
||||||
log(true, "debugToolkit =", debugToolkit)
|
|
||||||
log(true, "debugChange =", debugChange)
|
|
||||||
log(true, "debugAction =", debugPlugin)
|
|
||||||
log(true, "debugFlags =", debugFlags)
|
|
||||||
log(true, "debugNow =", debugNow)
|
|
||||||
log(true, "debugError =", debugError)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) Dump(b bool) {
|
|
||||||
if ! b {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log(b, "Name = ", t.Width, t.Height)
|
|
||||||
if (t.uiBox != nil) {
|
|
||||||
log(b, "uiBox =", t.uiBox)
|
|
||||||
}
|
|
||||||
if (t.uiButton != nil) {
|
|
||||||
log(b, "uiButton =", t.uiButton)
|
|
||||||
}
|
|
||||||
if (t.uiCombobox != nil) {
|
|
||||||
log(b, "uiCombobox =", t.uiCombobox)
|
|
||||||
}
|
|
||||||
if (t.uiWindow != nil) {
|
|
||||||
log(b, "uiWindow =", t.uiWindow)
|
|
||||||
}
|
|
||||||
if (t.uiTab != nil) {
|
|
||||||
log(b, "uiTab =", t.uiTab)
|
|
||||||
}
|
|
||||||
if (t.uiGroup != nil) {
|
|
||||||
log(b, "uiGroup =", t.uiGroup)
|
|
||||||
}
|
|
||||||
if (t.uiEntry != nil) {
|
|
||||||
log(b, "uiEntry =", t.uiEntry)
|
|
||||||
}
|
|
||||||
if (t.uiMultilineEntry != nil) {
|
|
||||||
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
|
|
||||||
}
|
|
||||||
if (t.uiSlider != nil) {
|
|
||||||
log(b, "uiSlider =", t.uiSlider)
|
|
||||||
}
|
|
||||||
if (t.uiCheckbox != nil) {
|
|
||||||
log(b, "uiCheckbox =", t.uiCheckbox)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func GetDebugToolkit () bool {
|
|
||||||
return debugToolkit
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func flag(a *toolkit.Action) {
|
|
||||||
// should set the checkbox to this value
|
|
||||||
switch a.S {
|
|
||||||
case "Quiet":
|
|
||||||
logInfo = a.B
|
|
||||||
logVerbose = a.B
|
|
||||||
logWarn = a.B
|
|
||||||
logError = a.B
|
|
||||||
case "Error":
|
|
||||||
logError = a.B
|
|
||||||
case "Info":
|
|
||||||
logInfo = a.B
|
|
||||||
case "Verbose":
|
|
||||||
logInfo = a.B
|
|
||||||
logVerbose = a.B
|
|
||||||
logWarn = a.B
|
|
||||||
logError = a.B
|
|
||||||
debugToolkit = a.B
|
|
||||||
debugChange = a.B
|
|
||||||
debugPlugin = a.B
|
|
||||||
debugFlags = a.B
|
|
||||||
case "Toolkit":
|
|
||||||
debugToolkit = a.B
|
|
||||||
case "Change":
|
|
||||||
debugChange = a.B
|
|
||||||
case "Plugin":
|
|
||||||
debugPlugin = a.B
|
|
||||||
case "Flags":
|
|
||||||
debugFlags = a.B
|
|
||||||
case "Now":
|
|
||||||
debugNow = a.B
|
|
||||||
case "Show":
|
|
||||||
ShowDebug()
|
|
||||||
default:
|
|
||||||
log(debugError, "Can't set unknown flag", a.S)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) dumpWidget(b bool) {
|
|
||||||
var info, d string
|
|
||||||
|
|
||||||
if (n == nil) {
|
|
||||||
log(debugError, "dumpWidget() node == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
info = n.WidgetType.String()
|
|
||||||
|
|
||||||
d = strconv.Itoa(n.WidgetId) + " " + info + " " + n.Name
|
|
||||||
|
|
||||||
var tabs string
|
|
||||||
for i := 0; i < listChildrenDepth; i++ {
|
|
||||||
tabs = tabs + defaultPadding
|
|
||||||
}
|
|
||||||
log(b, tabs + d)
|
|
||||||
}
|
|
||||||
|
|
||||||
var defaultPadding string = " "
|
|
||||||
var listChildrenDepth int = 0
|
|
||||||
|
|
||||||
func (n *node) listChildren(dump bool) {
|
|
||||||
if (n == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n.dumpWidget(dump)
|
|
||||||
if len(n.children) == 0 {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
listChildrenDepth += 1
|
|
||||||
child.listChildren(dump)
|
|
||||||
listChildrenDepth -= 1
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// if you include more than just this import
|
|
||||||
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
|
|
||||||
import "go.wit.com/gui/toolkit"
|
|
||||||
|
|
||||||
// delete the child widget from the parent
|
|
||||||
// p = parent, c = child
|
|
||||||
func (n *node) destroy() {
|
|
||||||
pId := n.parent.WidgetId
|
|
||||||
cId := n.WidgetId
|
|
||||||
log(logNow, "delete()", pId, cId)
|
|
||||||
|
|
||||||
pt := n.parent.tk
|
|
||||||
ct := n.tk
|
|
||||||
if (ct == nil) {
|
|
||||||
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", pId, cId)
|
|
||||||
// this pukes out a whole universe of shit
|
|
||||||
// listMap()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Button:
|
|
||||||
log(true, "Should delete Button here:", n.Name)
|
|
||||||
log(true, "Parent:")
|
|
||||||
pt.Dump(true)
|
|
||||||
log(true, "Child:")
|
|
||||||
ct.Dump(true)
|
|
||||||
if (pt.uiBox == nil) {
|
|
||||||
log(true, "Don't know how to destroy this")
|
|
||||||
} else {
|
|
||||||
log(true, "Fuck it, destroy the whole box", n.parent.Name)
|
|
||||||
// pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent.
|
|
||||||
pt.uiBox.SetPadded(false)
|
|
||||||
pt.uiBox.Delete(4)
|
|
||||||
ct.uiButton.Disable()
|
|
||||||
// ct.uiButton.Hide()
|
|
||||||
ct.uiButton.Destroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
case toolkit.Window:
|
|
||||||
log(true, "Should delete Window here:", n.Name)
|
|
||||||
default:
|
|
||||||
log(true, "Fuckit, let's destroy a button")
|
|
||||||
if (ct.uiButton != nil) {
|
|
||||||
pt.uiBox.Delete(4)
|
|
||||||
ct.uiButton.Destroy()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,90 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import "github.com/andlabs/ui"
|
|
||||||
import _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is a code example taken directly from the toolkit andlabs/ui
|
|
||||||
|
|
||||||
This code is here to double check that the toolkit itself still works
|
|
||||||
the same way. This is intended as a sanity check.
|
|
||||||
*/
|
|
||||||
|
|
||||||
func BlankWindow(w *ui.Window) *ui.Box {
|
|
||||||
hbox := ui.NewHorizontalBox()
|
|
||||||
hbox.SetPadded(true)
|
|
||||||
w.SetChild(hbox)
|
|
||||||
return hbox
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) DemoNumbersPage() {
|
|
||||||
var w *ui.Window
|
|
||||||
|
|
||||||
log(debugToolkit, "Starting wit/gui toolkit andlabs/ui DemoNumbersPage()")
|
|
||||||
|
|
||||||
w = t.uiWindow
|
|
||||||
t.uiBox = makeNumbersPage()
|
|
||||||
t.uiBox.SetPadded(true)
|
|
||||||
w.SetChild(t.uiBox)
|
|
||||||
w.SetTitle("Internal demo of andlabs/ui toolkit")
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeNumbersPage() *ui.Box {
|
|
||||||
hbox := ui.NewHorizontalBox()
|
|
||||||
hbox.SetPadded(true)
|
|
||||||
|
|
||||||
group := ui.NewGroup("Numbers")
|
|
||||||
group.SetMargined(true)
|
|
||||||
hbox.Append(group, true)
|
|
||||||
|
|
||||||
vbox := ui.NewVerticalBox()
|
|
||||||
vbox.SetPadded(true)
|
|
||||||
group.SetChild(vbox)
|
|
||||||
|
|
||||||
spinbox := ui.NewSpinbox(0, 100)
|
|
||||||
slider := ui.NewSlider(0, 100)
|
|
||||||
pbar := ui.NewProgressBar()
|
|
||||||
spinbox.OnChanged(func(*ui.Spinbox) {
|
|
||||||
slider.SetValue(spinbox.Value())
|
|
||||||
pbar.SetValue(spinbox.Value())
|
|
||||||
})
|
|
||||||
slider.OnChanged(func(*ui.Slider) {
|
|
||||||
spinbox.SetValue(slider.Value())
|
|
||||||
pbar.SetValue(slider.Value())
|
|
||||||
})
|
|
||||||
vbox.Append(spinbox, false)
|
|
||||||
vbox.Append(slider, false)
|
|
||||||
vbox.Append(pbar, false)
|
|
||||||
|
|
||||||
ip := ui.NewProgressBar()
|
|
||||||
ip.SetValue(-1)
|
|
||||||
vbox.Append(ip, false)
|
|
||||||
|
|
||||||
group = ui.NewGroup("Lists")
|
|
||||||
group.SetMargined(true)
|
|
||||||
hbox.Append(group, true)
|
|
||||||
|
|
||||||
vbox = ui.NewVerticalBox()
|
|
||||||
vbox.SetPadded(true)
|
|
||||||
group.SetChild(vbox)
|
|
||||||
|
|
||||||
cbox := ui.NewCombobox()
|
|
||||||
cbox.Append("Combobox Item 1")
|
|
||||||
cbox.Append("Combobox Item 2")
|
|
||||||
cbox.Append("Combobox Item 3")
|
|
||||||
vbox.Append(cbox, false)
|
|
||||||
|
|
||||||
ecbox := ui.NewEditableCombobox()
|
|
||||||
ecbox.Append("Editable Item 1")
|
|
||||||
ecbox.Append("Editable Item 2")
|
|
||||||
ecbox.Append("Editable Item 3")
|
|
||||||
vbox.Append(ecbox, false)
|
|
||||||
|
|
||||||
rb := ui.NewRadioButtons()
|
|
||||||
rb.Append("Radio Button 1")
|
|
||||||
rb.Append("Radio Button 2")
|
|
||||||
rb.Append("Radio Button 3")
|
|
||||||
vbox.Append(rb, false)
|
|
||||||
|
|
||||||
return hbox
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newDropdown(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
log(debugToolkit, "gui.Toolbox.newDropdown() START", n.Name)
|
|
||||||
|
|
||||||
cb := ui.NewCombobox()
|
|
||||||
newt.uiCombobox = cb
|
|
||||||
newt.uiControl = cb
|
|
||||||
|
|
||||||
// initialize the index
|
|
||||||
newt.c = 0
|
|
||||||
newt.val = make(map[int]string)
|
|
||||||
|
|
||||||
cb.OnSelected(func(spin *ui.Combobox) {
|
|
||||||
i := spin.Selected()
|
|
||||||
if (newt.val == nil) {
|
|
||||||
log(logError, "make map didn't work")
|
|
||||||
n.S = "map did not work. ui.Combobox error"
|
|
||||||
} else {
|
|
||||||
n.S = newt.val[i]
|
|
||||||
}
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) addDropdownName(title string) {
|
|
||||||
t.uiCombobox.Append(title)
|
|
||||||
if (t.val == nil) {
|
|
||||||
log(debugToolkit, "make map didn't work")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.val[t.c] = title
|
|
||||||
|
|
||||||
// If this is the first menu added, set the dropdown to it
|
|
||||||
if (t.c == 0) {
|
|
||||||
log(debugChange, "THIS IS THE FIRST Dropdown", title)
|
|
||||||
t.uiCombobox.SetSelected(0)
|
|
||||||
}
|
|
||||||
t.c = t.c + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) SetDropdown(i int) {
|
|
||||||
t.uiCombobox.SetSelected(i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) AddDropdownName(s string) {
|
|
||||||
log(logInfo, "AddDropdownName()", n.WidgetId, "add:", s)
|
|
||||||
|
|
||||||
t := n.tk
|
|
||||||
if (t == nil) {
|
|
||||||
log(logInfo, "AddDropdownName() toolkit struct == nil. name=", n.Name, s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.addDropdownName(s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) SetDropdownName(a *toolkit.Action, s string) {
|
|
||||||
log(logInfo, "SetDropdown()", n.WidgetId, ",", s)
|
|
||||||
|
|
||||||
t := n.tk
|
|
||||||
if (t == nil) {
|
|
||||||
log(debugError, "SetDropdown() FAILED mapToolkits[w] == nil. name=", n.WidgetId, s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t.SetDropdown(1)
|
|
||||||
// TODO: send back to wit/gui goroutine with the chan
|
|
||||||
n.S = s
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Grid numbering by (X,Y)
|
|
||||||
// -----------------------------
|
|
||||||
// -- (1,1) -- (2,1) -- (3,1) --
|
|
||||||
// -- (1,2) -- (2,1) -- (3,1) --
|
|
||||||
// -----------------------------
|
|
||||||
func (p *node) newGrid(n *node) {
|
|
||||||
var newt *guiWidget
|
|
||||||
log(debugToolkit, "newGrid()", n.WidgetId, "to", n.ParentId)
|
|
||||||
|
|
||||||
newt = new(guiWidget)
|
|
||||||
|
|
||||||
c := ui.NewGrid()
|
|
||||||
newt.uiGrid = c
|
|
||||||
newt.uiControl = c
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newGroup(n *node) {
|
|
||||||
log(debugToolkit, "NewGroup()", n.Name)
|
|
||||||
|
|
||||||
newt := new(guiWidget)
|
|
||||||
|
|
||||||
log(debugToolkit, "NewGroup() create", n.Name)
|
|
||||||
|
|
||||||
g := ui.NewGroup(n.Name)
|
|
||||||
g.SetMargined(margin)
|
|
||||||
newt.uiGroup = g
|
|
||||||
newt.uiControl = g
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
var rawImage = []byte{
|
|
||||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
|
||||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
|
|
||||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
|
|
||||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
|
||||||
0x00, 0xca, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0xa5, 0x93, 0xb1, 0x0d,
|
|
||||||
0xc2, 0x40, 0x0c, 0x45, 0x1d, 0xc4, 0x14, 0x0c, 0x12, 0x41, 0x0f, 0x62,
|
|
||||||
0x12, 0x46, 0x80, 0x8a, 0x2e, 0x15, 0x30, 0x02, 0x93, 0x20, 0x68, 0x11,
|
|
||||||
0x51, 0x06, 0x61, 0x0d, 0x88, 0x2d, 0x7f, 0xdb, 0x07, 0x87, 0x08, 0xdc,
|
|
||||||
0x49, 0x91, 0x7d, 0xf6, 0xf7, 0xf3, 0x4f, 0xa4, 0x54, 0xbb, 0xeb, 0xf6,
|
|
||||||
0x41, 0x05, 0x67, 0xcc, 0xb3, 0x9b, 0xfa, 0xf6, 0x17, 0x62, 0xdf, 0xcd,
|
|
||||||
0x48, 0x00, 0x32, 0xbd, 0xa8, 0x1d, 0x72, 0xee, 0x3c, 0x47, 0x16, 0xfb,
|
|
||||||
0x5c, 0x53, 0x8d, 0x03, 0x30, 0x14, 0x84, 0xf7, 0xd5, 0x89, 0x26, 0xc7,
|
|
||||||
0x25, 0x10, 0x36, 0xe4, 0x05, 0xa2, 0x51, 0xbc, 0xc4, 0x1c, 0xc3, 0x1c,
|
|
||||||
0xed, 0x30, 0x1c, 0x8f, 0x16, 0x3f, 0x02, 0x78, 0x33, 0x20, 0x06, 0x60,
|
|
||||||
0x97, 0x70, 0xaa, 0x45, 0x7f, 0x85, 0x60, 0x5d, 0xb6, 0xf4, 0xc2, 0xc4,
|
|
||||||
0x3e, 0x0f, 0x44, 0xcd, 0x1b, 0x20, 0x90, 0x0f, 0xed, 0x85, 0xa8, 0x55,
|
|
||||||
0x05, 0x42, 0x43, 0xb4, 0x9e, 0xce, 0x71, 0xb3, 0xe8, 0x0e, 0xb4, 0xc4,
|
|
||||||
0xc3, 0x39, 0x21, 0xb7, 0x73, 0xbd, 0xe4, 0x1b, 0xe4, 0x04, 0xb6, 0xaa,
|
|
||||||
0x4f, 0x18, 0x2c, 0xee, 0x42, 0x31, 0x01, 0x84, 0xfa, 0xe0, 0xd4, 0x00,
|
|
||||||
0xdf, 0xb6, 0x83, 0xf8, 0xea, 0xc2, 0x00, 0x10, 0xfc, 0x1a, 0x05, 0x30,
|
|
||||||
0x74, 0x3b, 0xe0, 0xd1, 0x45, 0xb1, 0x83, 0xaa, 0xf4, 0x77, 0x7e, 0x02,
|
|
||||||
0x87, 0x1f, 0x42, 0x7f, 0x9e, 0x2b, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0x00,
|
|
||||||
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// make new Image using andlabs/ui
|
|
||||||
func (p *node) newImage(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
var img *ui.Image
|
|
||||||
|
|
||||||
log(debugToolkit, "rawImage() create", n.Name)
|
|
||||||
|
|
||||||
img = ui.NewImage(16, 16)
|
|
||||||
|
|
||||||
newt.uiImage = img
|
|
||||||
// newt.uiControl = img
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (a.Name == "image") {
|
|
||||||
log(true, "NewTextbox() trying to add a new image")
|
|
||||||
i := ui.NewImage(16, 16)
|
|
||||||
img, _, err := image.Decode(bytes.NewReader(rawImage))
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
nr, ok := img.(*image.RGBA)
|
|
||||||
if !ok {
|
|
||||||
i2 := image.NewRGBA(img.Bounds())
|
|
||||||
draw.Draw(i2, i2.Bounds(), img, img.Bounds().Min, draw.Src)
|
|
||||||
nr = i2
|
|
||||||
}
|
|
||||||
i.Append(nr)
|
|
||||||
t.uiBox.Append(i, true)
|
|
||||||
|
|
||||||
var img *ui.Image
|
|
||||||
var icon []byte
|
|
||||||
var imgA image.Image
|
|
||||||
|
|
||||||
icon, _ = res.ReadFile("resources/ping6.working.png")
|
|
||||||
// imgA, _, err := image.Decode(bytes.NewReader(b))
|
|
||||||
imgA, _, _ = image.Decode(icon)
|
|
||||||
img.Append(imgA)
|
|
||||||
img.Append(icon)
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,18 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newLabel(n *node) {
|
|
||||||
log(logInfo, "NewLabel()", n.Name)
|
|
||||||
|
|
||||||
newt := new(guiWidget)
|
|
||||||
c := ui.NewLabel(n.Name)
|
|
||||||
newt.uiLabel = c
|
|
||||||
newt.uiControl = c
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
witlog "go.wit.com/gui/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// various debugging flags
|
|
||||||
var logNow bool = true // useful for active development
|
|
||||||
var logError bool = true
|
|
||||||
var logWarn bool = true
|
|
||||||
var logInfo bool = false
|
|
||||||
var logVerbose bool = false
|
|
||||||
|
|
||||||
func log(a ...any) {
|
|
||||||
witlog.Where = "wit/gui/andlabs"
|
|
||||||
witlog.Log(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sleep(a ...any) {
|
|
||||||
witlog.Sleep(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func exit(a ...any) {
|
|
||||||
witlog.Exit(a...)
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
// the _ means we only need this for the init()
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
var uiMainUndef bool = true
|
|
||||||
var uiMain sync.Once
|
|
||||||
var muAction sync.Mutex
|
|
||||||
|
|
||||||
func catchActionChannel() {
|
|
||||||
log(logInfo, "catchActionChannel() START")
|
|
||||||
for {
|
|
||||||
log(logInfo, "catchActionChannel() for loop")
|
|
||||||
select {
|
|
||||||
case a := <-pluginChan:
|
|
||||||
log(logInfo, "catchActionChannel() SELECT widget id =", a.WidgetId, a.Name)
|
|
||||||
log(logInfo, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
muAction.Lock()
|
|
||||||
// TODO ui.QueueMain(f)
|
|
||||||
// TODO ui.QueueMain( func() {rawAction(a)} )
|
|
||||||
ui.QueueMain( func() {rawAction(&a)} )
|
|
||||||
// rawAction(a)
|
|
||||||
muAction.Unlock()
|
|
||||||
log(logInfo, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
|
||||||
func init() {
|
|
||||||
log(logNow, "Init() START")
|
|
||||||
log(debugToolkit, "Init()")
|
|
||||||
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
|
|
||||||
// log(debugToolkit, "init() Setting defaultBehavior = true")
|
|
||||||
setDefaultBehavior(true)
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
|
|
||||||
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
|
|
||||||
// actually, this probably breaks the macos build
|
|
||||||
go ui.Main(func() {
|
|
||||||
demoUI()
|
|
||||||
})
|
|
||||||
|
|
||||||
// andlabs = make(map[int]*andlabsT)
|
|
||||||
pluginChan = make(chan toolkit.Action, 1)
|
|
||||||
|
|
||||||
log(logNow, "Init() start channel reciever")
|
|
||||||
go catchActionChannel()
|
|
||||||
log(logNow, "Init() END")
|
|
||||||
}
|
|
|
@ -1,128 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) setText(a *toolkit.Action) {
|
|
||||||
log(debugChange, "setText() START with a.S =", a.S)
|
|
||||||
t := n.tk
|
|
||||||
if (t == nil) {
|
|
||||||
log(debugError, "setText error. tk == nil", n.Name, n.WidgetId)
|
|
||||||
actionDump(debugError, a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log(debugChange, "setText() Attempt on", n.WidgetType, "with", a.S)
|
|
||||||
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Window:
|
|
||||||
t.uiWindow.SetTitle(a.S)
|
|
||||||
case toolkit.Tab:
|
|
||||||
case toolkit.Group:
|
|
||||||
t.uiGroup.SetTitle(a.S)
|
|
||||||
case toolkit.Checkbox:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.SetText:
|
|
||||||
t.uiCheckbox.SetText(a.S)
|
|
||||||
case toolkit.Get:
|
|
||||||
n.B = t.uiCheckbox.Checked()
|
|
||||||
case toolkit.Set:
|
|
||||||
// TODO: commented out while working on chan
|
|
||||||
t.uiCheckbox.SetChecked(a.B)
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Textbox:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Set:
|
|
||||||
if (t.uiEntry != nil) {
|
|
||||||
t.uiEntry.SetText(a.S)
|
|
||||||
}
|
|
||||||
if (t.uiMultilineEntry != nil) {
|
|
||||||
t.uiMultilineEntry.SetText(a.S)
|
|
||||||
}
|
|
||||||
case toolkit.SetText:
|
|
||||||
if (t.uiEntry != nil) {
|
|
||||||
t.uiEntry.SetText(a.S)
|
|
||||||
}
|
|
||||||
if (t.uiMultilineEntry != nil) {
|
|
||||||
t.uiMultilineEntry.SetText(a.S)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Label:
|
|
||||||
t.uiLabel.SetText(a.S)
|
|
||||||
case toolkit.Button:
|
|
||||||
t.uiButton.SetText(a.S)
|
|
||||||
case toolkit.Slider:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Get:
|
|
||||||
n.I = t.uiSlider.Value()
|
|
||||||
case toolkit.Set:
|
|
||||||
t.uiSlider.SetValue(a.I)
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Spinner:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Get:
|
|
||||||
n.I = t.uiSpinbox.Value()
|
|
||||||
case toolkit.Set:
|
|
||||||
t.uiSpinbox.SetValue(a.I)
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Dropdown:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.AddText:
|
|
||||||
n.AddDropdownName(a.S)
|
|
||||||
case toolkit.Set:
|
|
||||||
var orig int
|
|
||||||
var i int = -1
|
|
||||||
var s string
|
|
||||||
orig = t.uiCombobox.Selected()
|
|
||||||
log(debugChange, "try to set the Dropdown to", a.S, "from", orig)
|
|
||||||
// try to find the string
|
|
||||||
for i, s = range t.val {
|
|
||||||
log(debugChange, "i, s", i, s)
|
|
||||||
if (a.S == s) {
|
|
||||||
t.uiCombobox.SetSelected(i)
|
|
||||||
log(debugChange, "setText() Dropdown worked.", n.S)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log(debugError, "setText() Dropdown did not find:", a.S)
|
|
||||||
// if i == -1, then there are not any things in the menu to select
|
|
||||||
if (i == -1) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// if the string was never set, then set the dropdown to the last thing added to the menu
|
|
||||||
if (orig == -1) {
|
|
||||||
t.uiCombobox.SetSelected(i)
|
|
||||||
}
|
|
||||||
case toolkit.Get:
|
|
||||||
// t.S = t.s
|
|
||||||
case toolkit.GetText:
|
|
||||||
// t.S = t.s
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Combobox:
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.AddText:
|
|
||||||
t.AddComboboxName(a.S)
|
|
||||||
case toolkit.Set:
|
|
||||||
t.uiEditableCombobox.SetText(a.S)
|
|
||||||
n.S = a.S
|
|
||||||
case toolkit.SetText:
|
|
||||||
t.uiEditableCombobox.SetText(a.S)
|
|
||||||
n.S = a.S
|
|
||||||
default:
|
|
||||||
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log(debugError, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
|
|
||||||
}
|
|
||||||
log(debugChange, "setText() END with a.S =", a.S)
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newSlider(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
|
|
||||||
s := ui.NewSlider(n.X, n.Y)
|
|
||||||
newt.uiSlider = s
|
|
||||||
newt.uiControl = s
|
|
||||||
|
|
||||||
s.OnChanged(func(spin *ui.Slider) {
|
|
||||||
n.I = newt.uiSlider.Value()
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newSpinner(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
|
|
||||||
s := ui.NewSpinbox(n.X, n.Y)
|
|
||||||
newt.uiSpinbox = s
|
|
||||||
newt.uiControl = s
|
|
||||||
|
|
||||||
s.OnChanged(func(s *ui.Spinbox) {
|
|
||||||
n.I = newt.uiSpinbox.Value()
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,60 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// import "go.wit.com/gui/toolkit"
|
|
||||||
|
|
||||||
import "github.com/andlabs/ui"
|
|
||||||
import _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
// var andlabs map[int]*andlabsT
|
|
||||||
// var callback func(int) bool
|
|
||||||
// var callback chan toolkit.Action
|
|
||||||
|
|
||||||
// It's probably a terrible idea to call this 'me'
|
|
||||||
var me config
|
|
||||||
|
|
||||||
type config struct {
|
|
||||||
rootNode *node // the base of the binary tree. it should have id == 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// stores the raw toolkit internals
|
|
||||||
type guiWidget struct {
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
|
|
||||||
// tw *toolkit.Widget
|
|
||||||
parent *guiWidget
|
|
||||||
children []*guiWidget
|
|
||||||
|
|
||||||
// used to track if a tab has a child widget yet
|
|
||||||
child bool
|
|
||||||
|
|
||||||
uiControl ui.Control
|
|
||||||
|
|
||||||
uiBox *ui.Box
|
|
||||||
uiButton *ui.Button
|
|
||||||
uiCombobox *ui.Combobox
|
|
||||||
uiCheckbox *ui.Checkbox
|
|
||||||
uiEntry *ui.Entry
|
|
||||||
uiGroup *ui.Group
|
|
||||||
uiLabel *ui.Label
|
|
||||||
uiSlider *ui.Slider
|
|
||||||
uiSpinbox *ui.Spinbox
|
|
||||||
uiTab *ui.Tab
|
|
||||||
uiWindow *ui.Window
|
|
||||||
uiMultilineEntry *ui.MultilineEntry
|
|
||||||
uiEditableCombobox *ui.EditableCombobox
|
|
||||||
uiImage *ui.Image
|
|
||||||
|
|
||||||
uiGrid *ui.Grid
|
|
||||||
gridX int
|
|
||||||
gridY int
|
|
||||||
|
|
||||||
// used as a counter to work around limitations of widgets like combobox
|
|
||||||
// this is probably fucked up and in many ways wrong because of unsafe goroutine threading
|
|
||||||
// but it's working for now due to the need for need for a correct interaction layer betten toolkits
|
|
||||||
c int
|
|
||||||
val map[int]string
|
|
||||||
|
|
||||||
// andlabs/ui only accesses widget id numbers
|
|
||||||
boxC int // how many things on in a box or how many tabs
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
|
||||||
This adds a tab
|
|
||||||
|
|
||||||
andlabs/ui is goofy in the sense that you have to determine
|
|
||||||
if the ui.Window already has a tab in it. If it does, then
|
|
||||||
you need to add this tab and not run SetChild() on the window
|
|
||||||
or instead it replaces the existing tab with the new one
|
|
||||||
|
|
||||||
I work around this by always sending a Toolkit that is a tab
|
|
||||||
once there is one. If you send a Window here, it will replace
|
|
||||||
any existing tabs rather than adding a new one
|
|
||||||
*/
|
|
||||||
func (p *node) newTab(n *node) {
|
|
||||||
var newt *guiWidget
|
|
||||||
|
|
||||||
if (p == nil) {
|
|
||||||
log(debugError, "newTab() p == nil. how the fuck does this happen?", n.WidgetId, n.ParentId)
|
|
||||||
}
|
|
||||||
if (p.WidgetType != toolkit.Window) {
|
|
||||||
log(debugError, "newTab() uiWindow == nil. I can't add a toolbar without window", n.WidgetId, n.ParentId)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
t := p.tk
|
|
||||||
|
|
||||||
log(debugToolkit, "newTab() START", n.WidgetId, n.ParentId)
|
|
||||||
|
|
||||||
if (t.uiTab == nil) {
|
|
||||||
// this means you have to make a new tab
|
|
||||||
log(debugToolkit, "newTab() GOOD. This should be the first tab:", n.WidgetId, n.ParentId)
|
|
||||||
newt = rawTab(t.uiWindow, n.Text)
|
|
||||||
t.uiTab = newt.uiTab
|
|
||||||
} else {
|
|
||||||
// this means you have to append a tab
|
|
||||||
log(debugToolkit, "newTab() GOOD. This should be an additional tab:", n.WidgetId, n.ParentId)
|
|
||||||
if (n.WidgetType == toolkit.Tab) {
|
|
||||||
// andlabs doesn't have multiple tab widgets so make a fake one?
|
|
||||||
// this makes a guiWidget internal structure with the parent values
|
|
||||||
newt = new(guiWidget)
|
|
||||||
newt.uiWindow = t.uiWindow
|
|
||||||
newt.uiTab = t.uiTab
|
|
||||||
} else {
|
|
||||||
newt = t.appendTab(n.Text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
}
|
|
||||||
|
|
||||||
// This sets _all_ the tabs to Margin = true
|
|
||||||
//
|
|
||||||
// TODO: do proper tab tracking (will be complicated). low priority
|
|
||||||
func tabSetMargined(tab *ui.Tab, b bool) {
|
|
||||||
c := tab.NumPages()
|
|
||||||
for i := 0; i < c; i++ {
|
|
||||||
log(debugToolkit, "SetMargined", i, b)
|
|
||||||
tab.SetMargined(i, b)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func rawTab(w *ui.Window, name string) *guiWidget {
|
|
||||||
var newt guiWidget
|
|
||||||
log(debugToolkit, "rawTab() START", name)
|
|
||||||
|
|
||||||
if (w == nil) {
|
|
||||||
log(debugError, "UiWindow == nil. I can't add a tab without a window")
|
|
||||||
log(debugError, "UiWindow == nil. I can't add a tab without a window")
|
|
||||||
log(debugError, "UiWindow == nil. I can't add a tab without a window")
|
|
||||||
// sleep(1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
tab := ui.NewTab()
|
|
||||||
w.SetChild(tab)
|
|
||||||
newt.uiTab = tab
|
|
||||||
newt.uiControl = tab
|
|
||||||
log(debugToolkit, "rawTab() END", name)
|
|
||||||
return &newt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) appendTab(name string) *guiWidget {
|
|
||||||
var newT guiWidget
|
|
||||||
log(debugToolkit, "appendTab() ADD", name)
|
|
||||||
|
|
||||||
if (t.uiTab == nil) {
|
|
||||||
log(debugToolkit, "UiWindow == nil. I can't add a widget without a place to put it")
|
|
||||||
panic("should never have happened. wit/gui/toolkit has ui.Tab == nil")
|
|
||||||
}
|
|
||||||
log(debugToolkit, "appendTab() START name =", name)
|
|
||||||
|
|
||||||
var hbox *ui.Box
|
|
||||||
if (defaultBehavior) {
|
|
||||||
hbox = ui.NewHorizontalBox()
|
|
||||||
} else {
|
|
||||||
if (bookshelf) {
|
|
||||||
hbox = ui.NewHorizontalBox()
|
|
||||||
} else {
|
|
||||||
hbox = ui.NewVerticalBox()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hbox.SetPadded(padded)
|
|
||||||
t.uiTab.Append(name, hbox)
|
|
||||||
|
|
||||||
newT.uiWindow = t.uiWindow
|
|
||||||
newT.uiTab = t.uiTab
|
|
||||||
newT.uiBox = hbox
|
|
||||||
return &newT
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (p *node) newTextbox(n *node) {
|
|
||||||
newt := new(guiWidget)
|
|
||||||
|
|
||||||
if (n.X == 1) {
|
|
||||||
e := ui.NewEntry()
|
|
||||||
newt.uiEntry = e
|
|
||||||
newt.uiControl = e
|
|
||||||
|
|
||||||
e.OnChanged(func(spin *ui.Entry) {
|
|
||||||
n.S = spin.Text()
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
e := ui.NewNonWrappingMultilineEntry()
|
|
||||||
newt.uiMultilineEntry = e
|
|
||||||
newt.uiControl = e
|
|
||||||
|
|
||||||
e.OnChanged(func(spin *ui.MultilineEntry) {
|
|
||||||
n.S = spin.Text()
|
|
||||||
n.doUserEvent()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
n.tk = newt
|
|
||||||
p.place(n)
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Example showing how to update the UI using the QueueMain function
|
|
||||||
// especially if the update is coming from another goroutine
|
|
||||||
//
|
|
||||||
// see QueueMain in 'main.go' for detailed description
|
|
||||||
|
|
||||||
var count int
|
|
||||||
|
|
||||||
func demoUI() {
|
|
||||||
mainWindow := ui.NewWindow("libui Updating UI", 640, 480, true)
|
|
||||||
mainWindow.OnClosing(func(*ui.Window) bool {
|
|
||||||
ui.Quit()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
ui.OnShouldQuit(func() bool {
|
|
||||||
mainWindow.Destroy()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
|
|
||||||
vbContainer := ui.NewVerticalBox()
|
|
||||||
vbContainer.SetPadded(true)
|
|
||||||
|
|
||||||
inputGroup := ui.NewGroup("Input")
|
|
||||||
inputGroup.SetMargined(true)
|
|
||||||
|
|
||||||
vbInput := ui.NewVerticalBox()
|
|
||||||
vbInput.SetPadded(true)
|
|
||||||
|
|
||||||
inputForm := ui.NewForm()
|
|
||||||
inputForm.SetPadded(true)
|
|
||||||
|
|
||||||
message := ui.NewEntry()
|
|
||||||
message.SetText("Hello World")
|
|
||||||
inputForm.Append("What message do you want to show?", message, false)
|
|
||||||
|
|
||||||
showMessageButton := ui.NewButton("Show message")
|
|
||||||
clearMessageButton := ui.NewButton("Clear message")
|
|
||||||
|
|
||||||
vbInput.Append(inputForm, false)
|
|
||||||
vbInput.Append(showMessageButton, false)
|
|
||||||
vbInput.Append(clearMessageButton, false)
|
|
||||||
|
|
||||||
inputGroup.SetChild(vbInput)
|
|
||||||
|
|
||||||
messageGroup := ui.NewGroup("Message")
|
|
||||||
messageGroup.SetMargined(true)
|
|
||||||
|
|
||||||
vbMessage := ui.NewVerticalBox()
|
|
||||||
vbMessage.SetPadded(true)
|
|
||||||
|
|
||||||
messageLabel := ui.NewLabel("")
|
|
||||||
|
|
||||||
vbMessage.Append(messageLabel, false)
|
|
||||||
|
|
||||||
messageGroup.SetChild(vbMessage)
|
|
||||||
|
|
||||||
countGroup := ui.NewGroup("Counter")
|
|
||||||
countGroup.SetMargined(true)
|
|
||||||
|
|
||||||
vbCounter := ui.NewVerticalBox()
|
|
||||||
vbCounter.SetPadded(true)
|
|
||||||
|
|
||||||
countLabel := ui.NewLabel("blah")
|
|
||||||
|
|
||||||
vbCounter.Append(countLabel, false)
|
|
||||||
countGroup.SetChild(vbCounter)
|
|
||||||
|
|
||||||
vbContainer.Append(inputGroup, false)
|
|
||||||
vbContainer.Append(messageGroup, false)
|
|
||||||
vbContainer.Append(countGroup, false)
|
|
||||||
|
|
||||||
mainWindow.SetChild(vbContainer)
|
|
||||||
|
|
||||||
showMessageButton.OnClicked(func(*ui.Button) {
|
|
||||||
// Update the UI directly as it is called from the main thread
|
|
||||||
messageLabel.SetText(message.Text())
|
|
||||||
})
|
|
||||||
|
|
||||||
clearMessageButton.OnClicked(func(*ui.Button) {
|
|
||||||
// Update the UI directly as it is called from the main thread
|
|
||||||
messageLabel.SetText("")
|
|
||||||
})
|
|
||||||
|
|
||||||
// this is messed up.
|
|
||||||
// mainWindow.Show()
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func main() {
|
|
||||||
ui.Main(setupUI)
|
|
||||||
}
|
|
||||||
*/
|
|
|
@ -1,29 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is specific to the nocui toolkit
|
|
||||||
func initWidget(n *node) *guiWidget {
|
|
||||||
var w *guiWidget
|
|
||||||
w = new(guiWidget)
|
|
||||||
// Set(w, "default")
|
|
||||||
|
|
||||||
if n.WidgetType == toolkit.Root {
|
|
||||||
log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
|
||||||
n.WidgetId = 0
|
|
||||||
me.rootNode = n
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.WidgetType == toolkit.Box) {
|
|
||||||
if (n.B) {
|
|
||||||
n.horizontal = true
|
|
||||||
} else {
|
|
||||||
n.horizontal = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return w
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
|
|
||||||
ui.MsgBox(t.uiWindow, msg1, msg2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *guiWidget) ErrorWindow(msg1 string, msg2 string) {
|
|
||||||
ui.MsgBoxError(t.uiWindow, msg1, msg2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newWindow(n *node) {
|
|
||||||
var newt *guiWidget
|
|
||||||
|
|
||||||
newt = new(guiWidget)
|
|
||||||
|
|
||||||
// menubar bool is if the OS defined border on the window should be used
|
|
||||||
win := ui.NewWindow(n.Name, n.X, n.Y, menubar)
|
|
||||||
win.SetBorderless(canvas)
|
|
||||||
win.SetMargined(margin)
|
|
||||||
win.OnClosing(func(*ui.Window) bool {
|
|
||||||
n.doUserEvent()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
newt.uiWindow = win
|
|
||||||
newt.uiControl = win
|
|
||||||
|
|
||||||
n.tk = newt
|
|
||||||
win.Show()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) SetWindowTitle(title string) {
|
|
||||||
log(debugToolkit, "toolkit NewWindow", n.Text, "title", title)
|
|
||||||
win := n.tk.uiWindow
|
|
||||||
if (win == nil) {
|
|
||||||
log(debugError, "Error: no window", n.WidgetId)
|
|
||||||
} else {
|
|
||||||
win.SetTitle(title)
|
|
||||||
log(debugToolkit, "Setting the window title", title)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,15 +0,0 @@
|
||||||
all: plugin
|
|
||||||
ldd ../gocui.so
|
|
||||||
|
|
||||||
goget:
|
|
||||||
go get -v -t -u
|
|
||||||
|
|
||||||
plugin:
|
|
||||||
go build -v -x -buildmode=plugin -o ../gocui.so
|
|
||||||
|
|
||||||
objdump:
|
|
||||||
objdump -t ../gocui.so |less
|
|
||||||
|
|
||||||
log:
|
|
||||||
reset
|
|
||||||
tail -f /tmp/witgui.* /tmp/guilogfile
|
|
|
@ -1,78 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
var fakeStartWidth int = me.FakeW
|
|
||||||
var fakeStartHeight int = me.TabH + me.FramePadH
|
|
||||||
// setup fake labels for non-visible things off screen
|
|
||||||
func (n *node) setFake() {
|
|
||||||
w := n.tk
|
|
||||||
w.isFake = true
|
|
||||||
|
|
||||||
n.gocuiSetWH(fakeStartWidth, fakeStartHeight)
|
|
||||||
|
|
||||||
fakeStartHeight += w.gocuiSize.Height()
|
|
||||||
// TODO: use the actual max hight of the terminal window
|
|
||||||
if (fakeStartHeight > 24) {
|
|
||||||
fakeStartHeight = me.TabH
|
|
||||||
fakeStartWidth += me.FakeW
|
|
||||||
}
|
|
||||||
if (logInfo) {
|
|
||||||
n.showView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the widget start width & height
|
|
||||||
func (n *node) addWidget() {
|
|
||||||
nw := n.tk
|
|
||||||
log(logInfo, "setStartWH() w.id =", n.WidgetId, "n.name", n.Name)
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Root:
|
|
||||||
log(logInfo, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.Name)
|
|
||||||
nw.color = &colorRoot
|
|
||||||
n.setFake()
|
|
||||||
return
|
|
||||||
case toolkit.Flag:
|
|
||||||
nw.color = &colorFlag
|
|
||||||
n.setFake()
|
|
||||||
return
|
|
||||||
case toolkit.Window:
|
|
||||||
nw.frame = false
|
|
||||||
nw.color = &colorWindow
|
|
||||||
// redoWindows(0,0)
|
|
||||||
return
|
|
||||||
case toolkit.Tab:
|
|
||||||
nw.color = &colorTab
|
|
||||||
// redoWindows(0,0)
|
|
||||||
return
|
|
||||||
case toolkit.Button:
|
|
||||||
nw.color = &colorButton
|
|
||||||
case toolkit.Box:
|
|
||||||
nw.color = &colorBox
|
|
||||||
nw.isFake = true
|
|
||||||
n.setFake()
|
|
||||||
return
|
|
||||||
case toolkit.Grid:
|
|
||||||
nw.color = &colorGrid
|
|
||||||
nw.isFake = true
|
|
||||||
n.setFake()
|
|
||||||
return
|
|
||||||
case toolkit.Group:
|
|
||||||
nw.color = &colorGroup
|
|
||||||
nw.frame = false
|
|
||||||
return
|
|
||||||
case toolkit.Label:
|
|
||||||
nw.color = &colorLabel
|
|
||||||
nw.frame = false
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
if n.IsCurrent() {
|
|
||||||
n.updateCurrent()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
n.showWidgetPlacement(logInfo, "addWidget()")
|
|
||||||
}
|
|
|
@ -1,33 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) setCheckbox(b bool) {
|
|
||||||
w := n.tk
|
|
||||||
if (n.WidgetType != toolkit.Checkbox) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (b) {
|
|
||||||
n.B = b
|
|
||||||
n.Text = "X " + n.Name
|
|
||||||
} else {
|
|
||||||
n.B = b
|
|
||||||
n.Text = " " + n.Name
|
|
||||||
}
|
|
||||||
t := len(n.Text) + 1
|
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + t
|
|
||||||
|
|
||||||
// w.realWidth = w.gocuiSize.Width() + me.PadW
|
|
||||||
// w.realHeight = w.gocuiSize.Height() + me.PadH
|
|
||||||
|
|
||||||
// if w.frame {
|
|
||||||
// w.realWidth += me.FramePadW
|
|
||||||
// w.realHeight += me.FramePadH
|
|
||||||
// }
|
|
||||||
|
|
||||||
n.deleteView()
|
|
||||||
n.showView()
|
|
||||||
}
|
|
|
@ -1,356 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// set isCurrent = false everywhere
|
|
||||||
func unsetCurrent(n *node) {
|
|
||||||
w := n.tk
|
|
||||||
w.isCurrent = false
|
|
||||||
|
|
||||||
if n.WidgetType == toolkit.Tab {
|
|
||||||
// n.tk.color = &colorTab
|
|
||||||
// n.setColor()
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
unsetCurrent(child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// when adding a new widget, this will update the display
|
|
||||||
// of the current widgets if that widget is supposed
|
|
||||||
// to be in current display
|
|
||||||
func (n *node) updateCurrent() {
|
|
||||||
log("updateCurrent()", n.Name)
|
|
||||||
if n.WidgetType == toolkit.Tab {
|
|
||||||
if n.IsCurrent() {
|
|
||||||
// n.tk.color = &colorActiveT
|
|
||||||
n.setColor(&colorActiveT)
|
|
||||||
n.hideView()
|
|
||||||
n.showView()
|
|
||||||
setCurrentTab(n)
|
|
||||||
} else {
|
|
||||||
// n.tk.color = &colorTab
|
|
||||||
// n.setColor()
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n.WidgetType == toolkit.Window {
|
|
||||||
if n.IsCurrent() {
|
|
||||||
// setCurrentWindow(n)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if n.WidgetType == toolkit.Root {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.parent.updateCurrent()
|
|
||||||
}
|
|
||||||
|
|
||||||
// shows the widgets in a window
|
|
||||||
func setCurrentWindow(n *node) {
|
|
||||||
if n.IsCurrent() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w := n.tk
|
|
||||||
if n.WidgetType != toolkit.Window {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
unsetCurrent(me.rootNode)
|
|
||||||
|
|
||||||
if n.hasTabs {
|
|
||||||
// set isCurrent = true on the first tab
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.tk.isCurrent = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
w.isCurrent = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// shows the widgets in a tab
|
|
||||||
func setCurrentTab(n *node) {
|
|
||||||
w := n.tk
|
|
||||||
if n.WidgetType != toolkit.Tab {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
unsetCurrent(me.rootNode)
|
|
||||||
w.isCurrent = true
|
|
||||||
p := n.parent.tk
|
|
||||||
p.isCurrent = true
|
|
||||||
log("setCurrent()", n.Name)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) doWidgetClick() {
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Root:
|
|
||||||
// THIS IS THE BEGINING OF THE LAYOUT
|
|
||||||
log("doWidgetClick()", n.Name)
|
|
||||||
redoWindows(0,0)
|
|
||||||
case toolkit.Flag:
|
|
||||||
log("doWidgetClick() FLAG widget name =", n.Name)
|
|
||||||
log("doWidgetClick() if this is the dropdown menu, handle it here?")
|
|
||||||
case toolkit.Window:
|
|
||||||
if (me.currentWindow == n) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (me.currentWindow != nil) {
|
|
||||||
unsetCurrent(me.currentWindow)
|
|
||||||
me.currentWindow.setColor(&colorWindow)
|
|
||||||
me.currentWindow.hideWidgets()
|
|
||||||
}
|
|
||||||
n.hideWidgets()
|
|
||||||
me.currentWindow = n
|
|
||||||
// setCurrentWindow(n) // probably delete this
|
|
||||||
n.setColor(&colorActiveW)
|
|
||||||
n.redoTabs(me.TabW, me.TabH)
|
|
||||||
for _, child := range n.children {
|
|
||||||
if (child.currentTab == true) {
|
|
||||||
log(true, "FOUND CURRENT TAB", child.Name)
|
|
||||||
setCurrentTab(child)
|
|
||||||
child.placeWidgets(me.RawW, me.RawH)
|
|
||||||
child.showWidgets()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* FIXME: redo this
|
|
||||||
if ! n.hasTabs {
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
case toolkit.Tab:
|
|
||||||
if (n.IsCurrent()) {
|
|
||||||
return // do nothing if you reclick on the already selected tab
|
|
||||||
}
|
|
||||||
// find the window and disable the active tab
|
|
||||||
p := n.parent
|
|
||||||
if (p != nil) {
|
|
||||||
p.hideWidgets()
|
|
||||||
p.redoTabs(me.TabW, me.TabH)
|
|
||||||
unsetCurrent(p)
|
|
||||||
for _, child := range p.children {
|
|
||||||
if child.WidgetType == toolkit.Tab {
|
|
||||||
child.setColor(&colorTab)
|
|
||||||
n.currentTab = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
n.currentTab = true
|
|
||||||
n.setColor(&colorActiveT)
|
|
||||||
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:
|
|
||||||
newR := n.realGocuiSize()
|
|
||||||
|
|
||||||
// w,h := n.logicalSize()
|
|
||||||
// w := newR.w1 - newR.w0
|
|
||||||
// h := newR.h1 - newR.h0
|
|
||||||
|
|
||||||
n.placeGrid(newR.w0, newR.h0)
|
|
||||||
n.showWidgets()
|
|
||||||
case toolkit.Box:
|
|
||||||
// w.showWidgetPlacement(logNow, "drawTree()")
|
|
||||||
if (n.horizontal) {
|
|
||||||
log("BOX IS HORIZONTAL", n.Name)
|
|
||||||
} else {
|
|
||||||
log("BOX IS VERTICAL", n.Name)
|
|
||||||
}
|
|
||||||
// n.placeWidgets()
|
|
||||||
n.toggleTree()
|
|
||||||
case toolkit.Button:
|
|
||||||
n.doUserEvent()
|
|
||||||
case toolkit.Dropdown:
|
|
||||||
log(true, "do the dropdown here")
|
|
||||||
if (me.ddview == nil) {
|
|
||||||
me.ddview = addDropdown()
|
|
||||||
tk := me.ddview.tk
|
|
||||||
tk.gocuiSize.w0 = 20
|
|
||||||
tk.gocuiSize.w1 = 40
|
|
||||||
tk.gocuiSize.h0 = 10
|
|
||||||
tk.gocuiSize.h1 = 25
|
|
||||||
tk.v, _ = me.baseGui.SetView("ddview",
|
|
||||||
tk.gocuiSize.w0,
|
|
||||||
tk.gocuiSize.h0,
|
|
||||||
tk.gocuiSize.w1,
|
|
||||||
tk.gocuiSize.h1, 0)
|
|
||||||
if (tk.v == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tk.v.Wrap = true
|
|
||||||
tk.v.Frame = true
|
|
||||||
tk.v.Clear()
|
|
||||||
fmt.Fprint(tk.v, "example.com\nwit.com")
|
|
||||||
me.ddview.SetVisible(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log(true, "doWidgetClick() visible =", me.ddview.Visible())
|
|
||||||
if (me.ddview.Visible()) {
|
|
||||||
me.ddview.SetVisible(false)
|
|
||||||
me.baseGui.DeleteView("ddview")
|
|
||||||
me.ddview.tk.v = nil
|
|
||||||
} else {
|
|
||||||
var dnsList string
|
|
||||||
for i, s := range n.vals {
|
|
||||||
log(logNow, "AddText()", n.Name, i, s)
|
|
||||||
dnsList += s + "\n"
|
|
||||||
}
|
|
||||||
me.ddNode = n
|
|
||||||
log(logNow, "new dns list should be set to:", dnsList)
|
|
||||||
me.ddview.Text = dnsList
|
|
||||||
me.ddview.SetText(dnsList)
|
|
||||||
me.ddview.SetVisible(true)
|
|
||||||
}
|
|
||||||
for i, s := range n.vals {
|
|
||||||
log(logNow, "AddText()", n.Name, i, s)
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var toggle bool = true
|
|
||||||
func (n *node) toggleTree() {
|
|
||||||
if (toggle) {
|
|
||||||
n.drawTree(toggle)
|
|
||||||
toggle = false
|
|
||||||
} else {
|
|
||||||
n.hideWidgets()
|
|
||||||
toggle = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// display the widgets in the binary tree
|
|
||||||
func (n *node) drawTree(draw bool) {
|
|
||||||
w := n.tk
|
|
||||||
if (w == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.showWidgetPlacement(logNow, "drawTree()")
|
|
||||||
if (draw) {
|
|
||||||
// w.textResize()
|
|
||||||
n.showView()
|
|
||||||
} else {
|
|
||||||
n.deleteView()
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.drawTree(draw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func click(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
// var l string
|
|
||||||
// var err error
|
|
||||||
|
|
||||||
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)
|
|
||||||
if (n.Name == "DropBox") {
|
|
||||||
log(logNow, "click() this is the dropdown menu. set a flag here what did I click? where is the mouse?")
|
|
||||||
log(logNow, "click() set a global dropdown clicked flag=true here")
|
|
||||||
me.ddClicked = true
|
|
||||||
}
|
|
||||||
n.doWidgetClick()
|
|
||||||
} else {
|
|
||||||
log(logNow, "click() could not find node name =", v.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := g.SetCurrentView(v.Name()); err != nil {
|
|
||||||
log(logNow, "click() END err =", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log(logVerbose, "click() END")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findUnderMouse() *node {
|
|
||||||
var found *node
|
|
||||||
var widgets []*node
|
|
||||||
var f func (n *node)
|
|
||||||
w, h := me.baseGui.MousePosition()
|
|
||||||
|
|
||||||
// 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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (n == me.ddview) {
|
|
||||||
log(true, "findUnderMouse() found ddview")
|
|
||||||
if n.Visible() {
|
|
||||||
log(true, "findUnderMouse() and ddview is visable. hide it here. TODO: find highlighted row")
|
|
||||||
found = n
|
|
||||||
// find the actual value here and set the dropdown widget
|
|
||||||
me.baseGui.DeleteView("ddview")
|
|
||||||
} else {
|
|
||||||
log(true, "findUnderMouse() I was lying, actually it's not found")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
f(child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f(me.rootNode)
|
|
||||||
// widgets has everything that matches
|
|
||||||
// TODO: pop up menu with a list of them
|
|
||||||
for _, n := range widgets {
|
|
||||||
//log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
|
|
||||||
n.showWidgetPlacement(logNow, "findUnderMouse() FOUND")
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
if (me.ctrlDown == nil) {
|
|
||||||
setupCtrlDownWidget()
|
|
||||||
me.ctrlDown.Text = found.Name
|
|
||||||
me.ctrlDown.tk.cuiName = "ctrlDown"
|
|
||||||
// me.ctrlDown.parent = me.rootNode
|
|
||||||
}
|
|
||||||
cd := me.ctrlDown.tk
|
|
||||||
if (found == nil) {
|
|
||||||
found = me.rootNode
|
|
||||||
}
|
|
||||||
me.ctrlDown.Text = found.Name
|
|
||||||
newR := found.realGocuiSize()
|
|
||||||
cd.gocuiSize.w0 = newR.w0
|
|
||||||
cd.gocuiSize.h0 = newR.h0
|
|
||||||
cd.gocuiSize.w1 = newR.w1
|
|
||||||
cd.gocuiSize.h1 = newR.h1
|
|
||||||
if me.ctrlDown.Visible() {
|
|
||||||
me.ctrlDown.hideView()
|
|
||||||
} else {
|
|
||||||
me.ctrlDown.showView()
|
|
||||||
}
|
|
||||||
me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,117 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"math/rand"
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
//w.v.SelBgColor = gocui.ColorCyan
|
|
||||||
//color.go: w.v.SelFgColor = gocui.ColorBlack
|
|
||||||
//color.go: w.v.BgColor = gocui.ColorGreen
|
|
||||||
|
|
||||||
type colorT struct {
|
|
||||||
frame gocui.Attribute
|
|
||||||
fg gocui.Attribute
|
|
||||||
bg gocui.Attribute
|
|
||||||
selFg gocui.Attribute
|
|
||||||
selBg gocui.Attribute
|
|
||||||
name string
|
|
||||||
}
|
|
||||||
|
|
||||||
var none gocui.Attribute = gocui.AttrNone
|
|
||||||
var lightPurple gocui.Attribute = gocui.GetColor("#DDDDDD") // light purple
|
|
||||||
var darkPurple gocui.Attribute = gocui.GetColor("#FFAA55") // Dark Purple
|
|
||||||
var heavyPurple gocui.Attribute = gocui.GetColor("#88AA55") // heavy purple
|
|
||||||
var powdererBlue gocui.Attribute = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
|
|
||||||
var superLightGrey gocui.Attribute = gocui.GetColor("#55AAFF") // super light grey
|
|
||||||
|
|
||||||
// Standard defined colors from gocui:
|
|
||||||
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
|
|
||||||
|
|
||||||
// v.BgColor = gocui.GetColor("#111111") // crazy red
|
|
||||||
// v.BgColor = gocui.GetColor("#FF9911") // heavy red
|
|
||||||
// v.SelBgColor = gocui.GetColor("#FFEE11") // blood red
|
|
||||||
|
|
||||||
// v.BgColor = gocui.GetColor("#55AAFF") // super light grey
|
|
||||||
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
|
|
||||||
|
|
||||||
// Normal Text On mouseover
|
|
||||||
// Widget Frame Text background Text background
|
|
||||||
var colorWindow colorT = colorT{ none , gocui.ColorBlue, none , none , powdererBlue , "normal window"}
|
|
||||||
var colorActiveW colorT = colorT{ none , none , powdererBlue , none , powdererBlue , "active window"}
|
|
||||||
|
|
||||||
var colorTab colorT = colorT{gocui.ColorBlue, gocui.ColorBlue, none , none , powdererBlue , "normal tab"}
|
|
||||||
var colorActiveT colorT = colorT{gocui.ColorBlue, none , powdererBlue , none , powdererBlue , "active tab"}
|
|
||||||
|
|
||||||
var colorButton colorT = colorT{gocui.ColorGreen, none , gocui.ColorWhite, gocui.ColorGreen, gocui.ColorBlack, "normal button"}
|
|
||||||
var colorLabel colorT = colorT{ none , none , superLightGrey , none , superLightGrey , "normal label"}
|
|
||||||
var colorGroup colorT = colorT{ none , none , superLightGrey , none , superLightGrey , "normal group"}
|
|
||||||
|
|
||||||
// widget debugging colors. these widgets aren't displayed unless you are debugging
|
|
||||||
var colorRoot colorT = colorT{gocui.ColorRed , none , powdererBlue , none , gocui.ColorBlue, "debug root"}
|
|
||||||
var colorFlag colorT = colorT{gocui.ColorRed , none , powdererBlue , none , gocui.ColorGreen, "debug flag"}
|
|
||||||
var colorBox colorT = colorT{gocui.ColorRed , none , lightPurple , none , gocui.ColorCyan, "debug box"}
|
|
||||||
var colorGrid colorT = colorT{gocui.ColorRed , none , lightPurple , none , gocui.ColorRed, "debug grid"}
|
|
||||||
var colorNone colorT = colorT{ none , none , none , none , none , "debug none"}
|
|
||||||
|
|
||||||
// actually sets the colors for the gocui element
|
|
||||||
// the user will see the colors change when this runs
|
|
||||||
// TODO: add black/white only flag for ttyS0
|
|
||||||
// TODO: or fix kvm/qemu serial console & SIGWINCH.
|
|
||||||
// TODO: and minicom and uboot and 5 million other things.
|
|
||||||
// TODO: maybe enough of us could actually do that if we made it a goal.
|
|
||||||
// TODO: start with riscv boards and fix it universally there
|
|
||||||
// TODO: so just a small little 'todo' item here
|
|
||||||
func (n *node) setColor(newColor *colorT) {
|
|
||||||
tk := n.tk
|
|
||||||
if (tk.color == newColor) {
|
|
||||||
// nothing to do since the colors have nto changed
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tk.color = newColor
|
|
||||||
if (tk.v == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (tk.color == nil) {
|
|
||||||
log(true, "Set the node to color = nil")
|
|
||||||
tk.color = &colorNone
|
|
||||||
}
|
|
||||||
log(true, "Set the node to color =", tk.color.name)
|
|
||||||
n.recreateView()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) setDefaultWidgetColor() {
|
|
||||||
n.showView()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) setDefaultHighlight() {
|
|
||||||
w := n.tk
|
|
||||||
if (w.v == nil) {
|
|
||||||
log(logError, "SetColor() failed on view == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w.v.SelBgColor = gocui.ColorGreen
|
|
||||||
w.v.SelFgColor = gocui.ColorBlack
|
|
||||||
}
|
|
||||||
|
|
||||||
func randColor() gocui.Attribute {
|
|
||||||
colors := []string{"Green", "#FFAA55", "Yellow", "Blue", "Red", "Black", "White"}
|
|
||||||
i := rand.Intn(len(colors))
|
|
||||||
log("randColor() i =", i)
|
|
||||||
return gocui.GetColor(colors[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) redoColor(draw bool) {
|
|
||||||
w := n.tk
|
|
||||||
if (w == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
sleep(.05)
|
|
||||||
n.setDefaultHighlight()
|
|
||||||
n.setDefaultWidgetColor()
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.redoColor(draw)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../nocui/common.go
|
|
|
@ -1,73 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) dumpTree(draw bool) {
|
|
||||||
w := n.tk
|
|
||||||
if (w == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.showWidgetPlacement(logNow, "dumpTree()")
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.dumpTree(draw)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) showWidgetPlacement(b bool, s string) {
|
|
||||||
if (n == nil) {
|
|
||||||
log(logError, "WTF w == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
w := n.tk
|
|
||||||
|
|
||||||
var s1 string
|
|
||||||
var pId int
|
|
||||||
if (n.parent == nil) {
|
|
||||||
log(logVerbose, "showWidgetPlacement() parent == nil", n.WidgetId, w.cuiName)
|
|
||||||
pId = 0
|
|
||||||
} else {
|
|
||||||
pId = n.parent.WidgetId
|
|
||||||
}
|
|
||||||
s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", n.WidgetId, pId)
|
|
||||||
if n.Visible() {
|
|
||||||
s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
|
|
||||||
w.gocuiSize.Width(), w.gocuiSize.Height(),
|
|
||||||
w.gocuiSize.w0, w.gocuiSize.h0, w.gocuiSize.w1, w.gocuiSize.h1)
|
|
||||||
} else {
|
|
||||||
s1 += fmt.Sprintf(" ")
|
|
||||||
}
|
|
||||||
if (n.parent != nil) {
|
|
||||||
if (n.parent.WidgetType == toolkit.Grid) {
|
|
||||||
s1 += fmt.Sprintf("At(%2d,%2d) ", n.AtW, n.AtH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tmp := "." + n.Name + "."
|
|
||||||
log(b, s1, s, n.WidgetType, ",", tmp) // , "text=", w.text)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) dumpWidget(pad string) {
|
|
||||||
log(true, "node:", pad, n.WidgetId, "At(", n.AtW, n.AtH, ") ,", n.WidgetType, ", n.Name =", n.Name, ", n.Text =", n.Text)
|
|
||||||
}
|
|
||||||
|
|
||||||
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,58 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"io"
|
|
||||||
"errors"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FakeFile struct {
|
|
||||||
reader *bytes.Reader
|
|
||||||
buffer *bytes.Buffer
|
|
||||||
offset int64
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeFile) Read(p []byte) (n int, err error) {
|
|
||||||
n, err = f.reader.ReadAt(p, f.offset)
|
|
||||||
f.offset += int64(n)
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeFile) Write(p []byte) (n int, err error) {
|
|
||||||
n, err = f.buffer.Write(p)
|
|
||||||
f.offset += int64(n)
|
|
||||||
f.reader.Reset(f.buffer.Bytes())
|
|
||||||
return n, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeFile) Seek(offset int64, whence int) (int64, error) {
|
|
||||||
newOffset := f.offset
|
|
||||||
|
|
||||||
switch whence {
|
|
||||||
case io.SeekStart:
|
|
||||||
newOffset = offset
|
|
||||||
case io.SeekCurrent:
|
|
||||||
newOffset += offset
|
|
||||||
case io.SeekEnd:
|
|
||||||
newOffset = int64(f.buffer.Len()) + offset
|
|
||||||
default:
|
|
||||||
return 0, errors.New("Seek: whence not at start,current or end")
|
|
||||||
}
|
|
||||||
// never can get here right?
|
|
||||||
|
|
||||||
if newOffset < 0 {
|
|
||||||
return 0, errors.New("Seek: offset < 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
f.offset = newOffset
|
|
||||||
return f.offset, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeFile() *FakeFile {
|
|
||||||
buf := &bytes.Buffer{}
|
|
||||||
return &FakeFile{
|
|
||||||
reader: bytes.NewReader(buf.Bytes()),
|
|
||||||
buffer: buf,
|
|
||||||
offset: 0,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,100 +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"
|
|
||||||
"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", 5, 10, 5, 10, 0) // x0, x1, y1, y2, overlap
|
|
||||||
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
|
|
||||||
}
|
|
|
@ -1,71 +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"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
)
|
|
||||||
|
|
||||||
var helpText []string = []string{"KEYBINDINGS",
|
|
||||||
"",
|
|
||||||
"?: toggle help",
|
|
||||||
"d: toggle debugging",
|
|
||||||
"r: redraw widgets",
|
|
||||||
"s/h: show/hide all widgets",
|
|
||||||
"L: list all widgets",
|
|
||||||
"M: list all widgets positions",
|
|
||||||
"q: quit()",
|
|
||||||
"p: panic()",
|
|
||||||
"o: show Stdout",
|
|
||||||
"l: log to /tmp/witgui.log",
|
|
||||||
"Ctrl-D: Toggle Debugging",
|
|
||||||
"Ctrl-V: Toggle Verbose Debugging",
|
|
||||||
"Ctrl-C: Exit",
|
|
||||||
"",
|
|
||||||
}
|
|
||||||
|
|
||||||
func hidehelplayout() {
|
|
||||||
me.baseGui.DeleteView("help")
|
|
||||||
// n.deleteView()
|
|
||||||
// child.hideFake()
|
|
||||||
}
|
|
||||||
|
|
||||||
func helplayout() error {
|
|
||||||
g := me.baseGui
|
|
||||||
var err error
|
|
||||||
maxX, _ := g.Size()
|
|
||||||
|
|
||||||
var newW int = 8
|
|
||||||
for _, s := range(helpText) {
|
|
||||||
if newW < len(s) {
|
|
||||||
newW = len(s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
help, err := g.SetView("help", maxX-(newW + me.FramePadW), 0, maxX-1, len(helpText) + me.FramePadH, 0)
|
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
help.SelBgColor = gocui.ColorGreen
|
|
||||||
help.SelFgColor = gocui.ColorBlack
|
|
||||||
// fmt.Fprintln(help, "Enter: Click Button")
|
|
||||||
// fmt.Fprintln(help, "Tab/Space: Switch Buttons")
|
|
||||||
// fmt.Fprintln(help, "Backspace: Delete Button")
|
|
||||||
// fmt.Fprintln(help, "Arrow keys: Move Button")
|
|
||||||
|
|
||||||
fmt.Fprintln(help, strings.Join(helpText, "\n"))
|
|
||||||
|
|
||||||
if _, err := g.SetCurrentView("help"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
me.helpLabel = help
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,175 +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 (
|
|
||||||
"os"
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func defaultKeybindings(g *gocui.Gui) error {
|
|
||||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, n := range []string{"but1", "but2", "help", "but3"} {
|
|
||||||
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// mouseDown() runs whenever you click on an unknown view (?)
|
|
||||||
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// if err := g.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click); err != nil {
|
|
||||||
// return err
|
|
||||||
// }
|
|
||||||
/*
|
|
||||||
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, msgDown); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
addDebugKeys(g)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func addDebugKeys(g *gocui.Gui) {
|
|
||||||
// show debugging buttons
|
|
||||||
g.SetKeybinding("", 'd', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
fakeStartWidth = me.FakeW
|
|
||||||
fakeStartHeight = me.TabH + me.FramePadH
|
|
||||||
if (showDebug) {
|
|
||||||
me.rootNode.showFake()
|
|
||||||
showDebug = false
|
|
||||||
} else {
|
|
||||||
me.rootNode.hideFake()
|
|
||||||
showDebug = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// display the help menu
|
|
||||||
g.SetKeybinding("", '?', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
if (showHelp) {
|
|
||||||
helplayout()
|
|
||||||
showHelp = false
|
|
||||||
} else {
|
|
||||||
me.baseGui.DeleteView("help")
|
|
||||||
showHelp = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// redraw all the widgets
|
|
||||||
g.SetKeybinding("", 'r', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
if (redoWidgets) {
|
|
||||||
redoWindows(0,0)
|
|
||||||
redoWidgets = false
|
|
||||||
} else {
|
|
||||||
me.rootNode.hideWidgets()
|
|
||||||
redoWidgets = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// hide all widgets
|
|
||||||
g.SetKeybinding("", 'h', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
me.rootNode.hideWidgets()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// show all widgets
|
|
||||||
g.SetKeybinding("", 's', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
me.rootNode.showWidgets()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// list all widgets
|
|
||||||
g.SetKeybinding("", 'L', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
me.rootNode.listWidgets()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// list all widgets with positions
|
|
||||||
g.SetKeybinding("", 'M', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
me.rootNode.dumpTree(true)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// log to output window
|
|
||||||
g.SetKeybinding("", 'o', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
if me.logStdout.Visible() {
|
|
||||||
me.logStdout.SetVisible(false)
|
|
||||||
setOutput(os.Stdout)
|
|
||||||
} else {
|
|
||||||
me.logStdout.SetVisible(true)
|
|
||||||
setOutput(me.logStdout.tk)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
// exit
|
|
||||||
g.SetKeybinding("", 'q', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
standardExit()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
standardExit()
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
if (showDebug) {
|
|
||||||
var a toolkit.Action
|
|
||||||
a.B = true
|
|
||||||
a.ActionType = toolkit.EnableDebug
|
|
||||||
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
|
|
||||||
})
|
|
||||||
|
|
||||||
// panic
|
|
||||||
g.SetKeybinding("", 'p', gocui.ModNone,
|
|
||||||
func(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
standardExit()
|
|
||||||
panic("forced panic in gocui")
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
// "fmt"
|
|
||||||
// "strings"
|
|
||||||
witlog "go.wit.com/gui/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// various debugging flags
|
|
||||||
var logNow bool = true // useful for active development
|
|
||||||
var logError bool = true
|
|
||||||
var logWarn bool = false
|
|
||||||
var logInfo bool = false
|
|
||||||
var logVerbose bool = false
|
|
||||||
|
|
||||||
var outputS []string
|
|
||||||
|
|
||||||
func log(a ...any) {
|
|
||||||
witlog.Where = "wit/gocui"
|
|
||||||
witlog.Log(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sleep(a ...any) {
|
|
||||||
witlog.Sleep(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func exit(a ...any) {
|
|
||||||
witlog.Exit(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func newLog(a ...any) {
|
|
||||||
s := fmt.Sprint(a...)
|
|
||||||
tmp := strings.Split(s, "\n")
|
|
||||||
outputS = append(outputS, tmp...)
|
|
||||||
if (len(outputS) > 50) {
|
|
||||||
outputS = outputS[10:]
|
|
||||||
}
|
|
||||||
if (me.baseGui != nil) {
|
|
||||||
v, _ := me.baseGui.View("msg")
|
|
||||||
if (v != nil) {
|
|
||||||
v.Clear()
|
|
||||||
fmt.Fprintln(v, strings.Join(outputS, "\n"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func setOutput(w io.Writer) {
|
|
||||||
if (w == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
witlog.SetOutput(w)
|
|
||||||
// witlog.SetToolkitOutput(newLog)
|
|
||||||
}
|
|
|
@ -1,101 +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 (
|
|
||||||
"os"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// sets defaults and establishes communication
|
|
||||||
// to this toolkit from the wit/gui golang package
|
|
||||||
func init() {
|
|
||||||
log(logInfo, "Init() of awesome-gocui")
|
|
||||||
|
|
||||||
// init the config struct default values
|
|
||||||
Set(&me, "default")
|
|
||||||
|
|
||||||
pluginChan = make(chan toolkit.Action)
|
|
||||||
|
|
||||||
log(logNow, "Init() start pluginChan")
|
|
||||||
go catchActionChannel()
|
|
||||||
sleep(.1) // probably not needed, but in here for now under development
|
|
||||||
go main()
|
|
||||||
sleep(.1) // probably not needed, but in here for now under development
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
recieves requests from the program to do things like:
|
|
||||||
* add new widgets
|
|
||||||
* change the text of a label
|
|
||||||
* etc..
|
|
||||||
*/
|
|
||||||
func catchActionChannel() {
|
|
||||||
log(logInfo, "catchActionChannel() START")
|
|
||||||
for {
|
|
||||||
log(logInfo, "catchActionChannel() infinite for() loop restarted select on channel")
|
|
||||||
select {
|
|
||||||
case a := <-pluginChan:
|
|
||||||
if (me.baseGui == nil) {
|
|
||||||
// something went wrong initializing the gocui
|
|
||||||
log(logError,"ERROR: console did not initialize")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log(logInfo, "catchActionChannel()", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
|
|
||||||
action(&a)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func Exit() {
|
|
||||||
// TODO: what should actually happen here?
|
|
||||||
log(true, "Exit() here. doing standardExit()")
|
|
||||||
standardExit()
|
|
||||||
}
|
|
||||||
|
|
||||||
func standardExit() {
|
|
||||||
log(true, "standardExit() doing baseGui.Close()")
|
|
||||||
me.baseGui.Close()
|
|
||||||
log(true, "standardExit() doing outf.Close()")
|
|
||||||
outf.Close()
|
|
||||||
// log(true, "standardExit() setOutput(os.Stdout)")
|
|
||||||
// setOutput(os.Stdout)
|
|
||||||
log(true, "standardExit() send back Quit()")
|
|
||||||
go sendBackQuit() // don't stall here in case the
|
|
||||||
// induces a delay in case the callback channel is broken
|
|
||||||
sleep(1)
|
|
||||||
log(true, "standardExit() exit()")
|
|
||||||
exit()
|
|
||||||
}
|
|
||||||
func sendBackQuit() {
|
|
||||||
// send 'Quit' back to the program (?)
|
|
||||||
var a toolkit.Action
|
|
||||||
a.ActionType = toolkit.UserQuit
|
|
||||||
callback <- a
|
|
||||||
}
|
|
||||||
|
|
||||||
var outf *os.File
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
var err error
|
|
||||||
log(logInfo, "main() start Init()")
|
|
||||||
|
|
||||||
outf, err = os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
exit("error opening file: %v", err)
|
|
||||||
}
|
|
||||||
os.Stdout = outf
|
|
||||||
defer outf.Close()
|
|
||||||
|
|
||||||
// setOutput(outf)
|
|
||||||
// log("This is a test log entry")
|
|
||||||
|
|
||||||
ferr, _ := os.OpenFile("/tmp/witgui.err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
|
|
||||||
os.Stderr = ferr
|
|
||||||
gocuiMain()
|
|
||||||
|
|
||||||
log(true, "MouseMain() closed")
|
|
||||||
standardExit()
|
|
||||||
}
|
|
|
@ -1,149 +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"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this function uses the mouse position to highlight & unhighlight things
|
|
||||||
// this is run every time the user moves the mouse over the terminal window
|
|
||||||
func mouseMove(g *gocui.Gui) {
|
|
||||||
mx, my := g.MousePosition()
|
|
||||||
for _, view := range g.Views() {
|
|
||||||
view.Highlight = false
|
|
||||||
}
|
|
||||||
if v, err := g.ViewByPosition(mx, my); err == nil {
|
|
||||||
v.Highlight = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func msgDown(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
initialMouseX, initialMouseY = g.MousePosition()
|
|
||||||
log(true, "msgDown() X,Y", initialMouseX, initialMouseY)
|
|
||||||
if vx, vy, _, _, err := g.ViewPosition("msg"); err == nil {
|
|
||||||
xOffset = initialMouseX - vx
|
|
||||||
yOffset = initialMouseY - vy
|
|
||||||
msgMouseDown = true
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func hideDDview() error {
|
|
||||||
w, h := me.baseGui.MousePosition()
|
|
||||||
log(true, "hide dropdown menu() view msgMouseDown (w,h) =", w, h)
|
|
||||||
if (me.ddview == nil) {
|
|
||||||
return gocui.ErrUnknownView
|
|
||||||
}
|
|
||||||
if (me.ddview.tk.v == nil) {
|
|
||||||
return gocui.ErrUnknownView
|
|
||||||
}
|
|
||||||
me.ddview.SetVisible(false)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func showDDview() error {
|
|
||||||
w, h := me.baseGui.MousePosition()
|
|
||||||
log(true, "show dropdown menu() view msgMouseDown (w,h) =", w, h)
|
|
||||||
if (me.ddview == nil) {
|
|
||||||
return gocui.ErrUnknownView
|
|
||||||
}
|
|
||||||
if (me.ddview.tk.v == nil) {
|
|
||||||
return gocui.ErrUnknownView
|
|
||||||
}
|
|
||||||
me.ddview.SetVisible(true)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func mouseUp(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
w, h := g.MousePosition()
|
|
||||||
log(true, "mouseUp() view msgMouseDown (check here for dropdown menu click) (w,h) =", w, h)
|
|
||||||
if (me.ddClicked) {
|
|
||||||
me.ddClicked = false
|
|
||||||
log(true, "mouseUp() ddview is the thing that was clicked", w, h)
|
|
||||||
log(true, "mouseUp() find out what the string is here", w, h, me.ddview.tk.gocuiSize.h1)
|
|
||||||
|
|
||||||
var newZone string = ""
|
|
||||||
if (me.ddNode != nil) {
|
|
||||||
value := h - me.ddview.tk.gocuiSize.h0 - 1
|
|
||||||
log(true, "mouseUp() me.ddview.tk.gocuiSize.h1 =", me.ddview.tk.gocuiSize.h1)
|
|
||||||
log(true, "mouseUp() me.ddNode.vals =", me.ddNode.vals)
|
|
||||||
valsLen := len(me.ddNode.vals)
|
|
||||||
log(true, "mouseUp() value =", value, "valsLen =", valsLen)
|
|
||||||
log(true, "mouseUp() me.ddNode.vals =", me.ddNode.vals)
|
|
||||||
if ((value >= 0) && (value < valsLen)) {
|
|
||||||
newZone = me.ddNode.vals[value]
|
|
||||||
log(true, "mouseUp() value =", value, "newZone =", newZone)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hideDDview()
|
|
||||||
if (newZone != "") {
|
|
||||||
if (me.ddNode != nil) {
|
|
||||||
me.ddNode.SetText(newZone)
|
|
||||||
me.ddNode.S = newZone
|
|
||||||
me.ddNode.doUserEvent()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
// if there is a drop down view active, treat it like a dialog box and close it
|
|
||||||
if (hideDDview() == nil) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if msgMouseDown {
|
|
||||||
msgMouseDown = false
|
|
||||||
if movingMsg {
|
|
||||||
movingMsg = false
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
g.DeleteView("msg")
|
|
||||||
}
|
|
||||||
} else if globalMouseDown {
|
|
||||||
globalMouseDown = false
|
|
||||||
g.DeleteView("globalDown")
|
|
||||||
}
|
|
||||||
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()
|
|
||||||
test := findUnderMouse()
|
|
||||||
msg := fmt.Sprintf("Mouse really down at: %d,%d", mx, my) + "foobar"
|
|
||||||
if (test == me.ddview) {
|
|
||||||
if (me.ddview.Visible()) {
|
|
||||||
log(true, "hide DDview() Mouse really down at:", mx, my)
|
|
||||||
hideDDview()
|
|
||||||
} else {
|
|
||||||
log(true, "show DDview() Mouse really down at:", mx, my)
|
|
||||||
showDDview()
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
x := mx - len(msg)/2
|
|
||||||
if x < 0 {
|
|
||||||
x = 0
|
|
||||||
} else if x+len(msg)+1 > maxX-1 {
|
|
||||||
x = maxX - 1 - len(msg) - 1
|
|
||||||
}
|
|
||||||
log(true, "mouseDown() about to write out message to 'globalDown' view. msg =", msg)
|
|
||||||
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,186 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) placeBox(startW int, startH int) {
|
|
||||||
if (n.WidgetType != toolkit.Box) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.showWidgetPlacement(logNow, "boxS()")
|
|
||||||
|
|
||||||
newW := startW
|
|
||||||
newH := startH
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.placeWidgets(newW, newH)
|
|
||||||
// n.showWidgetPlacement(logNow, "boxS()")
|
|
||||||
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
|
|
||||||
newW += w
|
|
||||||
} else {
|
|
||||||
log(logNow, "BOX IS VERTICAL ", n.Name, "newWH()", newW, newH, "child()", w, h, child.Name)
|
|
||||||
// expand based on the child height
|
|
||||||
newH += h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// just compute this every time?
|
|
||||||
// newR := n.realGocuiSize()
|
|
||||||
|
|
||||||
n.showWidgetPlacement(logNow, "boxE()")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) placeWidgets(startW int, startH int) {
|
|
||||||
if (n == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (me.rootNode == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Window:
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.placeWidgets(me.RawW, me.RawH)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case toolkit.Tab:
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.placeWidgets(me.RawW, me.RawH)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
case toolkit.Grid:
|
|
||||||
n.placeGrid(startW, startH)
|
|
||||||
case toolkit.Box:
|
|
||||||
n.placeBox(startW, startH)
|
|
||||||
case toolkit.Group:
|
|
||||||
// move the group to the parent's next location
|
|
||||||
n.gocuiSetWH(startW, startH)
|
|
||||||
n.showWidgetPlacement(logNow, "group()")
|
|
||||||
|
|
||||||
newW := startW + me.GroupPadW
|
|
||||||
newH := startH + 3 // normal hight of the group label
|
|
||||||
// now move all the children aka: run place() on them
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.placeWidgets(newW, newH)
|
|
||||||
newR := child.realGocuiSize()
|
|
||||||
// w := newR.w1 - newR.w0
|
|
||||||
h := newR.h1 - newR.h0
|
|
||||||
|
|
||||||
// increment straight down
|
|
||||||
newH += h
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
n.gocuiSetWH(startW, startH)
|
|
||||||
// n.moveTo(startW, startH)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) placeGrid(startW int, startH int) {
|
|
||||||
w := n.tk
|
|
||||||
n.showWidgetPlacement(logInfo, "grid0:")
|
|
||||||
if (n.WidgetType != toolkit.Grid) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// first compute the max sizes of the rows and columns
|
|
||||||
for _, child := range n.children {
|
|
||||||
newR := child.realGocuiSize()
|
|
||||||
childW := newR.w1 - newR.w0
|
|
||||||
childH := newR.h1 - newR.h0
|
|
||||||
|
|
||||||
// set the child's realWidth, and grid offset
|
|
||||||
if (w.widths[child.AtW] < childW) {
|
|
||||||
w.widths[child.AtW] = childW
|
|
||||||
}
|
|
||||||
if (w.heights[child.AtH] < childH) {
|
|
||||||
w.heights[child.AtH] = childH
|
|
||||||
}
|
|
||||||
// child.showWidgetPlacement(logInfo, "grid: ")
|
|
||||||
log(logVerbose, "placeGrid:", child.Name, "child()", childW, childH, "At()", child.AtW, child.AtH)
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the width and height offset of the grid for AtW,AtH
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.showWidgetPlacement(logInfo, "grid1:")
|
|
||||||
|
|
||||||
var totalW, totalH int
|
|
||||||
for i, w := range w.widths {
|
|
||||||
if (i < child.AtW) {
|
|
||||||
totalW += w
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for i, h := range w.heights {
|
|
||||||
if (i < child.AtH) {
|
|
||||||
totalH += h
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// the new corner to move the child to
|
|
||||||
newW := startW + totalW
|
|
||||||
newH := startH + totalH
|
|
||||||
|
|
||||||
log(logVerbose, "placeGrid:", child.Name, "new()", newW, newH, "At()", child.AtW, child.AtH)
|
|
||||||
child.placeWidgets(newW, newH)
|
|
||||||
child.showWidgetPlacement(logInfo, "grid2:")
|
|
||||||
}
|
|
||||||
n.showWidgetPlacement(logInfo, "grid3:")
|
|
||||||
}
|
|
||||||
|
|
||||||
// computes the real, actual size of all the gocli objects in a widget
|
|
||||||
func (n *node) realGocuiSize() *rectType {
|
|
||||||
var f func (n *node, r *rectType)
|
|
||||||
newR := new(rectType)
|
|
||||||
// initialize the values to opposite
|
|
||||||
newR.w0 = 80
|
|
||||||
newR.h0 = 24
|
|
||||||
if me.baseGui != nil {
|
|
||||||
maxW, maxH := me.baseGui.Size()
|
|
||||||
newR.w0 = maxW
|
|
||||||
newR.h0 = maxH
|
|
||||||
}
|
|
||||||
newR.w1 = 0
|
|
||||||
newR.h1 = 0
|
|
||||||
|
|
||||||
// expand the rectangle to the biggest thing displayed
|
|
||||||
f = func(n *node, r *rectType) {
|
|
||||||
newR := n.tk.gocuiSize
|
|
||||||
if ! n.tk.isFake {
|
|
||||||
if r.w0 > newR.w0 {
|
|
||||||
r.w0 = newR.w0
|
|
||||||
}
|
|
||||||
if r.h0 > newR.h0 {
|
|
||||||
r.h0 = newR.h0
|
|
||||||
}
|
|
||||||
if r.w1 < newR.w1 {
|
|
||||||
r.w1 = newR.w1
|
|
||||||
}
|
|
||||||
if r.h1 < newR.h1 {
|
|
||||||
r.h1 = newR.h1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
f(child, r)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
f(n, newR)
|
|
||||||
return newR
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) textSize() (int, int) {
|
|
||||||
var width, height int
|
|
||||||
|
|
||||||
for _, s := range strings.Split(n.Text, "\n") {
|
|
||||||
if (width < len(s)) {
|
|
||||||
width = len(s)
|
|
||||||
}
|
|
||||||
height += 1
|
|
||||||
}
|
|
||||||
return width, height
|
|
||||||
}
|
|
|
@ -1,126 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
// if you include more than just this import
|
|
||||||
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func action(a *toolkit.Action) {
|
|
||||||
log(logInfo, "action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
|
|
||||||
n := me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
var w *guiWidget
|
|
||||||
if (n != nil) {
|
|
||||||
w = n.tk
|
|
||||||
}
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Add:
|
|
||||||
if (w == nil) {
|
|
||||||
n := addNode(a)
|
|
||||||
// w = n.tk
|
|
||||||
n.addWidget()
|
|
||||||
} else {
|
|
||||||
// this is done to protect the plugin being 'refreshed' with the
|
|
||||||
// widget binary tree. TODO: find a way to keep them in sync
|
|
||||||
log(logError, "action() Add ignored for already defined widget",
|
|
||||||
a.WidgetId, a.ActionType, a.WidgetType, a.Name)
|
|
||||||
}
|
|
||||||
case toolkit.Show:
|
|
||||||
if (a.B) {
|
|
||||||
n.showView()
|
|
||||||
} else {
|
|
||||||
n.hideWidgets()
|
|
||||||
}
|
|
||||||
case toolkit.Set:
|
|
||||||
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:
|
|
||||||
n.SetText(a.S)
|
|
||||||
case toolkit.AddText:
|
|
||||||
n.AddText(a.S)
|
|
||||||
case toolkit.Move:
|
|
||||||
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
|
|
||||||
case toolkit.CloseToolkit:
|
|
||||||
log(logNow, "attempting to close the plugin and release stdout and stderr")
|
|
||||||
standardExit()
|
|
||||||
case toolkit.Enable:
|
|
||||||
if n.Visible() {
|
|
||||||
// widget was already shown
|
|
||||||
} else {
|
|
||||||
log(logInfo, "Setting Visable to true", a.Name)
|
|
||||||
n.SetVisible(true)
|
|
||||||
}
|
|
||||||
case toolkit.Disable:
|
|
||||||
if n.Visible() {
|
|
||||||
log(logInfo, "Setting Visable to false", a.Name)
|
|
||||||
n.SetVisible(false)
|
|
||||||
} else {
|
|
||||||
// widget was already hidden
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log(logError, "action() ActionType =", a.ActionType, "WidgetType =", a.WidgetType, "Name =", a.Name)
|
|
||||||
}
|
|
||||||
log(logInfo, "action() END")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) AddText(text string) {
|
|
||||||
if (n == nil) {
|
|
||||||
log(logNow, "widget is nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
n.vals = append(n.vals, text)
|
|
||||||
for i, s := range n.vals {
|
|
||||||
log(logNow, "AddText()", n.Name, i, s)
|
|
||||||
}
|
|
||||||
n.SetText(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) SetText(text string) {
|
|
||||||
var changed bool = false
|
|
||||||
if (n == nil) {
|
|
||||||
log(logNow, "widget is nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (n.Text != text) {
|
|
||||||
n.Text = text
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
if (n.S != text) {
|
|
||||||
n.S = text
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
if (! changed) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.Visible()) {
|
|
||||||
n.textResize()
|
|
||||||
n.deleteView()
|
|
||||||
n.showView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) Set(val any) {
|
|
||||||
// w := n.tk
|
|
||||||
log(logInfo, "Set() value =", val)
|
|
||||||
|
|
||||||
switch v := val.(type) {
|
|
||||||
case bool:
|
|
||||||
n.B = val.(bool)
|
|
||||||
n.setCheckbox(val.(bool))
|
|
||||||
case string:
|
|
||||||
n.SetText(val.(string))
|
|
||||||
case int:
|
|
||||||
n.I = val.(int)
|
|
||||||
default:
|
|
||||||
log(logError, "Set() unknown type =", val, v)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
var outputW int = 180
|
|
||||||
var outputH int = 24
|
|
||||||
|
|
||||||
func moveMsg(g *gocui.Gui) {
|
|
||||||
mx, my := g.MousePosition()
|
|
||||||
if !movingMsg && (mx != initialMouseX || my != initialMouseY) {
|
|
||||||
movingMsg = true
|
|
||||||
}
|
|
||||||
g.SetView("msg", mx-xOffset, my-yOffset, mx-xOffset+outputW, my-yOffset+outputH + me.FramePadH, 0)
|
|
||||||
g.SetViewOnBottom("msg")
|
|
||||||
}
|
|
||||||
|
|
||||||
func showMsg(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
var l string
|
|
||||||
var err error
|
|
||||||
|
|
||||||
log(true, "showMsg() v.name =", v.Name())
|
|
||||||
if _, err := g.SetCurrentView(v.Name()); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, cy := v.Cursor()
|
|
||||||
if l, err = v.Line(cy); err != nil {
|
|
||||||
l = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
makeOutputWidget(g, l)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
|
||||||
maxX, maxY := g.Size()
|
|
||||||
|
|
||||||
if (me.rootNode == nil) {
|
|
||||||
// keep skipping this until the binary tree is initialized
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if (me.logStdout == nil) {
|
|
||||||
a := new(toolkit.Action)
|
|
||||||
a.Name = "stdout"
|
|
||||||
a.Text = "stdout"
|
|
||||||
a.WidgetType = toolkit.Stdout
|
|
||||||
a.WidgetId = -3
|
|
||||||
a.ParentId = 0
|
|
||||||
n := addNode(a)
|
|
||||||
me.logStdout = n
|
|
||||||
me.logStdout.tk.gocuiSize.w0 = maxX - 32
|
|
||||||
me.logStdout.tk.gocuiSize.h0 = maxY/2
|
|
||||||
me.logStdout.tk.gocuiSize.w1 = me.logStdout.tk.gocuiSize.w0 + outputW
|
|
||||||
me.logStdout.tk.gocuiSize.h1 = me.logStdout.tk.gocuiSize.h0 + outputH
|
|
||||||
}
|
|
||||||
v, err := g.View("msg")
|
|
||||||
if (v == nil) {
|
|
||||||
log("makeoutputwindow() this is supposed to happen. v == nil", err)
|
|
||||||
} else {
|
|
||||||
log("makeoutputwindow() msg != nil. WTF now? err =", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// help, err := g.SetView("help", maxX-32, 0, maxX-1, 13, 0)
|
|
||||||
// v, err = g.SetView("msg", 3, 3, 30, 30, 0)
|
|
||||||
|
|
||||||
v, err = g.SetView("msg", maxX-32, maxY/2, maxX/2+outputW, maxY/2+outputH, 0)
|
|
||||||
if errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
log("makeoutputwindow() this is supposed to happen?", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (err != nil) {
|
|
||||||
log("makeoutputwindow() create output window failed", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v == nil) {
|
|
||||||
log("makeoutputwindow() msg == nil. WTF now? err =", err)
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
me.logStdout.tk.v = v
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Clear()
|
|
||||||
v.SelBgColor = gocui.ColorCyan
|
|
||||||
v.SelFgColor = gocui.ColorBlack
|
|
||||||
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n" + stringFromMouseClick)
|
|
||||||
g.SetViewOnBottom("msg")
|
|
||||||
// g.SetViewOnBottom(v.Name())
|
|
||||||
return v
|
|
||||||
}
|
|
|
@ -1,225 +0,0 @@
|
||||||
// LICENSE: same as the go language itself
|
|
||||||
// Copyright 2023 WIT.COM
|
|
||||||
|
|
||||||
// all structures and variables are local (aka lowercase)
|
|
||||||
// since the plugin should be isolated to access only
|
|
||||||
// by functions() to insure everything here is run
|
|
||||||
// inside a dedicated goroutine
|
|
||||||
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
"sync"
|
|
||||||
"strings"
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
// "go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// It's probably a terrible idea to call this 'me'
|
|
||||||
var me config
|
|
||||||
|
|
||||||
var showDebug bool = true
|
|
||||||
var showHelp bool = true
|
|
||||||
var redoWidgets bool = true
|
|
||||||
|
|
||||||
// This is the window that is currently active
|
|
||||||
var currentWindow *node
|
|
||||||
|
|
||||||
type config struct {
|
|
||||||
baseGui *gocui.Gui // the main gocui handle
|
|
||||||
rootNode *node // the base of the binary tree. it should have id == 0
|
|
||||||
|
|
||||||
ctrlDown *node // shown if you click the mouse when the ctrl key is pressed
|
|
||||||
currentWindow *node // this is the current tab or window to show
|
|
||||||
logStdout *node // where to show STDOUT
|
|
||||||
helpLabel *gocui.View
|
|
||||||
ddview *node // the gocui view to select dropdrown lists
|
|
||||||
ddClicked bool // the dropdown menu view was clicked
|
|
||||||
ddNode *node // the dropdown menu is for this widget
|
|
||||||
|
|
||||||
/*
|
|
||||||
// this is the channel we send user events like
|
|
||||||
// mouse clicks or keyboard events back to the program
|
|
||||||
callback chan toolkit.Action
|
|
||||||
|
|
||||||
// this is the channel we get requests to make widgets
|
|
||||||
pluginChan chan toolkit.Action
|
|
||||||
*/
|
|
||||||
|
|
||||||
// When the widget has a frame, like a button, it adds 2 lines runes on each side
|
|
||||||
// so you need 3 char spacing in each direction to not have them overlap
|
|
||||||
// the amount of padding when there is a frame
|
|
||||||
FramePadW int `default:"1" dense:"0"`
|
|
||||||
FramePadH int `default:"1" dense:"0"`
|
|
||||||
|
|
||||||
PadW int `default:"1" dense:"0"`
|
|
||||||
PadH int `default:"1" dense:"0"`
|
|
||||||
|
|
||||||
// how far down to start Window or Tab headings
|
|
||||||
WindowW int `default:"8" dense:"0"`
|
|
||||||
WindowH int `default:"-1"`
|
|
||||||
TabW int `default:"5" dense:"0"`
|
|
||||||
TabH int `default:"1" dense:"0"`
|
|
||||||
|
|
||||||
// additional amount of space to put between window & tab widgets
|
|
||||||
WindowPadW int `default:"8" dense:"0"`
|
|
||||||
TabPadW int `default:"4" dense:"0"`
|
|
||||||
|
|
||||||
// additional amount of space to indent on a group
|
|
||||||
GroupPadW int `default:"6" dense:"2"`
|
|
||||||
|
|
||||||
// the raw beginning of each window (or tab)
|
|
||||||
RawW int `default:"1"`
|
|
||||||
RawH int `default:"5"`
|
|
||||||
|
|
||||||
// offset for the hidden widgets
|
|
||||||
FakeW int `default:"20"`
|
|
||||||
|
|
||||||
padded bool // add space between things like buttons
|
|
||||||
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
|
||||||
canvas bool // if set to true, the windows are a raw canvas
|
|
||||||
menubar bool // for windows
|
|
||||||
stretchy bool // expand things like buttons to the maximum size
|
|
||||||
margin bool // add space around the frames of windows
|
|
||||||
|
|
||||||
// writeMutex protects locks the write process
|
|
||||||
writeMutex sync.Mutex
|
|
||||||
|
|
||||||
// used for listWidgets() debugging
|
|
||||||
depth int
|
|
||||||
}
|
|
||||||
|
|
||||||
// deprecate these
|
|
||||||
var (
|
|
||||||
initialMouseX, initialMouseY, xOffset, yOffset int
|
|
||||||
globalMouseDown, msgMouseDown, movingMsg bool
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is the gocui way
|
|
||||||
// corner starts at in the upper left corner
|
|
||||||
type rectType struct {
|
|
||||||
w0, h0, w1, h1 int // left top right bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rectType) Width() int {
|
|
||||||
return r.w1 - r.w0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *rectType) Height() int {
|
|
||||||
return r.h1 - r.h0
|
|
||||||
}
|
|
||||||
|
|
||||||
type guiWidget struct {
|
|
||||||
// the gocui package variables
|
|
||||||
v *gocui.View // this is nil if the widget is not displayed
|
|
||||||
cuiName string // what gocui uses to reference the widget
|
|
||||||
|
|
||||||
// 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 visible like with a Box or Grid
|
|
||||||
gocuiSize rectType
|
|
||||||
|
|
||||||
isCurrent bool // is this the currently displayed Window or Tab?
|
|
||||||
isFake bool // widget types like 'box' are 'false'
|
|
||||||
|
|
||||||
// used to track the size of grids
|
|
||||||
widths map[int]int // how tall each row in the grid is
|
|
||||||
heights map[int]int // how wide each column in the grid is
|
|
||||||
|
|
||||||
tainted bool
|
|
||||||
frame bool
|
|
||||||
|
|
||||||
// for a window, this is currently selected tab
|
|
||||||
selectedTab *node
|
|
||||||
|
|
||||||
// what color to use
|
|
||||||
color *colorT
|
|
||||||
}
|
|
||||||
|
|
||||||
// from the gocui devs:
|
|
||||||
// Write appends a byte slice into the view's internal buffer. Because
|
|
||||||
// View implements the io.Writer interface, it can be passed as parameter
|
|
||||||
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
|
|
||||||
// be called to clear the view's buffer.
|
|
||||||
|
|
||||||
func (w *guiWidget) Write(p []byte) (n int, err error) {
|
|
||||||
w.tainted = true
|
|
||||||
me.writeMutex.Lock()
|
|
||||||
defer me.writeMutex.Unlock()
|
|
||||||
if (me.logStdout.tk.v == nil) {
|
|
||||||
// optionally write the output to /tmp
|
|
||||||
s := fmt.Sprint(string(p))
|
|
||||||
s = strings.TrimSuffix(s, "\n")
|
|
||||||
fmt.Fprintln(outf, s)
|
|
||||||
v, _ := me.baseGui.View("msg")
|
|
||||||
if (v != nil) {
|
|
||||||
// fmt.Fprintln(outf, "found msg")
|
|
||||||
me.logStdout.tk.v = v
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// display the output in the gocui window
|
|
||||||
me.logStdout.tk.v.Clear()
|
|
||||||
|
|
||||||
s := fmt.Sprint(string(p))
|
|
||||||
s = strings.TrimSuffix(s, "\n")
|
|
||||||
tmp := strings.Split(s, "\n")
|
|
||||||
outputS = append(outputS, tmp...)
|
|
||||||
if (len(outputS) > outputH) {
|
|
||||||
l := len(outputS) - outputH
|
|
||||||
outputS = outputS[l:]
|
|
||||||
}
|
|
||||||
fmt.Fprintln(me.logStdout.tk.v, strings.Join(outputS, "\n"))
|
|
||||||
}
|
|
||||||
|
|
||||||
return len(p), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Set(ptr interface{}, tag string) error {
|
|
||||||
if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
|
|
||||||
log(logError, "Set() Not a pointer", ptr, "with tag =", tag)
|
|
||||||
return fmt.Errorf("Not a pointer")
|
|
||||||
}
|
|
||||||
|
|
||||||
v := reflect.ValueOf(ptr).Elem()
|
|
||||||
t := v.Type()
|
|
||||||
|
|
||||||
for i := 0; i < t.NumField(); i++ {
|
|
||||||
defaultVal := t.Field(i).Tag.Get(tag)
|
|
||||||
name := t.Field(i).Name
|
|
||||||
// log("Set() try name =", name, "defaultVal =", defaultVal)
|
|
||||||
setField(v.Field(i), defaultVal, name)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func setField(field reflect.Value, defaultVal string, name string) error {
|
|
||||||
|
|
||||||
if !field.CanSet() {
|
|
||||||
// log("setField() Can't set value", field, defaultVal)
|
|
||||||
return fmt.Errorf("Can't set value\n")
|
|
||||||
} else {
|
|
||||||
log("setField() Can set value", name, defaultVal)
|
|
||||||
}
|
|
||||||
|
|
||||||
switch field.Kind() {
|
|
||||||
case reflect.Int:
|
|
||||||
val, _ := strconv.Atoi(defaultVal)
|
|
||||||
field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
|
|
||||||
case reflect.String:
|
|
||||||
field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
|
|
||||||
case reflect.Bool:
|
|
||||||
if defaultVal == "true" {
|
|
||||||
field.Set(reflect.ValueOf(true))
|
|
||||||
} else {
|
|
||||||
field.Set(reflect.ValueOf(false))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
// implements widgets 'Window' and 'Tab'
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strings"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (w *guiWidget) Width() int {
|
|
||||||
if w.frame {
|
|
||||||
return w.gocuiSize.w1 - w.gocuiSize.w0
|
|
||||||
}
|
|
||||||
return w.gocuiSize.w1 - w.gocuiSize.w0 - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *guiWidget) Height() int {
|
|
||||||
if w.frame {
|
|
||||||
return w.gocuiSize.h1 - w.gocuiSize.h0
|
|
||||||
}
|
|
||||||
return w.gocuiSize.h1 - w.gocuiSize.h0 - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) gocuiSetWH(sizeW, sizeH int) {
|
|
||||||
w := len(n.Text)
|
|
||||||
lines := strings.Split(n.Text, "\n")
|
|
||||||
h := len(lines)
|
|
||||||
|
|
||||||
tk := n.tk
|
|
||||||
if tk.isFake {
|
|
||||||
tk.gocuiSize.w0 = sizeW
|
|
||||||
tk.gocuiSize.h0 = sizeH
|
|
||||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
|
|
||||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if tk.frame {
|
|
||||||
tk.gocuiSize.w0 = sizeW
|
|
||||||
tk.gocuiSize.h0 = sizeH
|
|
||||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
|
|
||||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
|
|
||||||
} else {
|
|
||||||
tk.gocuiSize.w0 = sizeW - 1
|
|
||||||
tk.gocuiSize.h0 = sizeH - 1
|
|
||||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + 1
|
|
||||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func redoWindows(nextW int, nextH int) {
|
|
||||||
for _, n := range me.rootNode.children {
|
|
||||||
if n.WidgetType != toolkit.Window {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
w := n.tk
|
|
||||||
var tabs bool
|
|
||||||
for _, child := range n.children {
|
|
||||||
if (child.WidgetType == toolkit.Tab) {
|
|
||||||
tabs = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (tabs) {
|
|
||||||
// window is tabs. Don't show it as a standard button
|
|
||||||
w.frame = false
|
|
||||||
n.hasTabs = true
|
|
||||||
} else {
|
|
||||||
w.frame = false
|
|
||||||
n.hasTabs = false
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
n.gocuiSetWH(nextW, nextH)
|
|
||||||
n.deleteView()
|
|
||||||
// setCurrentTab(n)
|
|
||||||
// if (len(w.cuiName) < 4) {
|
|
||||||
// w.cuiName = "abcd"
|
|
||||||
// }
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,232 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"errors"
|
|
||||||
"strconv"
|
|
||||||
"bufio"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func splitLines(s string) []string {
|
|
||||||
var lines []string
|
|
||||||
sc := bufio.NewScanner(strings.NewReader(s))
|
|
||||||
for sc.Scan() {
|
|
||||||
lines = append(lines, sc.Text())
|
|
||||||
}
|
|
||||||
return lines
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) textResize() bool {
|
|
||||||
w := n.tk
|
|
||||||
var width, height int = 0, 0
|
|
||||||
var changed bool = false
|
|
||||||
|
|
||||||
for i, s := range splitLines(n.Text) {
|
|
||||||
log(logInfo, "textResize() len =", len(s), i, s)
|
|
||||||
if (width < len(s)) {
|
|
||||||
width = len(s)
|
|
||||||
}
|
|
||||||
height += 1
|
|
||||||
}
|
|
||||||
if (w.gocuiSize.w1 != w.gocuiSize.w0 + width + me.FramePadW) {
|
|
||||||
w.gocuiSize.w1 = w.gocuiSize.w0 + width + me.FramePadW
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
if (w.gocuiSize.h1 != w.gocuiSize.h0 + height + me.FramePadH) {
|
|
||||||
w.gocuiSize.h1 = w.gocuiSize.h0 + height + me.FramePadH
|
|
||||||
changed = true
|
|
||||||
}
|
|
||||||
if (changed) {
|
|
||||||
n.showWidgetPlacement(logNow, "textResize() changed")
|
|
||||||
}
|
|
||||||
return changed
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) hideView() {
|
|
||||||
n.SetVisible(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// display's the text of the widget in gocui
|
|
||||||
// will create a new gocui view if there isn't one or if it has been moved
|
|
||||||
func (n *node) showView() {
|
|
||||||
var err error
|
|
||||||
w := n.tk
|
|
||||||
|
|
||||||
if (w.cuiName == "") {
|
|
||||||
log(logError, "showView() w.cuiName was not set for widget", w)
|
|
||||||
w.cuiName = strconv.Itoa(n.WidgetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the gocui element doesn't exist, create it
|
|
||||||
if (w.v == nil) {
|
|
||||||
n.recreateView()
|
|
||||||
}
|
|
||||||
x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName)
|
|
||||||
log(logInfo, "showView() w.v already defined for widget", n.Name, err)
|
|
||||||
|
|
||||||
// n.smartGocuiSize()
|
|
||||||
changed := n.textResize()
|
|
||||||
|
|
||||||
if (changed) {
|
|
||||||
log(logNow, "showView() textResize() changed. Should recreateView here wId =", w.cuiName)
|
|
||||||
} else {
|
|
||||||
log(logNow, "showView() Clear() and Fprint() here wId =", w.cuiName)
|
|
||||||
w.v.Clear()
|
|
||||||
fmt.Fprint(w.v, n.Text)
|
|
||||||
n.SetVisible(false)
|
|
||||||
n.SetVisible(true)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the gocui element has changed where it is supposed to be on the screen
|
|
||||||
// recreate it
|
|
||||||
if (x0 != w.gocuiSize.w0) {
|
|
||||||
n.recreateView()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (y0 != w.gocuiSize.h0) {
|
|
||||||
log(logError, "showView() start hight mismatch id=", w.cuiName, "gocui h vs computed h =", w.gocuiSize.h0, y0)
|
|
||||||
n.recreateView()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (x1 != w.gocuiSize.w1) {
|
|
||||||
log(logError, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1)
|
|
||||||
n.recreateView()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (y1 != w.gocuiSize.h1) {
|
|
||||||
log(logError, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1)
|
|
||||||
n.recreateView()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n.SetVisible(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// create or recreate the gocui widget visible
|
|
||||||
// deletes the old view if it exists and recreates it
|
|
||||||
func (n *node) recreateView() {
|
|
||||||
var err error
|
|
||||||
w := n.tk
|
|
||||||
log(logError, "recreateView() START", n.WidgetType, n.Name)
|
|
||||||
if (me.baseGui == nil) {
|
|
||||||
log(logError, "recreateView() ERROR: me.baseGui == nil", w)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// this deletes the button from gocui
|
|
||||||
me.baseGui.DeleteView(w.cuiName)
|
|
||||||
w.v = nil
|
|
||||||
|
|
||||||
if (n.Name == "CLOUDFLARE_EMAIL") {
|
|
||||||
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
|
|
||||||
n.dumpWidget("jwc")
|
|
||||||
n.textResize()
|
|
||||||
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
|
|
||||||
}
|
|
||||||
|
|
||||||
a := w.gocuiSize.w0
|
|
||||||
b := w.gocuiSize.h0
|
|
||||||
c := w.gocuiSize.w1
|
|
||||||
d := w.gocuiSize.h1
|
|
||||||
|
|
||||||
w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
|
|
||||||
if err == nil {
|
|
||||||
n.showWidgetPlacement(logError, "recreateView()")
|
|
||||||
log(logError, "recreateView() internal plugin error err = nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
n.showWidgetPlacement(logError, "recreateView()")
|
|
||||||
log(logError, "recreateView() internal plugin error error.IS()", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// this sets up the keybinding for the name of the window
|
|
||||||
// does this really need to be done? I think we probably already
|
|
||||||
// know everything about where all the widgets are so we could bypass
|
|
||||||
// the gocui package and just handle all the mouse events internally here (?)
|
|
||||||
// for now, the w.v.Name is a string "1", "2", "3", etc from the widgetId
|
|
||||||
|
|
||||||
// set the binding for this gocui view now that it has been created
|
|
||||||
// gocui handles overlaps of views so it will run on the view that is clicked on
|
|
||||||
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
|
|
||||||
|
|
||||||
// this actually sends the text to display to gocui
|
|
||||||
w.v.Wrap = true
|
|
||||||
w.v.Frame = w.frame
|
|
||||||
w.v.Clear()
|
|
||||||
fmt.Fprint(w.v, n.Text)
|
|
||||||
// n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
|
|
||||||
// n.dumpWidget("jwc 2")
|
|
||||||
|
|
||||||
// if you don't do this here, it will be black & white only
|
|
||||||
if (w.color != nil) {
|
|
||||||
w.v.FrameColor = w.color.frame
|
|
||||||
w.v.FgColor = w.color.fg
|
|
||||||
w.v.BgColor = w.color.bg
|
|
||||||
w.v.SelFgColor = w.color.selFg
|
|
||||||
w.v.SelBgColor = w.color.selBg
|
|
||||||
}
|
|
||||||
if (n.Name == "CLOUDFLARE_EMAIL") {
|
|
||||||
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
|
|
||||||
n.dumpTree(true)
|
|
||||||
}
|
|
||||||
log(logError, "recreateView() END")
|
|
||||||
}
|
|
||||||
|
|
||||||
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.hideView()
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.hideWidgets()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) hideFake() {
|
|
||||||
w := n.tk
|
|
||||||
if (w.isFake) {
|
|
||||||
n.hideView()
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.hideFake()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) showFake() {
|
|
||||||
w := n.tk
|
|
||||||
if (w.isFake) {
|
|
||||||
n.setFake()
|
|
||||||
n.showWidgetPlacement(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 {
|
|
||||||
n.showWidgetPlacement(logInfo, "current:")
|
|
||||||
n.showView()
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.showWidgets()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,147 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initWidget(n *node) *guiWidget {
|
|
||||||
var w *guiWidget
|
|
||||||
w = new(guiWidget)
|
|
||||||
// Set(w, "default")
|
|
||||||
|
|
||||||
w.frame = true
|
|
||||||
|
|
||||||
// set the name used by gocui to the id
|
|
||||||
w.cuiName = strconv.Itoa(n.WidgetId)
|
|
||||||
|
|
||||||
if n.WidgetType == toolkit.Root {
|
|
||||||
log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
|
||||||
n.WidgetId = 0
|
|
||||||
me.rootNode = n
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.WidgetType == toolkit.Box) {
|
|
||||||
if (n.B) {
|
|
||||||
n.horizontal = true
|
|
||||||
} else {
|
|
||||||
n.horizontal = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.WidgetType == toolkit.Grid) {
|
|
||||||
w.widths = make(map[int]int) // how tall each row in the grid is
|
|
||||||
w.heights = make(map[int]int) // how wide each column in the grid is
|
|
||||||
}
|
|
||||||
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupCtrlDownWidget() {
|
|
||||||
a := new(toolkit.Action)
|
|
||||||
a.Name = "ctrlDown"
|
|
||||||
a.WidgetType = toolkit.Dialog
|
|
||||||
a.WidgetId = -1
|
|
||||||
a.ParentId = 0
|
|
||||||
n := addNode(a)
|
|
||||||
|
|
||||||
me.ctrlDown = n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) deleteView() {
|
|
||||||
w := n.tk
|
|
||||||
if (w.v != nil) {
|
|
||||||
w.v.Visible = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// make sure the view isn't really there
|
|
||||||
me.baseGui.DeleteView(w.cuiName)
|
|
||||||
w.v = 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 (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
|
|
||||||
}
|
|
||||||
|
|
||||||
func addDropdown() *node {
|
|
||||||
n := new(node)
|
|
||||||
n.WidgetType = toolkit.Flag
|
|
||||||
n.WidgetId = -2
|
|
||||||
n.ParentId = 0
|
|
||||||
|
|
||||||
// copy the data from the action message
|
|
||||||
n.Name = "DropBox"
|
|
||||||
n.Text = "DropBox text"
|
|
||||||
|
|
||||||
// store the internal toolkit information
|
|
||||||
n.tk = new(guiWidget)
|
|
||||||
n.tk.frame = true
|
|
||||||
|
|
||||||
// set the name used by gocui to the id
|
|
||||||
n.tk.cuiName = "-1 dropbox"
|
|
||||||
|
|
||||||
n.tk.color = &colorFlag
|
|
||||||
|
|
||||||
// add this new widget on the binary tree
|
|
||||||
n.parent = me.rootNode
|
|
||||||
if n.parent != nil {
|
|
||||||
n.parent.children = append(n.parent.children, n)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
|
@ -1,5 +0,0 @@
|
||||||
all: plugin
|
|
||||||
ldd ../nocui.so
|
|
||||||
|
|
||||||
plugin:
|
|
||||||
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../nocui.so
|
|
|
@ -1,5 +0,0 @@
|
||||||
# nogui
|
|
||||||
|
|
||||||
Package gui implements a abstraction layer for Go visual elements.
|
|
||||||
|
|
||||||
This is a sample plugin. It's a skeleton intended to be used when making a new toolkit plugin.
|
|
|
@ -1,153 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *node) show(b bool) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) enable(b bool) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) pad(at toolkit.ActionType) {
|
|
||||||
switch n.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
switch at {
|
|
||||||
case toolkit.Margin:
|
|
||||||
// SetMargined(true)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
// SetMargined(false)
|
|
||||||
case toolkit.Pad:
|
|
||||||
// SetMargined(true)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
// SetMargined(false)
|
|
||||||
}
|
|
||||||
case toolkit.Tab:
|
|
||||||
case toolkit.Window:
|
|
||||||
case toolkit.Grid:
|
|
||||||
case toolkit.Box:
|
|
||||||
case toolkit.Textbox:
|
|
||||||
log(logError, "TODO: implement ActionType =", at)
|
|
||||||
default:
|
|
||||||
log(logError, "TODO: implement pad() for", at)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) move(newParent *node) {
|
|
||||||
p := n.parent
|
|
||||||
|
|
||||||
switch p.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
case toolkit.Tab:
|
|
||||||
// tabSetMargined(tParent.uiTab, true)
|
|
||||||
case toolkit.Window:
|
|
||||||
// t.uiWindow.SetBorderless(false)
|
|
||||||
case toolkit.Grid:
|
|
||||||
// t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Box:
|
|
||||||
log(logInfo, "TODO: move() where =", p.ParentId)
|
|
||||||
log(logInfo, "TODO: move() for widget =", n.WidgetId)
|
|
||||||
default:
|
|
||||||
log(logError, "TODO: need to implement move() for type =", n.WidgetType)
|
|
||||||
log(logError, "TODO: need to implement move() for where =", p.ParentId)
|
|
||||||
log(logError, "TODO: need to implement move() for widget =", n.WidgetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) Delete() {
|
|
||||||
p := n.parent
|
|
||||||
log(logNow, "uiDelete()", n.WidgetId, "to", p.WidgetId)
|
|
||||||
|
|
||||||
switch p.WidgetType {
|
|
||||||
case toolkit.Group:
|
|
||||||
// tParent.uiGroup.SetMargined(true)
|
|
||||||
case toolkit.Tab:
|
|
||||||
// tabSetMargined(tParent.uiTab, true)
|
|
||||||
case toolkit.Window:
|
|
||||||
// t.uiWindow.SetBorderless(false)
|
|
||||||
case toolkit.Grid:
|
|
||||||
// t.uiGrid.SetPadded(true)
|
|
||||||
case toolkit.Box:
|
|
||||||
log(logNow, "tWidget.boxC =", p.Name)
|
|
||||||
log(logNow, "is there a tParent parent? =", p.parent)
|
|
||||||
// this didn't work:
|
|
||||||
// tWidget.uiControl.Disable()
|
|
||||||
// sleep(.8)
|
|
||||||
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
|
|
||||||
default:
|
|
||||||
log(logError, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
|
|
||||||
log(logError, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func doAction(a *toolkit.Action) {
|
|
||||||
log(logNow, "doAction() START a.ActionType =", a.ActionType)
|
|
||||||
log(logNow, "doAction() START a.S =", a.S)
|
|
||||||
|
|
||||||
if (a.ActionType == toolkit.InitToolkit) {
|
|
||||||
// TODO: make sure to only do this once
|
|
||||||
// go uiMain.Do(func() {
|
|
||||||
// ui.Main(demoUI)
|
|
||||||
// go catchActionChannel()
|
|
||||||
// })
|
|
||||||
// try doing this on toolkit load in init()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log(logNow, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
|
|
||||||
switch a.WidgetType {
|
|
||||||
case toolkit.Root:
|
|
||||||
me.rootNode = addNode(a)
|
|
||||||
log(logNow, "doAction() found rootNode")
|
|
||||||
return
|
|
||||||
case toolkit.Flag:
|
|
||||||
// flag(&a)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
n := me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
|
|
||||||
switch a.ActionType {
|
|
||||||
case toolkit.Add:
|
|
||||||
addNode(a)
|
|
||||||
case toolkit.Show:
|
|
||||||
n.show(true)
|
|
||||||
case toolkit.Hide:
|
|
||||||
n.show(false)
|
|
||||||
case toolkit.Enable:
|
|
||||||
n.enable(true)
|
|
||||||
case toolkit.Disable:
|
|
||||||
n.enable(false)
|
|
||||||
case toolkit.Get:
|
|
||||||
// n.setText(a.S)
|
|
||||||
case toolkit.GetText:
|
|
||||||
switch a.WidgetType {
|
|
||||||
case toolkit.Textbox:
|
|
||||||
a.S = n.S
|
|
||||||
}
|
|
||||||
case toolkit.Set:
|
|
||||||
// n.setText(a.S)
|
|
||||||
case toolkit.SetText:
|
|
||||||
// n.setText(a.S)
|
|
||||||
case toolkit.AddText:
|
|
||||||
// n.setText(a.S)
|
|
||||||
case toolkit.Margin:
|
|
||||||
n.pad(toolkit.Unmargin)
|
|
||||||
case toolkit.Unmargin:
|
|
||||||
n.pad(toolkit.Margin)
|
|
||||||
case toolkit.Pad:
|
|
||||||
n.pad(toolkit.Pad)
|
|
||||||
case toolkit.Unpad:
|
|
||||||
n.pad(toolkit.Unpad)
|
|
||||||
case toolkit.Delete:
|
|
||||||
n.Delete()
|
|
||||||
case toolkit.Move:
|
|
||||||
log(logNow, "doAction() attempt to move() =", a.ActionType, a.WidgetType)
|
|
||||||
newParent := me.rootNode.findWidgetId(a.ParentId)
|
|
||||||
n.move(newParent)
|
|
||||||
default:
|
|
||||||
log(logError, "doAction() Unknown =", a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
||||||
log(logInfo, "doAction() END =", a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue