lots cleaner code between the plugin

Queue() around SetText is helping userspace crashing
    merge forceDump(bool) into Dump()
    debugging output configuration is pretty clean
    keep cutting down duplicate things
    --gui-verbose flag works
    make label "standard" code
    add debug.FreeOSMemory()
    move the GO language internals to display in the GUI
    update push to do tags and go to github.com/wit-go/
    remove the other license file
        it might be confusing golang.org and github
    proper WidgetType
    added a Quit() button

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-03-01 11:35:36 -06:00
parent 053ea69885
commit 6196739d82
48 changed files with 1344 additions and 927 deletions

View File

@ -1,8 +0,0 @@
GNU Lesser General Public License (LGPL)
I don't want it to be possible to make closed source forks of this.
If you need to use this in a proprietary GO application, then
compile this as a plugin. The BSD license is bad for core GO libraries.
(GO now supports plugins as of version 1.8)
https://medium.com/@henvic/opensource-and-go-what-license-f6b36c201854

View File

@ -19,11 +19,12 @@ deb:
-wit mirrors
examples: \
all \
cmds-buttonplugin \
cmds-console-ui-helloworld \
cmds-helloworld \
cmds-debug \
cmds-textbox
cmds-textbox \
cmds-debug
cmds-buttonplugin:
make -C cmds/buttonplugin
@ -35,20 +36,21 @@ cmds-helloworld:
make -C cmds/helloworld
cmds-debug:
make -C cmds/debug
-make -C cmds/debug
cmds-textbox:
make -C cmds/textbox
# sync repo to the github backup
# git remote add github git@github.com:witorg/gui.git
# git remote add github2 git@github.com:wit-go/gui.git
github:
git push origin master
git push github2 master
git push github2 --tags
git push github master
git push github devel
git push github jcarr
@echo
@echo check https://github.com/witorg/gui
@echo check https://github.com/wit-go/gui
@echo
doc:

View File

@ -145,41 +145,41 @@ var WARN bool
## Functions
### func [DebugWidgetWindow](/debug_widget.go#L7)
`func DebugWidgetWindow(w *Node)`
### func [DebugWindow](/debug_window.go#L9)
`func DebugWindow()`
Creates a window helpful for debugging this package
### func [GetDebug](/debug.go#L20)
### func [Delete](/common.go#L66)
`func GetDebug() bool`
`func Delete(c *Node)`
### func [GolangDebugWindow](/example_window_golang_debug.go#L10)
`func GolangDebugWindow()`
### func [Indent](/debug.go#L120)
### func [Indent](/debug.go#L123)
`func Indent(a ...interface{})`
### func [InitPlugins](/main.go#L35)
### func [InitPlugins](/main.go#L46)
`func InitPlugins(names []string)`
### func [LoadToolkit](/plugin.go#L53)
### func [LoadToolkit](/plugin.go#L56)
`func LoadToolkit(name string) bool`
loads and initializes a toolkit (andlabs/ui, gocui, etc)
### func [Main](/main.go#L76)
### func [Main](/main.go#L87)
`func Main(f func())`
This should not pass a function
### func [Queue](/main.go#L106)
### func [Queue](/main.go#L117)
`func Queue(f func())`
@ -194,31 +194,25 @@ For example: gui.Queue(NewWindow())
`func SetDebug(s bool)`
### func [SetDebugChange](/debug.go#L52)
### func [SetDebugChange](/debug.go#L58)
`func SetDebugChange(s bool)`
This passes the debugChange flag to the toolkit plugin
### func [SetDebugToolkit](/debug.go#L37)
### func [SetDebugToolkit](/debug.go#L43)
`func SetDebugToolkit(s bool)`
This passes the debugToolkit flag to the toolkit plugin
### func [ShowDebugValues](/debug.go#L66)
### func [ShowDebugValues](/debug.go#L72)
`func ShowDebugValues()`
### func [StandardClose](/main.go#L119)
### func [StandardExit](/main.go#L136)
`func StandardClose(n *Node)`
The window is destroyed but the application does not quit
### func [StandardExit](/main.go#L125)
`func StandardExit(n *Node)`
`func StandardExit()`
The window is destroyed but the application does not quit
@ -239,7 +233,7 @@ This goroutine can be used like a watchdog timer
This struct can be used with the go-arg package
### type [GuiConfig](/structs.go#L30)
### type [GuiConfig](/structs.go#L33)
`type GuiConfig struct { ... }`
@ -249,14 +243,14 @@ This struct can be used with the go-arg package
var Config GuiConfig
```
### type [Node](/structs.go#L48)
### type [Node](/structs.go#L54)
`type Node struct { ... }`
The Node is a binary tree. This is how all GUI elements are stored
simply the name and the size of whatever GUI element exists
#### func [NewWindow](/window.go#L14)
#### func [NewWindow](/window.go#L15)
`func NewWindow() *Node`

View File

@ -1,25 +1,9 @@
package gui
import "git.wit.org/wit/gui/toolkit"
func (n *Node) NewButton(name string, custom func()) *Node {
newNode := n.New(name, "Button")
newNode.Widget.Custom = func() {
log(debugGui, "even newer clicker() name", newNode.Widget)
if (custom != nil) {
custom()
} else {
log(debugGui, "wit/gui No callback function is defined for button name =", name)
}
}
for _, aplug := range allPlugins {
log(debugGui, "gui.NewButton() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewButton == nil) {
log(debugGui, "\tgui.NewButton() aplug.NewButton = nil", aplug.name)
continue
}
aplug.NewButton(&n.Widget, &newNode.Widget)
}
newNode := n.New(name, toolkit.Button, custom)
send(n, newNode)
return newNode
}

View File

@ -1,55 +1,20 @@
package gui
import "git.wit.org/wit/gui/toolkit"
func (n *Node) Checked() bool {
n.Dump()
return n.checked
return n.widget.B
}
/*
This was the old code
newt.Custom = func () {
println("AM IN CALLBACK. SETTING NODE.checked START")
if newt.Checked() {
println("is checked")
c.checked = true
} else {
println("is not checked")
c.checked = false
}
commonCallback(c)
println("AM IN CALLBACK. SETTING NODE.checked END")
}
*/
func (n *Node) NewCheckbox(name string) *Node {
newNode := n.New(name, "Checkbox")
newNode.custom = n.custom
newNode.Widget.Custom = func() {
log(debugChange, "wit go gui checkbox", newNode.Widget)
if (n.custom != nil) {
log(debugChange, "trying parent.custom() callback() name =", name)
n.custom()
} else {
log(debugChange, "wit/gui No parent.custom() function is defined for button name =", name)
}
if (newNode.custom != nil) {
log(debugChange, "trying newNode.custom() callback name =", name)
newNode.custom()
} else {
log(debugChange, "wit/gui No newNode.custom() function is defined for button name =", name)
}
}
for _, aplug := range allPlugins {
log(debugGui, "gui.NewCheckbox() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewCheckbox == nil) {
log(debugGui, "\tgui.NewCheckbox() aplug.NewCheckbox = nil", aplug.name)
continue
}
aplug.NewCheckbox(&n.Widget, &newNode.Widget)
}
newNode := n.New(name, toolkit.Checkbox, nil)
send(n, newNode)
return newNode
}
func (n *Node) NewThing(name string) *Node {
newNode := n.New(name, toolkit.Button, nil)
send(n, newNode)
return newNode
}

View File

@ -7,8 +7,8 @@
#
run: build
./buttonplugin >/tmp/buttonplugin.log 2>&1
# ./buttonplugin
# ./buttonplugin >/tmp/buttonplugin.log 2>&1
./buttonplugin
build-release:
go get -v -u -x .

View File

@ -42,7 +42,7 @@ func main() {
log.Println("Main() END")
time.Sleep(1 * time.Second)
gui.Watchdog()
gui.StandardExit(nil)
gui.StandardExit()
}
var counter int = 5
@ -82,7 +82,9 @@ func buttonWindow() {
})
g.NewButton("gui.GolangDebugWindow()", func () {
gui.GolangDebugWindow()
// make a seperate window out of this
// w.GolangDebugWindow(false)
w.GolangDebugWindow(true)
})
g.NewButton("LoadToolkit(andlabs)", func () {

View File

@ -11,8 +11,6 @@ import (
type LogOptions struct {
LogFile string
Verbose bool
// GuiDebug bool `help:"open up the wit/gui Debugging Window"`
// GuiDemo bool `help:"open the wit/gui Demo Window"`
User string `arg:"env:USER"`
}
@ -45,11 +43,15 @@ func main() {
func initGUI() {
var w *gui.Node
gui.Config.Title = "Hello World"
gui.Config.Width = 640
gui.Config.Height = 480
gui.Config.Width = 642
gui.Config.Height = 481
gui.Config.Exit = myDefaultExit
w = gui.NewWindow()
w.Custom = func () {
log.Println("myDefaultExit(w)")
myDefaultExit(w)
}
w.Dump()
addDemoTab(w, "A Simple Tab Demo")
addDemoTab(w, "A Second Tab")
@ -57,6 +59,9 @@ func initGUI() {
if (args.GuiDebug) {
gui.DebugWindow()
}
if (args.GuiVerbose) {
gui.SetDebug(true)
}
}
func addDemoTab(window *gui.Node, title string) {
@ -71,18 +76,19 @@ func addDemoTab(window *gui.Node, title string) {
dd.AddDropdownName("more 1")
dd.AddDropdownName("more 2")
dd.AddDropdownName("more 3")
dd.OnChanged = func(*gui.Node) {
s := dd.GetText()
tb.SetText("hello world " + args.User + "\n" + s)
}
g2 = newNode.NewGroup("group 2")
tb = g2.NewTextbox("tb")
log.Println("tb =", tb.GetText())
tb.OnChanged = func(*gui.Node) {
tb.Custom = func() {
s := tb.GetText()
log.Println("text =", s)
}
dd.Custom = func() {
s := dd.GetText()
log.Println("hello world " + args.User + "\n" + s + "\n")
tb.SetText("hello world " + args.User + "\n" + s + "\n")
}
}
func myDefaultExit(n *gui.Node) {

View File

@ -1,17 +1,32 @@
package gui
// import "errors"
import "regexp"
import (
"regexp"
// "errors"
// "git.wit.org/wit/gui/toolkit"
)
// functions for handling text related GUI elements
func (n *Node) SetText(str string) bool {
log(debugChange, "gui.SetText() value = FIXME. NOT DOING ANYTHING", str)
log(debugChange, "gui.SetText() value =", str)
n.widget.Action = "Set"
n.widget.S = str
send(n.parent, n)
return true
}
func (n *Node) AppendText(str string) bool {
n.widget.Action = "Set"
tmp := n.widget.S + str
log(debugChange, "gui.AppendText() value =", tmp)
n.widget.S = tmp
send(n.parent, n)
return true
}
func (n *Node) GetText() string {
return "TODO: GetText() = {}"
return n.widget.S
}
/*
@ -48,19 +63,18 @@ func normalizeInt(s string) string {
return clean
}
func Delete(c *Node) {
c.widget.Action = "Delete"
send(c.parent, c)
}
func commonCallback(n *Node) {
// TODO: make all of this common code to all the widgets
if (n.OnChanged == nil) {
log(debugChange, "Not Running n.OnChanged(n) == nil")
// This might be common everywhere finally (2023/03/01)
if (n.Custom == nil) {
log(debugChange, "Not Running n.Custom(n) == nil")
} else {
log(debugChange, "Running n.OnChanged(n)")
n.OnChanged(n)
}
if (n.custom == nil) {
log(debugChange, "Not Running n.custom(n) == nil")
} else {
log(debugChange, "Running n.custom()")
n.custom()
log(debugChange, "Running n.Custom(n)")
n.Custom()
}
}

View File

@ -4,8 +4,8 @@ package gui
// A function dump out the binary tree
import (
// "fmt"
"reflect"
"strconv"
"git.wit.org/wit/gui/toolkit"
)
// various debugging flags
@ -17,14 +17,20 @@ var debugChange bool = false // shows user events like mouse and keyboard
var debugPlugin bool = false
var debugToolkit bool = false
func GetDebug () bool {
return debugGui
}
// func GetDebug () bool {
// return debugGui
// }
func SetDebug (s bool) {
debugGui = s
// debugDump = s
// debugNode = s
debugGui = s
debugChange = s
debugDump = s
debugTabs = s
debugPlugin = s
debugNode = s
debugToolkit = s
SetDebugChange(s)
SetDebugToolkit(s)
}
/*
@ -64,12 +70,14 @@ func SetDebugChange (s bool) {
}
func ShowDebugValues() {
log(true, "Debug =", debugGui)
log(true, "DebugDump =", debugDump)
log(true, "DebugNode =", debugNode)
log(true, "DebugTabs =", debugTabs)
log(true, "DebugPlugin =", debugPlugin)
log(true, "DebugChange =", debugChange)
// The order here should match the order in the GUI
// TODO: get the order from the node binary tree
log(true, "Debug =", debugGui)
log(true, "DebugChange =", debugChange)
log(true, "DebugDump =", debugDump)
log(true, "DebugTabs =", debugTabs)
log(true, "DebugPlugin =", debugPlugin)
log(true, "DebugNode =", debugNode)
log(true, "DebugToolkit =", debugToolkit)
// dump out the debugging flags for the plugins
@ -102,14 +110,9 @@ func (n *Node) Dump() {
if (n.children != nil) {
Indent("children = ", n.children)
}
if (n.custom != nil) {
Indent("custom = ", n.custom)
if (n.Custom != nil) {
Indent("Custom = ", n.Custom)
}
Indent("checked = ", n.checked)
if (n.OnChanged != nil) {
Indent("OnChanged = ", n.OnChanged)
}
Indent("text = ", reflect.ValueOf(n.text).Kind(), n.text)
Indent("NODE DUMP END")
}
@ -124,15 +127,15 @@ func Indent(a ...interface{}) {
func (n *Node) dumpWidget() {
var info string
if (n.Widget.Type == "") {
n.Widget.Type = "UNDEF"
}
info = n.Widget.Type
info = n.widget.Type.String()
info += ", " + n.Widget.Name
if (n.Name != n.Widget.Name) {
info += ", " + n.widget.Name
if (n.Name != n.widget.Name) {
info += " NAME MISMATCH"
}
if (n.widget.Type == toolkit.Checkbox) {
info += " = " + strconv.FormatBool(n.widget.B)
}
logindent(listChildrenDepth, defaultPadding, n.id, info)
}

84
debug_flags.go Normal file
View File

@ -0,0 +1,84 @@
package gui
// Let's you toggle on and off the various types of debugging output
// These checkboxes should be in the same order as the are printed
func (n *Node) debugFlags(makeWindow bool) {
var w, g *Node
// Either:
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "Debug Flags"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w.Custom = w.StandardClose
} else {
w = n.NewTab("Debug Flags")
}
w.Dump()
g = w.NewGroup("Debug Flags")
g.NewButton("Turn on all Debug Flags", func () {
SetDebug(true)
})
g.NewButton("Turn off all Debug Flags", func () {
SetDebug(false)
})
// generally useful debugging
cb1 := g.NewCheckbox("debugGui")
cb1.Custom = func() {
debugGui = cb1.widget.B
log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B)
}
// debugging that will show you things like mouse clicks, user inputing text, etc
// also set toolkit.DebugChange
cb2 := g.NewCheckbox("debugChange")
cb2.Custom = func() {
debugChange = cb2.widget.B
SetDebugChange(cb2.widget.B)
log(debugGui, "Custom() n.widget =", cb2.widget.Name, cb2.widget.B)
}
// supposed to tell if you are going to dump full variable output
cb3 := g.NewCheckbox("debugDump")
cb3.Custom = func() {
debugDump = cb3.widget.B
log(debugGui, "Custom() n.widget =", cb3.widget.Name, cb3.widget.B)
}
cb4 := g.NewCheckbox("debugTabs")
cb4.Custom = func() {
debugTabs = cb4.widget.B
log(debugGui, "Custom() n.widget =", cb4.widget.Name, cb4.widget.B)
}
// should show you when things go into or come back from the plugin
cb5 := g.NewCheckbox("debugPlugin")
cb5.Custom = func() {
debugPlugin = cb5.widget.B
log(debugGui, "Custom() n.widget =", cb5.widget.Name, cb5.widget.B)
}
cb6 := g.NewCheckbox("debugNode")
cb6.Custom = func() {
debugNode = cb6.widget.B
log(debugGui, "Custom() n.widget =", cb6.widget.Name, cb6.widget.B)
}
// turns on debugging inside the plugin toolkit
cb7 := g.NewCheckbox("debugToolkit")
cb7.Custom = func() {
SetDebugToolkit(cb7.widget.B)
log(debugGui, "Custom() n.widget =", cb7.widget.Name, cb7.widget.B)
}
g.NewButton("Dump Debug Flags", func () {
ShowDebugValues()
})
}

168
debug_golang.go Normal file
View File

@ -0,0 +1,168 @@
package gui
import (
"fmt"
"bytes"
// "os"
"runtime"
"runtime/debug"
"runtime/pprof"
)
func (n *Node) GolangDebugWindow(makeWindow bool) {
var w, g, og, outputTextbox *Node
// Either:
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "GO"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w.Custom = w.StandardClose
} else {
w = n.NewTab("GO")
}
w.Dump()
g = w.NewGroup("Language Internals")
g.NewButton("ReadModuleInfo()", func () {
tmp, _ := debug.ReadBuildInfo()
outputTextbox.SetText(tmp.String())
})
g.NewButton("debug.PrintStack()", func () {
outputTextbox.SetText(string(debug.Stack()))
})
g.NewButton("pprof.Lookup(goroutine)", func () {
buf := new(bytes.Buffer)
pprof.Lookup("goroutine").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("pprof.Lookup(heap)", func () {
buf := new(bytes.Buffer)
pprof.Lookup("heap").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("pprof.Lookup(block)", func () {
buf := new(bytes.Buffer)
pprof.Lookup("block").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("pprof.Lookup threadcreate", func () {
buf := new(bytes.Buffer)
pprof.Lookup("threadcreate").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("runtime.ReadMemStats()", func () {
outputTextbox.SetText(runtimeReadMemStats())
})
g.NewButton("debug.FreeOSMemory()", func () {
var out string = "Before debug.FreeOSMemory():\n\n"
out += runtimeReadMemStats()
debug.FreeOSMemory()
out += "\n\nAfter debug.FreeOSMemory():\n\n"
out += runtimeReadMemStats()
outputTextbox.SetText(out)
})
g.NewButton("debug.ReadGCStats()", func () {
var tmp debug.GCStats
var out string
debug.ReadGCStats(&tmp)
log(tmp)
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("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
out += fmt.Sprintln("Pause:", tmp.Pause, "// []time.Duration pause history, most recent first")
out += fmt.Sprintln("PauseEnd:", tmp.Pause, "// []time.Time pause history, most recent first")
out += fmt.Sprintln("PauseQuantiles:", tmp.PauseQuantiles, "// []time.Duration")
outputTextbox.SetText(out)
})
g.NewButton("debug.SetTraceback('all')", func () {
debug.SetTraceback("all")
})
g.NewButton("panic()", func () {
panic("test")
})
g.NewLabel("TODO:")
g.NewButton("debug.SetMemoryLimit(int)", func () {
// TODO:
//debug.SetMemoryLimit(1024 * 1024 * 100)
})
g.NewButton("debug.SetMaxStack(int bytes)", func () {
// default is apparently 1GB
})
g.NewButton("debug.SetMaxThreads(int)", func () {
// default is apparently 10,000
})
g.NewButton("debug.SetTraceback('all')", func () {
debug.SetTraceback("all")
})
// deprecated (probably) by String() implementation within golang
g.NewButton("dumpModuleInfo() (deprecate)", func () {
outputTextbox.SetText(dumpModuleInfo())
})
og = w.NewGroup("output")
outputTextbox = og.NewTextbox("outputBox")
outputTextbox.Custom = func () {
log("custom TextBox() for golang output a =", outputTextbox.widget.S, outputTextbox.id)
}
}
func runtimeReadMemStats() string {
var s runtime.MemStats
var out string
runtime.ReadMemStats(&s)
out += fmt.Sprintln("alloc:", s.Alloc, "bytes")
out += fmt.Sprintln("total-alloc:", s.TotalAlloc, "bytes")
out += fmt.Sprintln("sys:", s.Sys, "bytes")
out += fmt.Sprintln("lookups:", s.Lookups)
out += fmt.Sprintln("mallocs:", s.Mallocs)
out += fmt.Sprintln("frees:", s.Frees)
out += fmt.Sprintln("heap-alloc:", s.HeapAlloc, "bytes")
out += fmt.Sprintln("heap-sys:", s.HeapSys, "bytes")
out += fmt.Sprintln("heap-idle:", s.HeapIdle,"bytes")
out += fmt.Sprintln("heap-in-use:", s.HeapInuse, "bytes")
out += fmt.Sprintln("heap-released:", s.HeapReleased, "bytes")
out += fmt.Sprintln("heap-objects:", s.HeapObjects)
out += fmt.Sprintln("stack-in-use:", s.StackInuse, "bytes")
out += fmt.Sprintln("stack-sys", s.StackSys, "bytes")
out += fmt.Sprintln("next-gc: when heap-alloc >=", s.NextGC, "bytes")
out += fmt.Sprintln("last-gc:", s.LastGC, "ns")
out += fmt.Sprintln("gc-pause:", s.PauseTotalNs, "ns")
out += fmt.Sprintln("num-gc:", s.NumGC)
out += fmt.Sprintln("enable-gc:", s.EnableGC)
out += fmt.Sprintln("debug-gc:", s.DebugGC)
return out
}
func dumpModuleInfo() string {
var out string
tmp, _ := debug.ReadBuildInfo()
if tmp == nil {
out += fmt.Sprintln("This wasn't compiled with go module support")
return ""
}
out += fmt.Sprintln("mod.Path = ", tmp.Path)
out += fmt.Sprintln("mod.Main.Path = ", tmp.Main.Path)
out += fmt.Sprintln("mod.Main.Version = ", tmp.Main.Version)
out += fmt.Sprintln("mod.Main.Sum = ", tmp.Main.Sum)
for _, value := range tmp.Deps {
out += fmt.Sprintln("\tmod.Path = ", value.Path)
out += fmt.Sprintln("\tmod.Version = ", value.Version)
}
return out
}

115
debug_widget.go Normal file
View File

@ -0,0 +1,115 @@
package gui
import (
"strconv"
)
func DebugWidgetWindow(w *Node) {
var win, g *Node
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name
Config.Title = title
Config.Width = 300
Config.Height = 400
win = NewWindow()
win.Custom = w.StandardClose
g = win.NewGroup("Actions")
g.NewLabel(title)
g.NewButton("Dump()", func () {
w.Dump()
})
g.NewButton("Disable()", func () {
w.widget.Action = "Disable"
send(w.parent, w)
})
g.NewButton("Enable()", func () {
w.widget.Action = "Enable"
send(w.parent, w)
})
g.NewButton("Show()", func () {
w.widget.Action = "Show"
send(w.parent, w)
})
g.NewButton("Hide()", func () {
w.widget.Action = "Hide"
send(w.parent, w)
})
g.NewButton("Value()", func () {
log("w.B =", w.widget.B)
log("w.I =", w.widget.I)
log("w.S =", w.widget.S)
})
g.NewButton("Set Value(20)", func () {
w.widget.Action = "Set"
w.widget.B = true
w.widget.I = 20
w.widget.S = "Set Value(20)"
send(w.parent, w)
})
g.NewButton("Delete()", func () {
Delete(w)
})
}
func (n *Node) debugWidgets(makeWindow bool) {
var w, gList, gShow *Node
// Either:
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "Widgets"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w.Custom = w.StandardClose
} else {
w = n.NewTab("Widgets")
}
w.Dump()
gList = w.NewGroup("Pick a widget to debug")
gShow = w.NewGroup("Added Widgets go here")
gList.NewButton("Button", func () {
a := gShow.NewButton("myButton", func () {
log("this code is more better")
})
DebugWidgetWindow(a)
})
gList.NewButton("Checkbox", func () {
a := gShow.NewCheckbox("myCheckbox")
a.Custom = func () {
log("custom checkox func a =", a.widget.B, a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Label", func () {
a := gShow.NewLabel("mylabel")
DebugWidgetWindow(a)
})
gList.NewButton("Textbox", func () {
a := gShow.NewTextbox("mytext")
a.Custom = func () {
log("custom TextBox() a =", a.widget.S, a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Slider", func () {
a := gShow.NewSlider("tmp slider", 10, 55)
a.Custom = func () {
log("custom slider() a =", a.widget.S, a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Spinner", func () {
a := gShow.NewSpinner("tmp spinner", 6, 32)
a.Custom = func () {
log("custom spinner() a =", a.widget.S, a.id)
}
DebugWidgetWindow(a)
})
}

View File

@ -10,88 +10,16 @@ func DebugWindow() {
Config.Title = "go.wit.org/gui debug window"
Config.Width = 300
Config.Height = 200
Config.Exit = StandardClose
bugWin = NewWindow()
bugWin.Custom = bugWin.StandardClose
bugWin.DebugTab("Debug Tab")
}
var checkd, checkdn, checkdt, checkdtk *Node
//////////////////////// debug flags //////////////////////////////////
func debugFlags(n *Node) {
var df, checkdn, checkdd, changeCheckbox *Node
df = n.NewGroup("Debug Flags")
df.NewLabel("flags to control debugging output")
cb := df.NewCheckbox("debugGui")
cb.custom = func() {
log(true, "custom ran correctly for =", n.Name)
debugGui = true
}
checkdd = df.NewCheckbox("debugDump")
checkdd.custom = func() {
log(true, "debugDump() custom ran correctly for =", n.Name)
debugDump = true
}
checkdn = df.NewCheckbox("debugNode")
checkdn.custom = func() {
log(true, "debugNode() custom ran correctly for =", n.Name)
debugNode = true
}
cb = df.NewCheckbox("debugChange")
cb.custom = func() {
log(true, "checkbox: custom() ran correctly for =", cb.Name)
log(true, "START debugChange =", debugChange)
if (debugChange) {
debugChange = false
SetDebugChange(false)
log(true, "debugToolkitChange turned off node.Name =", cb.Name)
} else {
debugChange = true
SetDebugChange(true)
log(true, "debugToolkitChange turned on Name =", cb.Name)
}
log(true, "END debugChange =", debugChange)
}
cb = df.NewCheckbox("debugTabs")
cb.custom = func() {
log(true, "debugTabs() custom ran correctly for =", n.Name)
debugTabs = true
}
cb = df.NewCheckbox("debugPlugin")
cb.custom = func() {
log(true, "debugPlugin() custom ran correctly for =", n.Name)
debugPlugin = true
}
changeCheckbox = df.NewCheckbox("debugToolkit")
changeCheckbox.custom = func() {
SetDebugToolkit(true)
}
df.NewButton("Debug Toolkit", func() {
if (debugToolkit) {
SetDebugToolkit(false)
log(true, "debugToolkit turned off node.Name =", n.Name)
} else {
SetDebugToolkit(true)
log(true, "debugToolkit turned on Name =", n.Name)
}
})
df.NewButton("Dump Debug Flags", func () {
ShowDebugValues()
})
}
var checkd, checkdn, checkdt, checkdtk, lb1, lb2 *Node
var myButton *Node
func (n *Node) DebugTab(title string) *Node {
var newN, gog, g1, g2, g3, dd *Node
var newN, gog, g1, g2, g3, dd, junk, newThing *Node
// time.Sleep(1 * time.Second)
newN = n.NewTab(title)
@ -101,7 +29,13 @@ func (n *Node) DebugTab(title string) *Node {
gog = newN.NewGroup("GOLANG")
gog.NewLabel("go language")
gog.NewButton("GO Language Debug", func () {
GolangDebugWindow()
newN.GolangDebugWindow(false)
})
gog.NewButton("Debug Flags", func () {
newN.debugFlags(false)
})
gog.NewButton("Debug Widgets", func () {
newN.debugWidgets(false)
})
gog.NewLabel("wit/gui package")
@ -109,11 +43,21 @@ func (n *Node) DebugTab(title string) *Node {
// DemoToolkitWindow()
})
debugFlags(newN)
junk = gog.NewButton("junk", func () {
log("click junk, get junk")
})
gog.NewLabel("tmp label")
//////////////////////// window debugging things //////////////////////////////////
g1 = newN.NewGroup("Current Windows")
dd = g1.NewDropdown("Window Dropdown")
dd.Custom = func() {
name := dd.widget.S
bugWin = mapWindows[name]
log("The Window was set to", name)
}
log(debugGui, "dd =", dd)
// initialize the windows map if it hasn't been
@ -122,6 +66,7 @@ func (n *Node) DebugTab(title string) *Node {
}
var dump = false
var last = ""
for _, child := range Config.master.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
if (child.parent != nil) {
@ -134,16 +79,44 @@ func (n *Node) DebugTab(title string) *Node {
child.Dump()
}
dd.AddDropdownName(child.Name)
last = child.Name
mapWindows[child.Name] = child
}
dd.SetDropdown(0)
dd.SetDropdownName(last)
dd.NewButton("Delete(junk)", func () {
Delete(junk)
})
dd.NewButton("myButton", func () {
gog.NewButton("myButton", func () {
log("this code is better")
})
})
dd.NewButton("add Hope", func () {
var i int = 1
log("add hope?", i)
gog.NewButton("hope", func () {
i += 1
log("write better code", i)
})
})
dd.NewButton("add newThing", func () {
var i, j int = 1, 1
newThing = gog.NewThing("NewThing")
newThing.Custom = func() {
f := i + j
log("newThing!!! n.widget =", newThing.widget.Name, newThing.widget.B, f)
j = i
i = f
}
log("newThing!!! n.widget")
})
g2 = newN.NewGroup("Debug Window")
g2.NewButton("SetMargined(tab)", func () {
log(debugChange, "START SetMargined(tab)", g2.Name)
// name := dd.GetText()
name := dd.Widget.S
name := dd.widget.S
log(true, "name =", name)
log(debugChange, "name =", name)
log(debugChange, "mapWindows[name] =", mapWindows[name])
/*
@ -154,7 +127,7 @@ func (n *Node) DebugTab(title string) *Node {
}
*/
bugWin = mapWindows[name]
log(debugChange, "END dd.Widget.S =", dd.Widget.S)
log(debugChange, "END dd.widget.S =", dd.widget.S)
// gw.UiTab.SetMargined(*gw.TabNumber, true)
})
g2.NewButton("Hide(tab)", func () {
@ -170,6 +143,9 @@ func (n *Node) DebugTab(title string) *Node {
g2.NewButton("change Title", func () {
// mainWindow.SetText("hello world")
})
g2.NewButton("Quit", func () {
exit()
})
/////////////////////////////////////////////////////
g3 = newN.NewGroup("Node Debug")

View File

@ -1,53 +1,46 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
// add a new entry to the dropdown name
func (n *Node) AddDropdownName(name string) {
for _, aplug := range allPlugins {
log(debugGui, "gui.AddDropdownName() aplug =", aplug.name, "name =", name)
log(debugPlugin, "AddDropdownName() aplug =", aplug.name, "name =", name)
if (aplug.AddDropdownName == nil) {
log(debugGui, "\tgui.AddDropdownName() aplug.NewDropdown = nil", aplug.name)
log(debugPlugin, "\taplug.AddDropdownName() = nil")
continue
}
aplug.AddDropdownName(&n.Widget, name)
aplug.AddDropdownName(&n.widget, name)
}
if (n.Widget.Custom == nil) {
n.SetDropdownChange( func() {
log(debugChange, "gui.Dropdown change() REAL Custom() name =", name)
log(debugChange, "gui.Dropdown change() REAL n.Widget.S =", n.Widget.S)
})
}
// TODO, this makes functions over and over for each dropdown menu
/*
n.Widget.Custom = func() {
log(debugChange, "gui.Dropdown change() START Custom() name =", name)
log(debugChange, "gui.Dropdown change() START n.Widget.S =", n.Widget.S)
}
*/
}
func (n *Node) SetDropdown(s any) {
log(debugGui, "gui.SetDropdown() TODO: make this work. s =", s)
}
func (n *Node) SetDropdownChange(f func()) {
n.Widget.Custom = f
// Set the dropdown menu to 'name'
func (n *Node) SetDropdownName(name string) {
log(debugGui, "SetDropdownName() work. name =", name)
for _, aplug := range allPlugins {
log(debugPlugin, "SetDropdownName() aplug =", aplug.name, "name =", name)
if (aplug.SetDropdownName == nil) {
log(true, "\taplug.SetDropdownName() aplug = nil")
continue
}
aplug.SetDropdownName(&n.widget, name)
}
}
func (n *Node) NewDropdown(name string) *Node {
newNode := n.New(name, "Dropdown")
newNode := n.New(name, toolkit.Dropdown, nil)
for _, aplug := range allPlugins {
log(debugGui, "gui.NewDropdown() aplug =", aplug.name, "name =", newNode.Widget.Name)
log(debugGui, "gui.NewDropdown() aplug =", aplug.name, "name =", newNode.widget.Name)
if (aplug.NewDropdown == nil) {
log(debugGui, "\tgui.NewDropdown() aplug.NewDropdown = nil", aplug.name)
continue
}
aplug.NewDropdown(&n.Widget, &newNode.Widget)
aplug.NewDropdown(&n.widget, &newNode.widget)
}
// TODO, this doesn't work for some reason (over-written by plugin?)
newNode.Widget.Custom = func() {
log(true, "gui.NewDropdown() START Custom()")
}
return newNode
}

View File

@ -1,104 +0,0 @@
package gui
import (
"os"
"runtime"
"runtime/debug"
"runtime/pprof"
)
func GolangDebugWindow() {
var w, t *Node
Config.Title = "Go Language Debug Window"
Config.Width = 400
Config.Height = 400
Config.Exit = StandardClose
w = NewWindow()
t = w.NewTab("Debug Tab")
log("debugWindow() START")
/////////////////////////////// Column DEBUG GOLANG //////////////////////
g := t.NewGroup("GO Language")
g.NewButton("runtime.Stack()", func () {
log("\tSTART")
buf := make([]byte, 1<<16)
runtime.Stack(buf, true)
log("\t %s", buf)
log("\tEND")
})
g.NewButton("dumpModuleInfo()", func () {
log("\tSTART")
dumpModuleInfo()
log("\tEND")
})
g.NewButton("debug.PrintStack()", func () {
log("\tSTART")
debug.PrintStack()
log("\tEND")
})
g.NewButton("pprof.Lookup(goroutine)", func () {
log("\tSTART")
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
log("\tEND")
})
g.NewButton("pprof.Lookup(heap)", func () {
log("\tSTART")
pprof.Lookup("heap").WriteTo(os.Stdout, 1)
log("\tEND")
})
g.NewButton("pprof.Lookup(block)", func () {
log("\tSTART")
pprof.Lookup("block").WriteTo(os.Stdout, 1)
log("\tEND")
})
g.NewButton("pprof.Lookup threadcreate", func () {
log("\tSTART")
pprof.Lookup("threadcreate").WriteTo(os.Stdout, 1)
log("\tEND")
})
g.NewButton("runtime.ReadMemStats", func () {
var s runtime.MemStats
runtime.ReadMemStats(&s)
log("alloc: %v bytes\n", s.Alloc)
log("total-alloc: %v bytes\n", s.TotalAlloc)
log("sys: %v bytes\n", s.Sys)
log("lookups: %v\n", s.Lookups)
log("mallocs: %v\n", s.Mallocs)
log("frees: %v\n", s.Frees)
log("heap-alloc: %v bytes\n", s.HeapAlloc)
log("heap-sys: %v bytes\n", s.HeapSys)
log("heap-idle: %v bytes\n", s.HeapIdle)
log("heap-in-use: %v bytes\n", s.HeapInuse)
log("heap-released: %v bytes\n", s.HeapReleased)
log("heap-objects: %v\n", s.HeapObjects)
log("stack-in-use: %v bytes\n", s.StackInuse)
log("stack-sys: %v bytes\n", s.StackSys)
log("next-gc: when heap-alloc >= %v bytes\n", s.NextGC)
log("last-gc: %v ns\n", s.LastGC)
log("gc-pause: %v ns\n", s.PauseTotalNs)
log("num-gc: %v\n", s.NumGC)
log("enable-gc: %v\n", s.EnableGC)
log("debug-gc: %v\n", s.DebugGC)
})
}
func dumpModuleInfo() {
tmp, _ := debug.ReadBuildInfo()
if tmp == nil {
log("This wasn't compiled with go module support")
return
}
log("mod.Path = ", tmp.Path)
log("mod.Main.Path = ", tmp.Main.Path)
log("mod.Main.Version = ", tmp.Main.Version)
log("mod.Main.Sum = ", tmp.Main.Sum)
for _, value := range tmp.Deps {
log("\tmod.Path = ", value.Path)
log("\tmod.Version = ", value.Version)
}
}

View File

@ -1,22 +1,14 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
// TODO: which name is better. AddGroup or NewGroup ?
// first reaction is NewGroup
func (n *Node) NewGroup(name string) *Node {
var newNode *Node
newNode = n.New(name, "Group")
log(debugGui, "toolkit.NewGroup() START", name)
log(debugGui, "gui.Node.NewGroup()", name)
for _, aplug := range allPlugins {
log(debugGui, "gui.Node.NewGroup() toolkit plugin =", aplug.name)
if (aplug.NewGroup == nil) {
continue
}
aplug.NewGroup(&n.Widget, &newNode.Widget)
}
newNode = n.New(name, toolkit.Group, nil)
send(n, newNode)
return newNode
}

View File

@ -1,19 +1,14 @@
package gui
// import "errors"
// import "regexp"
import (
"git.wit.org/wit/gui/toolkit"
)
func (n *Node) NewLabel(text string) *Node {
newNode := n.New(text, "Label")
for _, aplug := range allPlugins {
log(debugGui, "gui.NewLabel() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewLabel == nil) {
log(debugGui, "\tgui.NewLabel() aplug.NewLabel = nil", aplug.name)
continue
}
aplug.NewLabel(&n.Widget, &newNode.Widget)
}
newNode := n.New(text, toolkit.Label, func() {
log(debugChange, "TextBox changed", text)
})
send(n, newNode)
return newNode
}

5
log.go
View File

@ -98,8 +98,9 @@ func log(a ...any) {
if (a == nil) {
return
}
var blah bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(blah)) {
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
// golog.Println("\t a[0] = bool")
if (a[0] == false) {
return

43
main.go
View File

@ -16,20 +16,31 @@ const Yaxis = 1 // stack things vertically
var res embed.FS
func init() {
debugGui = true
log(debugGui, "gui.init() has been run")
log("init() has been run")
Config.counter = 0
Config.prefix = "wit"
title := "guiBinaryTree"
w := 640
h := 480
Config.Width = 640
Config.Height = 480
// Populates the top of the binary tree
Config.master = addNode(title, w, h)
// Config.master.Dump()
debugGui = false
Config.master = addNode("guiBinaryTree")
go doGuiChan()
}
func doGuiChan() {
for {
select {
case <-Config.ActionCh1:
log(true, "CHANNEL ACTION 1 !!!!!")
return
case <-Config.ActionCh2:
log(true, "CHANNEL ACTION 2 !!!!!")
return
default:
}
}
}
func InitPlugins(names []string) {
@ -116,21 +127,21 @@ func Queue(f func()) {
}
// The window is destroyed but the application does not quit
func StandardClose(n *Node) {
func (n *Node) StandardClose() {
log(debugGui, "wit/gui Standard Window Close. name =", n.Name)
log(debugGui, "wit/gui Standard Window Close. n.custom exit =", n.custom)
log(debugGui, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
}
// The window is destroyed but the application does not quit
func StandardExit(n *Node) {
log(debugGui, "wit/gui Standard Window Exit. running os.Exit()")
log(debugGui, "gui.Node.StandardExit() attempt to exit each toolkit plugin")
func StandardExit() {
log("wit/gui Standard Window Exit. running os.Exit()")
log("gui.Node.StandardExit() attempt to exit each toolkit plugin")
for i, aplug := range allPlugins {
log(debugGui, "gui.Node.NewButton()", i, aplug)
log("gui.Node.NewButton()", i, aplug)
if (aplug.Quit != nil) {
aplug.Quit()
}
}
exit("StandardExit")
exit(0)
}

37
node.go
View File

@ -1,15 +1,30 @@
package gui
// import "git.wit.org/wit/gui/toolkit"
import "git.wit.org/wit/gui/toolkit"
/*
generic function to create a new node on the binary tree
*/
func (n *Node) New(title string, t string) *Node {
func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
var newN *Node
newN = addNode(title, n.Width, n.Height)
newN.Widget.Type = t
newN = addNode(title)
newN.widget.Type = t
newN.widget.Action = "New"
newN.Custom = custom
// TODO: This should not be defined for each widget. This has to be stupid
// or wait a second, is this where I send something to a channel?
newN.widget.Custom = func() {
if (newN.Custom == nil) {
log(debugChange, "newT.Custom() == nil. Not doing anything. SEND SOMETHING TO THE CHANNEL")
return
}
log(debugChange, "newT.Custom() START SEND SOMETHING TO THE CHANNEL widget.Name =", newN.widget.Name)
// send something to the channel here????
newN.Custom()
log(debugChange, "newT.Custom() END SEND SOMETHING TO THE CHANNEL widget.Name =", newN.widget.Name)
}
n.Append(newN)
newN.parent = n
@ -19,20 +34,10 @@ func (n *Node) New(title string, t string) *Node {
/*
raw create function for a new node struct
*/
func addNode(title string, width int, height int) *Node {
func addNode(title string) *Node {
n := new(Node)
n.Name = title
n.Width = width
n.Height = height
n.Widget.Name = title
n.Widget.Width = width
n.Widget.Height = height
// no longer a string
// id := Config.prefix + strconv.Itoa(Config.counter)
// n.id = id
n.widget.Name = title
n.id = Config.counter
Config.counter += 1

View File

@ -26,21 +26,24 @@ type aplug struct {
MainOk bool
Init func()
Main func(func ())
Queue func(func ())
// TODO: make Main() main() and never allow the user to call it
// run plugin.Main() when the plugin is loaded
Main func(func ()) // this never returns. Each plugin must have it's own goroutine
Queue func(func ()) // Should this return right away? Should it wait (can it wait?)
Quit func()
NewWindow func(*toolkit.Widget)
// NewWindow func(*toolkit.Widget)
// simplifies passing to the plugin
Send func(*toolkit.Widget, *toolkit.Widget)
NewButton func(*toolkit.Widget, *toolkit.Widget)
NewGroup func(*toolkit.Widget, *toolkit.Widget)
NewCheckbox func(*toolkit.Widget, *toolkit.Widget)
NewTab func(*toolkit.Widget, *toolkit.Widget)
NewLabel func(*toolkit.Widget, *toolkit.Widget)
NewTextbox func(*toolkit.Widget, *toolkit.Widget)
NewSlider func(*toolkit.Widget, *toolkit.Widget)
NewSpinner func(*toolkit.Widget, *toolkit.Widget)
NewDropdown func(*toolkit.Widget, *toolkit.Widget)
AddDropdownName func(*toolkit.Widget, string)
SetDropdownName func(*toolkit.Widget, string)
SetDebugToolkit func(bool)
SetDebugChange func(bool)
@ -73,27 +76,27 @@ func LoadToolkit(name string) bool {
// newPlug.Ok = true
newPlug.name = name
// map all the functions
// deprecate Init(?)
newPlug.Init = loadFuncE(&newPlug, "Init")
newPlug.Quit = loadFuncE(&newPlug, "Quit")
// this should be laodFuncE()
// should make a goroutine that never exits
newPlug.Main = loadFuncF(&newPlug, "Main")
// should send things to the goroutine above
newPlug.Queue = loadFuncF(&newPlug, "Queue")
newPlug.NewWindow = loadFunc1(&newPlug, "NewWindow")
// unload the plugin and restore state
newPlug.Quit = loadFuncE(&newPlug, "Quit")
newPlug.NewButton = loadFunc2(&newPlug, "NewButton")
newPlug.NewGroup = loadFunc2(&newPlug, "NewGroup")
newPlug.NewCheckbox = loadFunc2(&newPlug, "NewCheckbox")
newPlug.NewTab = loadFunc2(&newPlug, "NewTab")
newPlug.NewLabel = loadFunc2(&newPlug, "NewLabel")
newPlug.NewTextbox = loadFunc2(&newPlug, "NewTextbox")
newPlug.NewSlider = loadFunc2(&newPlug, "NewSlider")
newPlug.NewSpinner = loadFunc2(&newPlug, "NewSpinner")
// Sends a widget (button, checkbox, etc) and it's parent widget
// This includes instructions like "Add", "Delete", "Disable", etc
newPlug.Send = loadFunc2(&newPlug, "Send")
// newPlug.NewGroup = loadFunc2(&newPlug, "NewGroup")
newPlug.NewDropdown = loadFunc2(&newPlug, "NewDropdown")
newPlug.AddDropdownName = loadFuncS(&newPlug, "AddDropdownName")
newPlug.SetDropdownName = loadFuncS(&newPlug, "SetDropdownName")
newPlug.SetDebugToolkit = loadFuncB(&newPlug, "SetDebugToolkit")
newPlug.SetDebugChange = loadFuncB(&newPlug, "SetDebugChange")
@ -275,3 +278,16 @@ func loadfile(filename string) *plugin.Plugin {
log(debugGui, "plugin WORKED =", filename)
return plug
}
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
func send(p *Node, c *Node) {
for _, aplug := range allPlugins {
log(debugPlugin, "Send() aplug =", aplug.name, "name =", c.widget.Name)
if (aplug.Send == nil) {
log(debugPlugin, "\tSend() failed (aplug.Selete = nil) for", aplug.name)
continue
}
aplug.Send(&c.parent.widget, &c.widget)
}
}

View File

@ -1,22 +1,16 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
func (n *Node) NewSlider(name string, x int, y int) *Node {
newNode := n.New(name, "Slider")
newNode.Widget.X = x
newNode.Widget.Y = y
newNode.Widget.Custom = func() {
log(debugGui, "even newer clicker() name in NewSlider", newNode.Widget)
}
for _, aplug := range allPlugins {
log(debugGui, "gui.NewSlider() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewSlider == nil) {
log(debugGui, "\tgui.NewSlider() aplug.NewSlider = nil", aplug.name)
continue
}
aplug.NewSlider(&n.Widget, &newNode.Widget)
}
newNode := n.New(name, toolkit.Slider, func() {
log(debugGui, "even newer clicker() name in NewSlider name =", name)
})
newNode.widget.X = x
newNode.widget.Y = y
send(n, newNode)
return newNode
}

View File

@ -1,22 +1,16 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
func (n *Node) NewSpinner(name string, x int, y int) *Node {
newNode := n.New(name, "Spinner")
newNode.Widget.X = x
newNode.Widget.Y = y
newNode.Widget.Custom = func() {
log(debugGui, "even newer clicker() name in NewSpinner", newNode.Widget)
}
for _, aplug := range allPlugins {
log(debugGui, "gui.NewSpinner() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewSpinner == nil) {
log(debugGui, "\tgui.NewSpinner() aplug.NewSpinner = nil", aplug.name)
continue
}
aplug.NewSpinner(&n.Widget, &newNode.Widget)
}
newNode := n.New(name, toolkit.Spinner, func() {
log(debugGui, "even newer clicker() name in NewSpinner name =", name)
})
newNode.widget.X = x
newNode.widget.Y = y
send(n, newNode)
return newNode
}

View File

@ -25,8 +25,11 @@ var Config GuiConfig
type GuiArgs struct {
Toolkit []string `arg:"--toolkit" help:"The order to attempt loading plugins [gocui,andlabs,gtk,qt]"`
GuiDebug bool `arg:"--gui-debug" help:"debug the GUI"`
GuiVerbose bool `arg:"--gui-verbose" help:"enable all GUI flags"`
}
// var verbose GuiArgs.GuiDebug
type GuiConfig struct {
// This is the master node. The Binary Tree starts here
master *Node
@ -41,6 +44,9 @@ type GuiConfig struct {
depth int
counter int // used to make unique ID's
prefix string
ActionCh1 chan int
ActionCh2 chan int
}
// The Node is a binary tree. This is how all GUI elements are stored
@ -48,7 +54,7 @@ type GuiConfig struct {
type Node struct {
id int
Widget toolkit.Widget
widget toolkit.Widget
// deprecate these and use toolkit.Widget
Name string
@ -56,16 +62,15 @@ type Node struct {
Height int
// this function is run when there are mouse or keyboard events
OnChanged func(*Node)
Custom func()
parent *Node
children []*Node
// is keeping
// deprecate these things if they don't really need to exist
custom func()
checked bool
text string
// checked bool
// text string
}
func (n *Node) Parent() *Node {

13
tab.go
View File

@ -1,22 +1,15 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
// This function should make a new node with the parent and
// the 'tab' as a child
func (n *Node) NewTab(text string) *Node {
newNode := n.New(text, "Tab")
for _, aplug := range allPlugins {
log(debugGui, "gui.NewTab() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewTab == nil) {
log(debugGui, "\tgui.NewTab() aplug.NewTab = nil", aplug.name)
continue
}
aplug.NewTab(&n.Widget, &newNode.Widget)
}
newNode := n.New(text, toolkit.Tab, nil)
send(n, newNode)
return newNode
}

View File

@ -1,20 +1,14 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
func (n *Node) NewTextbox(name string) *Node {
newNode := n.New(name, "Textbox")
newNode.Widget.Custom = func() {
log(debugGui, "wit/gui clicker()NewTextBox BUT IS EMPTY. FIXME", newNode.Widget)
}
for _, aplug := range allPlugins {
log(debugGui, "gui.NewTextbox() aplug =", aplug.name, "name =", newNode.Widget.Name)
if (aplug.NewTextbox == nil) {
log(debugGui, "\tgui.NewTextbox() aplug.NewTextbox = nil", aplug.name)
continue
}
aplug.NewTextbox(&n.Widget, &newNode.Widget)
}
newNode := n.New(name, toolkit.Textbox, func() {
log(debugGui, "wit/gui clicker()NewTextBox BUT IS EMPTY. FIXME name =", name)
})
send(n, newNode)
return newNode
}

View File

@ -11,7 +11,7 @@ func (t *andlabsT) GetBox() *ui.Box {
// create a new box
func (t *andlabsT) NewBox() *andlabsT {
log(debugToolkit, "gui.Toolbox.NewBox() START create default")
t.Dump()
t.Dump(debugToolkit)
if (t.uiGroup != nil) {
log(debugToolkit, "\tgui.Toolbox.NewBox() is a Group")
var newTK andlabsT
@ -49,6 +49,6 @@ func (t *andlabsT) NewBox() *andlabsT {
return &newT
}
log(debugToolkit, "\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box")
t.Dump()
t.Dump(debugToolkit)
return nil
}

View File

@ -7,7 +7,7 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) {
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
var t, newt *andlabsT
var b *ui.Button
log(debugToolkit, "gui.andlabs.NewButton()", w.Name)
@ -25,19 +25,11 @@ func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) {
b = ui.NewButton(w.Name)
newt.uiButton = b
newt.tw = w
newt.parent = t
b.OnClicked(func(*ui.Button) {
log(debugChange, "TODO: SHOULD LEAVE Button click HERE VIA channels. button name =", w.Name)
log(debugChange, "FOUND WIDGET =", w)
if (w.Custom == nil) {
log(debugChange, "WIDGET DOES NOT have Custom()")
log(debugChange, "TODO: NOTHING TO DO button name =", w.Name)
return
}
// t.Dump()
// newt.Dump()
log(debugChange, "Running w.Custom()")
w.Custom()
newt.commonChange(newt.tw)
})
log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box parent t:", w.Name)
@ -55,3 +47,41 @@ func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) {
mapWidgetsToolkits(w, newt)
}
func doButton(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newButton(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Button() ct.broken", ct)
return
}
if (ct.uiButton == nil) {
log(true, "Button() uiButton == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiButton.Enable()
case "Disable":
ct.uiButton.Disable()
case "Show":
ct.uiButton.Show()
case "Hide":
ct.uiButton.Hide()
case "Set":
ct.uiButton.SetText(c.S)
default:
log(true, "Can't do", c.Action, "to a Button")
}
}

View File

@ -1,36 +1,29 @@
package main
import "git.wit.org/wit/gui/toolkit"
import (
"git.wit.org/wit/gui/toolkit"
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
func (t andlabsT) NewCheckbox(name string, f func()) *andlabsT {
log(debugToolkit, "gui.Toolkit.NewCheckbox()", name)
func (t andlabsT) NewCheckbox(w *toolkit.Widget) *andlabsT {
log(debugToolkit, "NewCheckbox()", w.Name, w.Type)
var newt andlabsT
newt.tw = w
if t.broken() {
return nil
}
c := ui.NewCheckbox(name)
c := ui.NewCheckbox(w.Name)
newt.uiCheckbox = c
newt.uiBox = t.uiBox
t.uiBox.Append(c, stretchy)
// newt.Custom = f
c.OnToggled(func(spin *ui.Checkbox) {
// log(debugToolkit, "gui.Toolkit.NewCheckbox() clicked", name)
newt.commonChange("Checkbox")
/*
if (f != nil) {
log(debugToolkit, "Run custom() here", f)
log(SPEW, f)
f()
} else {
log(debugToolkit, "No custom() function here")
}
*/
newt.tw.B = newt.Checked()
log(debugChange, "val =", newt.tw.B)
newt.commonChange(newt.tw)
})
return &newt
@ -45,25 +38,52 @@ func (t andlabsT) Checked() bool {
}
func NewCheckbox(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugToolkit, "gui.andlabs.NewCheckbox()", w.Name)
log(debugToolkit, "NewCheckbox()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
listMap()
listMap(debugError)
return
}
newt := t.NewCheckbox(w.Name, w.Custom)
newt.Custom = w.Custom
/*
if (w.Custom != nil) {
log(true, "go.andlabs.NewCheckbox() toolkit struct == nil. name=", parentW.Name, w.Name)
log(true, "Run custom() START here", w.Custom)
w.Custom()
log(true, "Run custom() END")
// exit("ran it here")
} else {
log(true, "No custom() function here")
// exit("nothing here")
}
*/
newt := t.NewCheckbox(w)
mapWidgetsToolkits(w, newt)
}
func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
NewCheckbox(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "checkbox() ct.broken", ct)
return
}
if (ct.uiCheckbox == nil) {
log(true, "checkbox() uiCheckbox == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiCheckbox.Enable()
case "Disable":
ct.uiCheckbox.Disable()
case "Show":
ct.uiCheckbox.Show()
case "Hide":
ct.uiCheckbox.Hide()
case "Set":
ct.uiCheckbox.SetText(c.S)
ct.uiCheckbox.SetChecked(c.B)
default:
log(true, "Can't do", c.Action, "to a checkbox")
}
}

View File

@ -1,5 +1,9 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func init() {
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
@ -7,79 +11,52 @@ func init() {
setDefaultBehavior(true)
}
func (t andlabsT) commonChange(widget string) {
s := t.String()
log(debugChange, "commonChange() START widget =", widget)
log(debugChange, "commonChange() t.String =", s)
if (t.OnChanged != nil) {
// log(debugChange, "commonChange() toolkit.OnChanged() START")
// t.OnChanged(&t)
exit("OnChanged is not implemented. TODO: FIX THIS")
func (t andlabsT) commonChange(tw *toolkit.Widget) {
log(debugChange, "commonChange() START widget =", t.Name, t.Type)
if (tw == nil) {
log(true, "commonChange() What the fuck. there is no widget t.tw == nil")
return
}
if (t.Custom != nil) {
log(debugChange, "commonChange() START toolkit.Custom()")
t.Custom()
log(debugChange, "commonChange() END toolkit.Custom()")
if (tw.Custom == nil) {
log(debugChange, "commonChange() END Widget.Custom() = nil", t.tw.Name, t.tw.Type)
return
}
if (widget == "Checkbox") {
log(debugChange, "commonChange() END Need to read the Checkbox value")
return
}
if (widget == "Dropdown") {
t.getDropdown()
if (t.tw == nil) {
log(debugChange, "commonChange() END tw.Custom == nil")
}
if (t.tw.Custom == nil) {
log(debugChange, "commonChange() END Dropdown (no custom())")
}
t.tw.Custom()
log(debugChange, "commonChange() END Dropdown")
return
}
log(debugChange, "commonChange() t.String =", s)
log(debugChange, "commonChange() ENDED without finding any callback")
}
func (t *andlabsT) getDropdown() {
log(debugChange, "commonChange() Need to read the dropdown menu")
if (t.uiCombobox == nil) {
log(debugChange, "commonChange() END BAD NEWS. t.uiCombobox == nil")
return
}
i := t.uiCombobox.Selected()
log(debugChange, "commonChange() t.uiCombobox = ", i)
if (t.tw == nil) {
log(debugChange, "commonChange() END tw = nil")
return
}
t.tw.S = t.String()
log(debugChange, "commonChange() END tw = ", t.tw)
return
tw.Custom()
log(debugChange, "commonChange() END Widget.Custom()", t.tw.Name, t.tw.Type)
}
// does some sanity checks on the internal structs of the binary tree
// TODO: probably this should not panic unless it's running in devel mode (?)
// TODO: redo this now that WidgetType is used and send() is used to package plugins
func (t *andlabsT) broken() bool {
if (t.parent != nil) {
return false
}
if (t.uiBox == nil) {
if (t.uiWindow != nil) {
log(debugToolkit, "gui.Toolkit.UiBox == nil. This is an empty window. Try to add a box")
log(debugToolkit, "UiBox == nil. This is an empty window. Try to add a box")
t.NewBox()
return false
}
log(debugToolkit, "gui.Toolkit.UiBox == nil. I can't add a widget without a place to put it")
log(true, "UiBox == nil. I can't add a widget without a place to put it")
// log(debugToolkit, "probably could just make a box here?")
// corruption or something horrible?
t.Dump(true)
panic("wit/gui toolkit/andlabs func broken() invalid goroutine access into this toolkit?")
panic("wit/gui toolkit/andlabs func broken() this probably should not cause the app to panic here (?)")
return true
}
if (t.uiWindow == nil) {
log(debugToolkit, "gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)")
forceDump(t)
log(debugToolkit, "UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)")
t.Dump(debugToolkit)
return false
}
return false
}
func broken(w *toolkit.Widget) bool {
if (w == nil) {
log(true, "widget == nil. I can't do anything widget")
return true
}
return false
}

View File

@ -1,6 +1,6 @@
package main
// import "git.wit.org/wit/gui/toolkit"
import "git.wit.org/wit/gui/toolkit"
import "github.com/davecgh/go-spew/spew"
@ -15,6 +15,8 @@ var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugError bool = true
// var DebugToolkit bool
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
@ -59,42 +61,35 @@ func (t *andlabsT) String() string {
return t.GetText()
}
func forceDump(t *andlabsT) {
tmp := debugToolkit
debugToolkit = true
t.Dump()
debugToolkit = tmp
}
func (t *andlabsT) GetText() string {
log(debugToolkit, "gui.Toolkit.GetText() Enter debugToolkit=", debugToolkit)
log(debugToolkit, "GetText() Enter debugToolkit=", debugToolkit)
if (t.uiEntry != nil) {
log(debugToolkit, "gui.Toolkit.uiEntry.Text() =", t.uiEntry.Text())
log(debugToolkit, "uiEntry.Text() =", t.uiEntry.Text())
return t.uiEntry.Text()
}
if (t.uiMultilineEntry != nil) {
log(debugToolkit, "gui.Toolkit.uiMultilineEntry.Text() =", t.uiMultilineEntry.Text())
log(debugToolkit, "uiMultilineEntry.Text() =", t.uiMultilineEntry.Text())
text := t.uiMultilineEntry.Text()
log(debugToolkit, "gui.Toolkit.uiMultilineEntry.Text() =", text)
log(debugToolkit, "uiMultilineEntry.Text() =", text)
t.text = text
return text
}
if (t.uiCombobox != nil) {
log(debugToolkit, "gui.Toolkit.uiCombobox() =", t.text)
log(debugToolkit, "uiCombobox() =", t.text)
return t.text
}
return ""
}
func (t *andlabsT) SetText(s string) bool {
log(debugToolkit, "gui.Toolkit.Text() SetText() Enter")
log(debugToolkit, "Text() SetText() Enter")
if (t.uiEntry != nil) {
log(debugToolkit, "gui.Toolkit.Value() =", t.uiEntry.Text)
log(debugToolkit, "Value() =", t.uiEntry.Text)
t.uiEntry.SetText(s)
return true
}
if (t.uiMultilineEntry != nil) {
log(debugToolkit, "gui.Toolkit.Value() =", t.uiMultilineEntry.Text)
log(debugToolkit, "Value() =", t.uiMultilineEntry.Text)
t.uiMultilineEntry.SetText(s)
return true
}
@ -103,91 +98,101 @@ func (t *andlabsT) SetText(s string) bool {
func sanity(t *andlabsT) bool {
if (debugToolkit) {
log(debugToolkit, "gui.Toolkit.Value() Enter")
log(debugToolkit, "Value() Enter")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t.uiEntry == nil) {
log(debugToolkit, "gui.Toolkit.Value() =", t.uiEntry.Text)
log(debugToolkit, "Value() =", t.uiEntry.Text)
return false
}
return true
}
func (t *andlabsT) SetValue(i int) bool {
log(debugToolkit, "gui.Toolkit.SetValue() START")
log(debugToolkit, "SetValue() START")
if (sanity(t)) {
return false
}
t.Dump()
t.Dump(debugToolkit)
// panic("got to toolkit.SetValue")
return true
}
func (t *andlabsT) Value() int {
if (debugToolkit) {
log(debugToolkit, "gui.Toolkit.Value() Enter")
log(debugToolkit, "Value() Enter")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t == nil) {
log(debugToolkit, "gui.Toolkit.Value() can not get value t == nil")
log(debugToolkit, "Value() can not get value t == nil")
return 0
}
if (t.uiSlider != nil) {
log(debugToolkit, "gui.Toolkit.Value() =", t.uiSlider.Value)
log(debugToolkit, "Value() =", t.uiSlider.Value)
return t.uiSlider.Value()
}
if (t.uiSpinbox != nil) {
log(debugToolkit, "gui.Toolkit.Value() =", t.uiSpinbox.Value)
log(debugToolkit, "Value() =", t.uiSpinbox.Value)
return t.uiSpinbox.Value()
}
log(debugToolkit, "gui.Toolkit.Value() Could not find a ui element to get a value from")
log(debugToolkit, "Value() Could not find a ui element to get a value from")
return 0
}
func (t *andlabsT) Dump() {
if ! debugToolkit {
func (t *andlabsT) Dump(b bool) {
if ! b {
return
}
log(debugToolkit, "gui.Toolkit.Dump() Name = ", t.Name, t.Width, t.Height)
log(b, "Name = ", t.Name, t.Width, t.Height)
if (t.uiBox != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiBox =", t.uiBox)
log(b, "uiBox =", t.uiBox)
}
if (t.uiButton != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiButton =", t.uiButton)
log(b, "uiButton =", t.uiButton)
}
if (t.uiCombobox != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiCombobox =", t.uiCombobox)
log(b, "uiCombobox =", t.uiCombobox)
}
if (t.uiWindow != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiWindow =", t.uiWindow)
log(b, "uiWindow =", t.uiWindow)
}
if (t.uiTab != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiTab =", t.uiTab)
log(b, "uiTab =", t.uiTab)
}
if (t.uiGroup != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiGroup =", t.uiGroup)
log(b, "uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiEntry =", t.uiEntry)
log(b, "uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiMultilineEntry =", t.uiMultilineEntry)
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
}
if (t.uiSlider != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiSlider =", t.uiSlider)
log(b, "uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log(debugToolkit, "gui.Toolkit.Dump() uiCheckbox =", t.uiCheckbox)
log(b, "uiCheckbox =", t.uiCheckbox)
}
if (t.OnExit != nil) {
log(debugToolkit, "gui.Toolkit.Dump() OnExit =", t.OnExit)
}
if (t.Custom != nil) {
log(debugToolkit, "gui.Toolkit.Dump() Custom =", t.Custom)
}
log(debugToolkit, "gui.Toolkit.Dump() c =", t.c)
log(debugToolkit, "gui.Toolkit.Dump() val =", t.val)
log(debugToolkit, "gui.Toolkit.Dump() text =", t.text)
widgetDump(b, t.tw)
}
func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) {
log(b, "widget = nil")
return
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)
log(b, "widget.I =", w.I)
log(b, "widget.Width =", w.Width)
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
}

View File

@ -1,20 +1,20 @@
package main
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
"git.wit.org/wit/gui/toolkit"
)
import "git.wit.org/wit/gui/toolkit"
func (t *andlabsT) NewDropdown(title string) *andlabsT {
// make new node here
func (t *andlabsT) NewDropdown(w *toolkit.Widget) *andlabsT {
var newt andlabsT
log(debugToolkit, "gui.Toolbox.NewDropdownCombobox()", title)
log(debugToolkit, "gui.Toolbox.NewDropdown() START", w.Name)
if t.broken() {
return nil
}
newt.tw = w
s := ui.NewCombobox()
newt.uiCombobox = s
newt.uiBox = t.uiBox
@ -27,11 +27,11 @@ func (t *andlabsT) NewDropdown(title string) *andlabsT {
s.OnSelected(func(spin *ui.Combobox) {
i := spin.Selected()
if (newt.val == nil) {
log(debugToolkit, "make map didn't work")
log(debugChange, "make map didn't work")
newt.text = "error"
}
newt.text = newt.val[i]
newt.commonChange("Dropdown")
newt.tw.S = newt.val[i]
newt.commonChange(newt.tw)
})
return &newt
@ -44,6 +44,12 @@ func (t *andlabsT) AddDropdownName(title string) {
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(1)
}
t.c = t.c + 1
}
@ -57,11 +63,10 @@ func NewDropdown(parentW *toolkit.Widget, w *toolkit.Widget) {
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewDropdown() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap()
listMap(debugToolkit)
return
}
newt := t.NewDropdown(w.Name)
newt.Custom = w.Custom
newt.tw = w
newt := t.NewDropdown(w)
mapWidgetsToolkits(w, newt)
}
@ -71,18 +76,21 @@ func AddDropdownName(w *toolkit.Widget, s string) {
t := mapToolkits[w]
if (t == nil) {
log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", w.Name, s)
listMap()
listMap(debugToolkit)
return
}
t.AddDropdownName(s)
}
func SetDropdown(w *toolkit.Widget, i int) {
log(debugToolkit, "gui.andlabs.SetDropdown()", i)
func SetDropdownName(w *toolkit.Widget, s string) {
log(debugChange, "gui.andlabs.SetDropdown()", w.Name, ",", s)
t := mapToolkits[w]
if (t == nil) {
log(debugToolkit, "go.andlabs.SetDropdown() toolkit struct == nil. name=", w.Name, i)
listMap()
log(debugError, "ERROR: SetDropdown() FAILED mapToolkits[w] == nil. name=", w.Name, s)
listMap(debugError)
return
}
t.SetDropdown(i)
t.SetDropdown(1)
t.tw.S = s
}

View File

@ -7,13 +7,13 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugToolkit, "gui.andlabs.NewGroup()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewGroup() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap()
listMap(debugToolkit)
}
newt := t.NewGroup(w.Name)
mapWidgetsToolkits(w, newt)
@ -23,18 +23,23 @@ func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
func (t andlabsT) NewGroup(title string) *andlabsT {
var newt andlabsT
log(debugToolkit, "gui.Toolbox.NewGroup() create", title)
log(debugToolkit, "NewGroup() create", title)
g := ui.NewGroup(title)
g.SetMargined(margin)
if (t.uiBox != nil) {
t.uiBox.Append(g, stretchy)
// TODO: temporary hack to make the output textbox 'fullscreen'
if (title == "output") {
t.uiBox.Append(g, true)
} else {
t.uiBox.Append(g, stretchy)
}
} else if (t.uiWindow != nil) {
t.uiWindow.SetChild(g)
} else {
log(debugToolkit, "gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugToolkit, "probably could just make a box here?")
log(debugError, "NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
@ -47,8 +52,5 @@ func (t andlabsT) NewGroup(title string) *andlabsT {
newt.uiWindow = t.uiWindow
newt.Name = title
t.Dump()
newt.Dump()
// panic("toolkit.NewGroup")
return &newt
}

View File

@ -7,66 +7,74 @@ import (
"git.wit.org/wit/gui/toolkit"
)
var pwLabel *toolkit.Widget
var wLabel *toolkit.Widget
var tmpNewt *andlabsT
func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
var newt *andlabsT
log(debugToolkit, "NewLabel()", w.Name)
func NewLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
pwLabel = parentW
wLabel = w
tmpNewt = new(andlabsT)
tmpNewt.Width = 10
log(debugToolkit, "mapWidgets in ui.QueueMain() START newt =", tmpNewt.Width, tmpNewt)
if (tmpNewt == nil) {
log(debugToolkit, "mapWidgets WHY THE HELL IS THIS NIL?", tmpNewt.Width, tmpNewt)
}
ui.QueueMain(newLabel)
log(true, "sleep(.2) HACK. TODO: wrap spinlock around andlabs.ui goroutine")
// log(true, "sleep(.2) HACK. TODO: verify newLabel() is running inside andlabs/ui goroutine") // verified that worked
sleep(.2)
log(debugToolkit, "mapWidgets parentW/wLabel =", pwLabel)
log(debugToolkit, "mapWidgets new/newt =", tmpNewt)
mapWidgetsToolkits(w, tmpNewt)
/*
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewDropdown() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap()
}
newt := t.NewDropdown(w.Name)
mapWidgetsToolkits(w, newt)
*/
}
func newLabel() {
var t, newt *andlabsT
log(debugToolkit, "gui.andlabs.NewButton()", wLabel.Name)
t = mapToolkits[pwLabel]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewButton() toolkit struct == nil. name=", pwLabel.Name, wLabel.Name)
listMap(debugError)
log(debugError, "ERROR newLabel() listMap()")
log(debugError, "ERROR FFFFFFFFFFFF listMap()")
log(debugError, "ERROR FFFFFFFFFFFF listMap()")
return
}
log(debugToolkit, "NewLabel()", w.Name)
if t.broken() {
return
}
newt = tmpNewt
newt.uiLabel = ui.NewLabel(wLabel.Name)
newt = new(andlabsT)
c := ui.NewLabel(w.Name + " FIX")
newt.uiLabel = c
newt.uiBox = t.uiBox
newt.tw = w
if (defaultBehavior) {
t.uiBox.Append(c, stretchy)
}
log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box parent t:", wLabel.Name)
t.Dump()
log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box new t:", wLabel.Name)
newt.Dump()
mapWidgetsToolkits(w, newt)
}
if (t.uiBox != nil) {
t.uiBox.Append(newt.uiLabel, false)
} else {
log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this label in a box")
func doLabel(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newLabel(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Label() ct.broken", ct)
return
}
if (ct.uiLabel == nil) {
log(true, "Label() uiLabel == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiLabel.Enable()
case "Disable":
ct.uiLabel.Disable()
case "Show":
ct.uiLabel.Show()
case "Hide":
ct.uiLabel.Hide()
case "Set":
ct.uiLabel.SetText(c.S)
default:
log(true, "Can't do", c.Action, "to a Label")
}
}

View File

@ -98,9 +98,8 @@ func log(a ...any) {
if (a == nil) {
return
}
var blah bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(blah)) {
// golog.Println("\t a[0] = bool")
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
if (a[0] == false) {
return
}
@ -111,7 +110,9 @@ func log(a ...any) {
// a = a[1:]
a[0] = "WIT/GUI/Toolkit"
if (debugToolkit) {
spew.Dump(a)
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}

View File

@ -32,20 +32,19 @@ func Main(f func()) {
// For example: Queue(NewWindow())
//
func Queue(f func()) {
log(debugToolkit, "Sending function to ui.QueueMain() (using gtk via andlabs/ui)")
log("THIS MIGHT BREAK")
log(debugToolkit, "Sending function to ui.QueueMain()")
log(true, "THIS DOES BREAK. TODO: wrap this")
ui.QueueMain(f)
// f()
}
func Init() {
log(debugToolkit, "should Init() here")
log(debugToolkit, "Init()")
mapWidgets = make(map[*andlabsT]*toolkit.Widget)
mapToolkits = make(map[*toolkit.Widget]*andlabsT)
}
func Quit() {
log(debugToolkit, "should Quit() here")
// myExit(nil)
log(debugToolkit, "Quit() TODO: close the toolkit cleanly")
}

View File

@ -1,49 +1,104 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
// 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 "git.wit.org/wit/gui/toolkit"
// This is a map between the widgets in wit/gui and the internal structures of gocui
// import "github.com/andlabs/ui"
// import _ "github.com/andlabs/ui/winmanifest"
var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT
// This lists out the know mappings
func listMap() {
log(debugToolkit, "listMap() HERE")
log(debugToolkit, "listMap() HERE")
log(debugToolkit, "listMap() HERE mapWidgets()")
for t, w := range mapWidgets {
log(debugToolkit, "andlabs =", t.Name, "widget =", w.Name)
//
// This should be called ?
// Pass() ?
// This handles all interaction between the wit/gui package (what golang knows about)
// and this plugin that talks to the OS and does scary and crazy things to make
// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses)
//
// Once you are here, you should be in a protected goroutine created by the golang wit/gui package
//
// TODO: make sure you can't escape this goroutine
//
func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) {
log(debugPlugin, "Send() parent = nil")
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugToolkit, "listMap() HERE mapToolkits()")
for w, t := range mapToolkits {
log(debugToolkit, "andlabs =", t, "widget =", w.Name)
forceDump(t)
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
switch c.Type {
case toolkit.Window:
newWindow(c)
case toolkit.Tab:
newTab(p, c)
case toolkit.Group:
newGroup(p, c)
case toolkit.Button:
doButton(p, c)
case toolkit.Checkbox:
doCheckbox(p, c)
case toolkit.Label:
newLabel(p, c)
case toolkit.Textbox:
doTextbox(p, c)
case toolkit.Slider:
newSlider(p, c)
case toolkit.Spinner:
newSpinner(p, c)
default:
log(true, "unknown parent =", p.Name, p.Type)
log(true, "unknown child =", c.Name, c.Type)
log(true, "Don't know how to do", c.Type, "yet")
}
}
func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
if (mapToolkits[w] == nil) {
mapToolkits[w] = t
} else {
log(debugToolkit, "WTF: mapToolkits was sent nil. this should not happen w =", w)
log(debugToolkit, "WTF: mapToolkits was sent nil. this should not happen t =", t.Width)
log(debugToolkit, "WTF: mapToolkits map already set to ", mapToolkits[w])
panic("WTF mapWidgetsToolkits() w == nil")
// delete the child widget from the parent
// p = parent, c = child
func destroy(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "delete()", c.Name, c.Type)
pt := mapToolkits[p]
ct := mapToolkits[c]
if (ct == nil) {
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type)
// this pukes out a whole universe of shit
// listMap()
return
}
if (mapWidgets[t] == nil) {
mapWidgets[t] = w
} else {
log(debugToolkit, "WTF: mapWidgets already installed. w =", w)
log(debugToolkit, "WTF: mapWidgets already installed. t =", t.Width, t)
log(SPEW, &t)
log(SPEW, t)
log(SPEW, *t)
log(debugToolkit, "WTF: mapWidgets already mapped to", mapWidgets[t])
log(SPEW, mapWidgets[t])
panic("WTF. mapWidget andlabs toolkit already mapped to gui toolkit")
switch ct.Type {
case toolkit.Button:
log(true, "Should delete Button here:", c.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", pt.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:", c.Name)
default:
log(true, "Don't know how to delete c =", c.Type, c.Name)
log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
log(true, "Fuckit, let's destroy a button", c.Name, c.Type)
if (ct.uiButton != nil) {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()
}
}
}

View File

@ -7,31 +7,32 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func (t andlabsT) NewSlider(title string, x int, y int) *andlabsT {
func (t andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
// make new node here
log(debugToolkit, "gui.Toolkit.NewSpinbox()", x, y)
log(debugToolkit, w.Name, w.Type, w.X, w.Y)
var newt andlabsT
if (t.uiBox == nil) {
log(debugToolkit, "gui.ToolkitNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugToolkit, "node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugToolkit, "probably could just make a box here?")
exit("internal golang wit/gui/toolkit error")
return nil
}
s := ui.NewSlider(x, y)
s := ui.NewSlider(w.X, w.Y)
newt.uiSlider = s
newt.uiBox = t.uiBox
newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(spin *ui.Slider) {
newt.commonChange("Slider")
newt.commonChange(newt.tw)
})
return &newt
}
func NewSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
@ -40,6 +41,6 @@ func NewSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
newt = t.NewSlider(w.Name, w.X, w.Y)
newt = t.newSlider(w)
mapWidgetsToolkits(w, newt)
}

View File

@ -1,27 +1,43 @@
package main
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
import (
"git.wit.org/wit/gui/toolkit"
func (t andlabsT) NewSpinner(title string, x int, y int) *andlabsT {
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (t andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
// make new node here
log(debugToolkit, "gui.Toolkit.NewSpinner()", x, y)
log(debugToolkit, "newSpinner()", w.X, w.Y)
var newt andlabsT
if (t.uiBox == nil) {
log(debugToolkit, "gui.ToolkitNode.NewSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it")
exit("internal golang wit/gui error")
log(debugToolkit, "newSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it")
return nil
}
s := ui.NewSpinbox(x, y)
s := ui.NewSpinbox(w.X, w.Y)
newt.uiSpinbox = s
newt.uiBox = t.uiBox
newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(s *ui.Spinbox) {
newt.commonChange("Spinner")
newt.commonChange(newt.tw)
})
return &newt
}
func newSpinner(parentW *toolkit.Widget, w *toolkit.Widget) {
var newt *andlabsT
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
newt = t.newSpinner(w)
mapWidgetsToolkits(w, newt)
}

View File

@ -10,31 +10,27 @@ type andlabsT struct {
id string
Name string
Type toolkit.WidgetType
Width int
Height int
tw *toolkit.Widget
OnChanged func(*andlabsT)
OnExit func(*andlabsT)
Custom func()
parent *andlabsT
uiBox *ui.Box
uiBox2 *ui.Box // temporary hack while implementing tabs
uiButton *ui.Button
uiControl *ui.Control
uiCombobox *ui.Combobox
uiCheckbox *ui.Checkbox
uiEntry *ui.Entry
uiMultilineEntry *ui.MultilineEntry
uiGroup *ui.Group
uiLabel *ui.Label
uiSlider *ui.Slider
uiSpinbox *ui.Spinbox
uiTab *ui.Tab
uiText *ui.EditableCombobox
uiWindow *ui.Window
UiWindowBad *ui.Window
// UiWindowBad *ui.Window // erase this
uiMultilineEntry *ui.MultilineEntry
uiEditableCombobox *ui.EditableCombobox
// 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

View File

@ -33,7 +33,7 @@ func (t *andlabsT) newTab(name string) *andlabsT {
if (t.uiTab == nil) {
// this means you have to make a new tab
log(debugToolkit, "gui.toolkit.NewTab() GOOD. This should be the first tab:", name)
newt = newTab(t.uiWindow, name)
newt = rawTab(t.uiWindow, name)
t.uiTab = newt.uiTab
} else {
// this means you have to append a tab
@ -44,9 +44,9 @@ func (t *andlabsT) newTab(name string) *andlabsT {
newt.Name = name
log(debugToolkit, "t:")
t.Dump()
t.Dump(debugToolkit)
log(debugToolkit, "newt:")
newt.Dump()
newt.Dump(debugToolkit)
return newt
}
@ -62,7 +62,7 @@ func tabSetMargined(tab *ui.Tab) {
}
}
func newTab(w *ui.Window, name string) *andlabsT {
func rawTab(w *ui.Window, name string) *andlabsT {
var t andlabsT
log(debugToolkit, "gui.toolkit.NewTab() ADD", name)
@ -118,7 +118,7 @@ func (t *andlabsT) appendTab(name string) *andlabsT {
return &newT
}
func NewTab(parentW *toolkit.Widget, w *toolkit.Widget) {
func newTab(parentW *toolkit.Widget, w *toolkit.Widget) {
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)

View File

@ -5,19 +5,32 @@ import "git.wit.org/wit/gui/toolkit"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
func (t andlabsT) NewTextbox(name string) *andlabsT {
var newt andlabsT
func newTextbox(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugToolkit, "NewTexbox()", w.Name)
log(debugToolkit, "gui.Toolkit.NewTextbox()", name)
t := mapToolkits[parentW]
if (t == nil) {
listMap(debugError)
log(debugError, "newTextbox() listMap()")
log(debugError, "FFFFFFFFFFFF listMap()")
log(debugError, "FFFFFFFFFFFF listMap()")
}
// t.NewTextbox(w)
// func (t andlabsT) NewTextbox(w *toolkit.Widget) *andlabsT {
var newt *andlabsT
newt = new(andlabsT)
log(debugToolkit, "gui.Toolkit.NewTextbox()", w.Name)
if t.broken() {
return nil
return
}
c := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = c
newt.uiBox = t.uiBox
newt.Name = name
newt.Name = w.Name
newt.tw = w
if (defaultBehavior) {
t.uiBox.Append(c, true)
} else {
@ -25,41 +38,59 @@ func (t andlabsT) NewTextbox(name string) *andlabsT {
}
c.OnChanged(func(spin *ui.MultilineEntry) {
newt.commonChange("Textbox")
w.S = newt.uiMultilineEntry.Text()
// this is still dangerous
// newt.commonChange(newt.tw)
log(debugChange, "Not yet safe to trigger on change for ui.MultilineEntry")
})
return &newt
}
func NewTextbox(parentW *toolkit.Widget, w *toolkit.Widget) {
var t, newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTextbox()", w.Name)
t = mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewTextbox() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
if t.broken() {
return
}
newt = new(andlabsT)
newt.uiLabel = ui.NewLabel(w.Name)
newt.uiBox = t.uiBox
log(debugToolkit, "gui.Toolbox.NewTextbox() about to append to Box parent t:", w.Name)
t.Dump()
log(debugToolkit, "gui.Toolbox.NewTextbox() about to append to Box new t:", w.Name)
newt.Dump()
if (t.uiBox != nil) {
t.uiBox.Append(newt.uiLabel, false)
} else {
log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this Textbox in a box")
return
}
mapWidgetsToolkits(w, newt)
}
func doTextbox(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newTextbox(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Textbox() ct.broken", ct)
return
}
if (ct.uiMultilineEntry == nil) {
log(debugError, "Textbox() uiMultilineEntry == nil", ct)
return
}
// the dns control panel isn't crashing anymore (?)
Queue(ct.doSimpleAction)
}
func (t *andlabsT) doSimpleAction() {
if (t.tw == nil) {
log(true, "doSimpleAction() got an empty widget")
log(true, "THIS SHOULD NEVER HAPPEN")
panic("crap. panic. widget == nil")
}
log(debugChange, "Going to attempt:", t.tw.Action)
switch t.tw.Action {
case "Enable":
t.uiMultilineEntry.Enable()
case "Disable":
t.uiMultilineEntry.Disable()
case "Show":
t.uiMultilineEntry.Show()
case "Hide":
t.uiMultilineEntry.Hide()
case "Set":
t.uiMultilineEntry.SetText(t.tw.S)
default:
log(debugError, "Can't do", t.tw.Action, "to a Textbox")
}
}

67
toolkit/andlabs/widget.go Normal file
View File

@ -0,0 +1,67 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
// This is a map between the widgets in wit/gui and the internal structures of gocui
var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT
// This lists out the know mappings
func listMap(b bool) {
log(b, "listMap() HERE")
log(b, "listMap() HERE")
for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name)
}
log(debugToolkit, "listMap() HERE mapToolkits()")
for w, t := range mapToolkits {
log(b, "andlabs =", t, "widget =", w.Name)
t.Dump(b)
}
log(b, "listMap() HERE mapWidgets()")
log(b, "listMap() HERE FIXME. output too big")
}
func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
if ((mapToolkits[w] == nil) && (mapWidgets[t] == nil)) {
log(debugToolkit, "map a new widget", w, t)
mapToolkits[w] = t
mapWidgets[t] = w
return
}
if (mapToolkits[w] != nil) {
tw := mapToolkits[w]
if (tw == nil) {
// logic corruption somewhere? Have you been deleting things recently?
log(true, "mapToolkits[w] is set, but mapWidgets[t] is nil")
panic("WTF mapWidgets[t] == nil")
}
log(true, "mapToolkits[w] is", tw)
if (tw == nil) {
log(true, "BAD map? mapWidgets[w] tw == nil")
} else {
log(true, "BAD map? mapWidgets[w] is", tw)
tw.Dump(true)
}
}
if (mapWidgets[t] != nil) {
wt := mapWidgets[t]
if (mapToolkits[w] == nil) {
// logic corruption somewhere? Have you been deleting things recently?
log(true, "mapWidgets[t] is set, but mapToolkits[w] is nil")
panic("WTF mapToolkits[w] == nil")
}
if (wt == nil) {
log(true, "BAD map? mapWidgets[t] wt == nil")
} else {
log(true, "BAD map? mapWidgets[t] is", wt)
widgetDump(true, wt)
}
}
log(debugToolkit, "map of widget worked", w.Type, ",", w.Name, ",", w.Action)
}

View File

@ -15,8 +15,8 @@ func (t *andlabsT) ErrorWindow(msg1 string, msg2 string) {
ui.MsgBoxError(t.uiWindow, msg1, msg2)
}
func NewWindow(w *toolkit.Widget) {
var t *andlabsT
func newWindow(w *toolkit.Widget) {
var newt *andlabsT
log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
@ -24,34 +24,23 @@ func NewWindow(w *toolkit.Widget) {
log(debugToolkit, "wit/gui plugin error. widget == nil")
return
}
t = new(andlabsT)
// t = NewWindow2(w.Name, w.Width, w.Height)
newt = new(andlabsT)
newt.tw = w
// func NewWindow2(title string, x int, y int) *andlabsT {
// menubar bool is if the OS defined border on the window should be used
win := ui.NewWindow(w.Name, w.Width, w.Height, menubar)
win.SetBorderless(canvas)
win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool {
log(debugToolkit, "ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here")
t.Dump()
if (w.Custom != nil) {
w.Custom()
return true
}
// if (w.Event != nil) {
// w.Event(w)
// return true
// }
log(debugToolkit, "andlabs.ui.Window().OnClosing() was not defined")
return false
newt.commonChange(newt.tw)
return true
})
win.Show()
t.uiWindow = win
t.UiWindowBad = win // deprecate this as soon as possible
t.Name = w.Name
newt.uiWindow = win
// newt.UiWindowBad = win // deprecate this as soon as possible
newt.Name = w.Name
mapWidgetsToolkits(w, t)
mapWidgetsToolkits(w, newt)
return
}

View File

@ -11,8 +11,19 @@ package toolkit
// Event() seems like a good name.
// Could a protobuf be used here? (Can functions be passed?)
type Widget struct {
Name string
Type string // after lots of back and forth, a simple string
Name string // "New", "Delete", "Set", aka something to do
Action string // "New", "Delete", "Set", aka something to do
// Type string // after lots of back and forth, a simple string
Type WidgetType
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
// The string is also used to set the button name
B bool
I int
// maybe safe if there is correctly working Custom() between goroutines
// (still probably not, almost certainly not)
S string // not safe to have 'S'
// This GUI is intended for simple things
// We are not laying out PDF's here
@ -22,49 +33,61 @@ type Widget struct {
X int
Y int
// latest attempt
// Put space around elements to improve look & feel
Margin bool
// Make widgets fill up the space available
Expand bool
// latest attempt. seems to work so far (2023/02/28)
// Hopefully this will be the barrier between the goroutines
Custom func()
// This might be useful to simplify retrieving
// values from things like checkboxes & dropdown's
B bool
I int
S string
// other things I've tried
// Event func(*Widget) *Widget
// OnChanged func(*Widget)
// Custom func(*Widget)
// OnExit func(*Widget)
}
/*
type Widget int
type WidgetType int
// https://ieftimov.com/post/golang-datastructures-trees/
const (
Unknown Widget = iota
Unknown WidgetType = iota
Window
Tab
Group
Frame
Dropbox
Spinner
Button
Checkbox
Dropdown
Label
Textbox
Slider
Spinner
)
func (s Widget) String() string {
func (s WidgetType) String() string {
switch s {
case Window:
return "Window"
case Tab:
return "Tab"
case Group:
return "Group"
case Frame:
return "Frame"
case Button:
return "Button"
case Checkbox:
return "Checkbox"
case Dropdown:
return "Dropdown"
case Label:
return "Label"
case Dropbox:
return "Dropbox"
case Textbox:
return "Textbox"
case Slider:
return "Slider"
case Spinner:
return "Spinner"
case Unknown:
return "Unknown"
}
return "unknown"
return "GuiToolkitTUndefinedType"
}
*/

View File

@ -1,6 +1,7 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
//import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
@ -13,39 +14,33 @@ import (
// my guess).
func NewWindow() *Node {
var newNode *Node
var custom func()
title := Config.Title
// Windows are created off of the master node of the Binary Tree
newNode = Config.master.New(title, "Window")
newNode.Widget.Width = Config.Width
newNode.Widget.Height = Config.Height
// If the user didn't set a custom Exit() use the standard exit() function
// This makes sure the GUI properly closes everything (GTK, QT, console ui, etc exit)
if (Config.Exit != nil) {
log("setting a custom exit")
newNode.custom = func() {
log(debugGui, "setting a custom exit")
custom = func() {
log(debugChange, "Running a custom exit()", Config.Exit)
log(debugChange, "Running a custom exit() Config.Title =", Config.Title)
log(debugChange, "Running a custom exit() Config.Width =", Config.Width)
Config.Exit(newNode)
}
} else {
log("not setting a custom exit")
}
if (newNode.custom == nil) {
newNode.custom = func () {StandardExit(newNode)}
}
newNode.Widget.Custom = newNode.custom
log(debugGui, "gui.Node.Window()", title)
for _, aplug := range allPlugins {
log(debugGui, "gui.Node.NewWindow() toolkit plugin =", aplug.name)
if (aplug.NewWindow == nil) {
log(debugGui, "gui.Node.NewWindow() is nil")
continue
log(debugGui, "setting the standard exit")
custom = func () {
log(debugChange, "Running StandardExit()")
StandardExit()
}
aplug.NewWindow(&newNode.Widget)
}
// Windows are created off of the master node of the Binary Tree
newNode = Config.master.New(Config.Title, toolkit.Window, custom)
newNode.widget.Width = Config.Width
newNode.widget.Height = Config.Height
log(debugGui, "Window()", Config.Title)
send(nil, newNode)
return newNode
}