From 355e5ec968427c2b07b78fec12224f31a65df740 Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Mon, 14 Nov 2022 14:30:28 -0600 Subject: setup building without plugins on windows notes from github remote keep removing os.Exit() rename from andlabs2 back to andlabs rename files for windows andlabs/ui gocui always sets STDOUT a file in /tmp/ Signed-off-by: Jeff Carr --- Makefile | 11 +- README-goreadme.md | 29 ++- README.md | 2 - andlabs.go | 18 ++ cmds/buttonplugin/main.go | 4 +- common.go | 2 +- group.go | 20 -- main.go | 6 +- structs.go | 36 +--- toolkit/andlabs-direct/box.go | 66 +++++++ toolkit/andlabs-direct/button.go | 79 ++++++++ toolkit/andlabs-direct/checkbox.go | 34 ++++ toolkit/andlabs-direct/common.go | 61 ++++++ toolkit/andlabs-direct/demo.go | 92 +++++++++ toolkit/andlabs-direct/dropdown.go | 55 ++++++ toolkit/andlabs-direct/group.go | 42 +++++ toolkit/andlabs-direct/label.go | 21 +++ toolkit/andlabs-direct/main.go | 31 +++ toolkit/andlabs-direct/old/area.go | 136 +++++++++++++ toolkit/andlabs-direct/old/color.go | 31 +++ toolkit/andlabs-direct/old/seperator.go | 25 +++ toolkit/andlabs-direct/old/structs.go | 273 +++++++++++++++++++++++++++ toolkit/andlabs-direct/old/table.go | 150 +++++++++++++++ toolkit/andlabs-direct/old/tableCallbacks.go | 108 +++++++++++ toolkit/andlabs-direct/slider.go | 31 +++ toolkit/andlabs-direct/spinner.go | 30 +++ toolkit/andlabs-direct/structs.go | 249 ++++++++++++++++++++++++ toolkit/andlabs-direct/tab.go | 133 +++++++++++++ toolkit/andlabs-direct/textbox.go | 34 ++++ toolkit/andlabs-direct/window.go | 66 +++++++ toolkit/andlabs/Makefile | 4 + toolkit/andlabs/box.go | 12 +- toolkit/andlabs/button.go | 72 +++---- toolkit/andlabs/checkbox.go | 8 +- toolkit/andlabs/common.go | 6 +- toolkit/andlabs/demo.go | 4 +- toolkit/andlabs/dropdown.go | 49 ++++- toolkit/andlabs/group.go | 32 +++- toolkit/andlabs/label.go | 39 +++- toolkit/andlabs/main.go | 34 +++- toolkit/andlabs/old/area.go | 136 ------------- toolkit/andlabs/old/color.go | 31 --- toolkit/andlabs/old/seperator.go | 25 --- toolkit/andlabs/old/structs.go | 273 --------------------------- toolkit/andlabs/old/table.go | 150 --------------- toolkit/andlabs/old/tableCallbacks.go | 108 ----------- toolkit/andlabs/plugin.go | 43 +++++ toolkit/andlabs/slider.go | 31 ++- toolkit/andlabs/spinner.go | 6 +- toolkit/andlabs/structs.go | 24 +-- toolkit/andlabs/tab.go | 30 ++- toolkit/andlabs/textbox.go | 44 ++++- toolkit/andlabs/window.go | 66 ++++--- toolkit/andlabs2/Makefile | 4 - toolkit/andlabs2/box.go | 66 ------- toolkit/andlabs2/button.go | 67 ------- toolkit/andlabs2/checkbox.go | 34 ---- toolkit/andlabs2/common.go | 61 ------ toolkit/andlabs2/demo.go | 92 --------- toolkit/andlabs2/dropdown.go | 90 --------- toolkit/andlabs2/group.go | 56 ------ toolkit/andlabs2/label.go | 42 ----- toolkit/andlabs2/main.go | 56 ------ toolkit/andlabs2/plugin.go | 43 ----- toolkit/andlabs2/slider.go | 48 ----- toolkit/andlabs2/spinner.go | 30 --- toolkit/andlabs2/structs.go | 249 ------------------------ toolkit/andlabs2/tab.go | 147 --------------- toolkit/andlabs2/textbox.go | 70 ------- toolkit/andlabs2/window.go | 78 -------- toolkit/gocui/gocui.go | 16 +- toolkit/gocui/keybindings.go | 2 +- window.go | 8 - 73 files changed, 2174 insertions(+), 2187 deletions(-) create mode 100644 andlabs.go create mode 100644 toolkit/andlabs-direct/box.go create mode 100644 toolkit/andlabs-direct/button.go create mode 100644 toolkit/andlabs-direct/checkbox.go create mode 100644 toolkit/andlabs-direct/common.go create mode 100644 toolkit/andlabs-direct/demo.go create mode 100644 toolkit/andlabs-direct/dropdown.go create mode 100644 toolkit/andlabs-direct/group.go create mode 100644 toolkit/andlabs-direct/label.go create mode 100644 toolkit/andlabs-direct/main.go create mode 100644 toolkit/andlabs-direct/old/area.go create mode 100644 toolkit/andlabs-direct/old/color.go create mode 100644 toolkit/andlabs-direct/old/seperator.go create mode 100644 toolkit/andlabs-direct/old/structs.go create mode 100644 toolkit/andlabs-direct/old/table.go create mode 100644 toolkit/andlabs-direct/old/tableCallbacks.go create mode 100644 toolkit/andlabs-direct/slider.go create mode 100644 toolkit/andlabs-direct/spinner.go create mode 100644 toolkit/andlabs-direct/structs.go create mode 100644 toolkit/andlabs-direct/tab.go create mode 100644 toolkit/andlabs-direct/textbox.go create mode 100644 toolkit/andlabs-direct/window.go create mode 100644 toolkit/andlabs/Makefile delete mode 100644 toolkit/andlabs/old/area.go delete mode 100644 toolkit/andlabs/old/color.go delete mode 100644 toolkit/andlabs/old/seperator.go delete mode 100644 toolkit/andlabs/old/structs.go delete mode 100644 toolkit/andlabs/old/table.go delete mode 100644 toolkit/andlabs/old/tableCallbacks.go create mode 100644 toolkit/andlabs/plugin.go delete mode 100644 toolkit/andlabs2/Makefile delete mode 100644 toolkit/andlabs2/box.go delete mode 100644 toolkit/andlabs2/button.go delete mode 100644 toolkit/andlabs2/checkbox.go delete mode 100644 toolkit/andlabs2/common.go delete mode 100644 toolkit/andlabs2/demo.go delete mode 100644 toolkit/andlabs2/dropdown.go delete mode 100644 toolkit/andlabs2/group.go delete mode 100644 toolkit/andlabs2/label.go delete mode 100644 toolkit/andlabs2/main.go delete mode 100644 toolkit/andlabs2/plugin.go delete mode 100644 toolkit/andlabs2/slider.go delete mode 100644 toolkit/andlabs2/spinner.go delete mode 100644 toolkit/andlabs2/structs.go delete mode 100644 toolkit/andlabs2/tab.go delete mode 100644 toolkit/andlabs2/textbox.go delete mode 100644 toolkit/andlabs2/window.go diff --git a/Makefile b/Makefile index 7985c4a..db08887 100644 --- a/Makefile +++ b/Makefile @@ -31,9 +31,12 @@ cmds-textbox: make -C cmds/textbox # sync repo to the github backup +# git remote add github git@github.com:witorg/gui.git github: git push origin master git push github master + git push github devel + git push github jcarr @echo @echo check https://github.com/witorg/gui @echo @@ -49,14 +52,14 @@ README.md: doc.go clean: rm -f toolkit/*.so -plugins: plugins-gocui plugins-andlabs2 +plugins: plugins-gocui plugins-andlabs plugins-gocui: make -C toolkit/gocui -plugins-andlabs2: - cd toolkit/andlabs2/ && GO111MODULE="off" go build -buildmode=plugin -o ../andlabs2.so - # make -C toolkit/andlabs2 +plugins-andlabs: + cd toolkit/andlabs/ && GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so + # make -C toolkit/andlabs objdump: objdump -t toolkit/andlabs.so |less diff --git a/README-goreadme.md b/README-goreadme.md index c48da62..5125d3d 100644 --- a/README-goreadme.md +++ b/README-goreadme.md @@ -128,11 +128,11 @@ Creates a window helpful for debugging this package This creates a window that shows how this package works -### func [GetDebug](/structs.go#L25) +### func [GetDebug](/structs.go#L23) `func GetDebug() bool` -### func [GetDebugToolkit](/structs.go#L37) +### func [GetDebugToolkit](/structs.go#L34) `func GetDebugToolkit() bool` @@ -140,7 +140,7 @@ This creates a window that shows how this package works `func GolangDebugWindow()` -### func [IndentPrintln](/structs.go#L188) +### func [IndentPrintln](/structs.go#L159) `func IndentPrintln(a ...interface{})` @@ -160,15 +160,26 @@ loads and initializes a toolkit (andlabs/ui, gocui, etc) This should not pass a function -### func [SetDebug](/structs.go#L29) +### func [Queue](/main.go#L115) + +`func Queue(f func())` + +Other goroutines must use this to access the GUI + +You can not acess / process the GUI thread directly from +other goroutines. This is due to the nature of how +Linux, MacOS and Windows work (they all work differently. suprise. surprise.) +For example: gui.Queue(NewWindow()) + +### func [SetDebug](/structs.go#L27) `func SetDebug(s bool)` -### func [SetDebugToolkit](/structs.go#L41) +### func [SetDebugToolkit](/structs.go#L38) `func SetDebugToolkit(s bool)` -### func [ShowDebugValues](/structs.go#L45) +### func [ShowDebugValues](/structs.go#L42) `func ShowDebugValues()` @@ -195,7 +206,7 @@ This goroutine can be used like a watchdog timer ## Types -### type [GuiConfig](/structs.go#L68) +### type [GuiConfig](/structs.go#L65) `type GuiConfig struct { ... }` @@ -205,13 +216,13 @@ This goroutine can be used like a watchdog timer var Config GuiConfig ``` -### type [GuiDebug](/structs.go#L56) +### type [GuiDebug](/structs.go#L53) `type GuiDebug struct { ... }` This struct can be used with go-arg -### type [Node](/structs.go#L87) +### type [Node](/structs.go#L84) `type Node struct { ... }` diff --git a/README.md b/README.md index 844fee3..652787c 100644 --- a/README.md +++ b/README.md @@ -207,8 +207,6 @@ my guess). ## Sub Packages -* [need-to-redo](./need-to-redo) - * [toolkit](./toolkit) --- diff --git a/andlabs.go b/andlabs.go new file mode 100644 index 0000000..fac4a8b --- /dev/null +++ b/andlabs.go @@ -0,0 +1,18 @@ +// +build windows + +/* + this is a direct compile version of andlabs/ui for windows since + golang on windows does not yet support plugins +*/ +package gui + +import ( + "log" + + "git.wit.org/wit/gui/toolkit/andlabs-direct" +) + +func trythis() { + log.Println("not sure what to try") + toolkit.DebugToolkit = true +} diff --git a/cmds/buttonplugin/main.go b/cmds/buttonplugin/main.go index c296280..cdd8ef3 100644 --- a/cmds/buttonplugin/main.go +++ b/cmds/buttonplugin/main.go @@ -77,8 +77,8 @@ func buttonWindow() { log.Println("world") }) - g.NewButton("LoadToolkit(andlabs2)", func () { - gui.LoadToolkit("andlabs2") + g.NewButton("LoadToolkit(andlabs)", func () { + gui.LoadToolkit("andlabs") }) g.NewButton("LoadToolkit(gocui)", func () { diff --git a/common.go b/common.go index 27b96bd..5e2cd4d 100644 --- a/common.go +++ b/common.go @@ -24,7 +24,7 @@ isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString for _, username := range []string{"userone", "user2", "user-three"} { if !isAlpha(username) { - fmt.Printf("%q is not valid\n", username) + log.Printf("%q is not valid\n", username) } } diff --git a/group.go b/group.go index d82e99a..a0fbe60 100644 --- a/group.go +++ b/group.go @@ -2,24 +2,15 @@ package gui import "log" -// import toolkit "git.wit.org/wit/gui/toolkit/andlabs" -// import newtoolkit "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 newT *toolkit.Toolkit var newNode *Node if (GetDebug()) { log.Println("toolkit.NewGroup() START", name) } -// if (n.toolkit == nil) { -// log.Println("toolkit.NewGroup() toolkit == nil") -// panic("toolkit should never be nil") -// } - newNode = n.New(name) log.Println("gui.Node.NewGroup()", name) @@ -31,16 +22,5 @@ func (n *Node) NewGroup(name string) *Node { aplug.NewGroup(&n.Widget, &newNode.Widget) } - // make a *Node with a *toolkit.Group - // newT = n.toolkit.NewGroup(name) - // newNode.toolkit = newT - // newNode.Dump() - return newNode } - -/* -func (n *Node) AddGroup(title string) *Node { - return n.NewGroup(title + " deprecated AddGroup") -} -*/ diff --git a/main.go b/main.go index ae22dc6..159b84e 100644 --- a/main.go +++ b/main.go @@ -52,12 +52,12 @@ func Init() { // the program didn't specify a plugin. Try to load one // TODO: detect the OS & user preferences to load the best one if (initBAD) { - if (LoadToolkit("andlabs2")) { + if (LoadToolkit("andlabs")) { initBAD = false } } - // andlabs2 gui failed. fall back to the terminal gui (should be compiled into the binary) + // andlabs gui plugin failed. fall back to the terminal gui (should be compiled into the binary) if (initBAD) { if (LoadToolkit("gocui")) { initBAD = false @@ -112,7 +112,7 @@ func Main(f func()) { // other goroutines. This is due to the nature of how // Linux, MacOS and Windows work (they all work differently. suprise. surprise.) // For example: gui.Queue(NewWindow()) -func queue(f func()) { +func Queue(f func()) { log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)") // toolkit.Queue(f) for _, aplug := range allPlugins { diff --git a/structs.go b/structs.go index af0947f..2b37ee0 100644 --- a/structs.go +++ b/structs.go @@ -3,11 +3,9 @@ package gui import ( "log" "reflect" + "git.wit.org/wit/gui/toolkit" ) -// import toolkit "git.wit.org/wit/gui/toolkit/andlabs" -import newtoolkit "git.wit.org/wit/gui/toolkit" - // // All GUI Data Structures and functions that are external // within the toolkit/ abstraction layer @@ -31,7 +29,6 @@ func SetDebug (s bool) { // also set these Config.Debug.Dump = s Config.Debug.Node = s - // toolkit.DebugToolkit = s } func GetDebugToolkit () bool { @@ -92,7 +89,7 @@ type Node struct { Width int Height int - Widget newtoolkit.Widget + Widget toolkit.Widget // this function is run when there are mouse or keyboard events OnChanged func(*Node) @@ -101,9 +98,6 @@ type Node struct { // TODO: make children a double linked list since some toolkits require order (?) children []*Node - // hmm. how do you handle this when the toolkits are plugins? - // toolkit *toolkit.Toolkit - // things that may not really be needed (?) custom func() checked bool @@ -144,26 +138,9 @@ func (n *Node) Dump() { IndentPrintln("OnChanged = ", n.OnChanged) } IndentPrintln("text = ", reflect.ValueOf(n.text).Kind(), n.text) -// if (n.toolkit != nil) { -// IndentPrintln("toolkit = ", reflect.ValueOf(n.toolkit).Kind()) -// n.toolkit.Dump() -// } -// if (n.id == nil) { -// // Node structs should never have a nil id. -// // I probably shouldn't panic here, but this is just to check the sanity of -// // the gui package to make sure it's not exiting -// panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library") -// } IndentPrintln("NODE DUMP END") } -/* -func (n *Node) SetName(name string) { - n.toolkit.SetWindowTitle(name) - return -} -*/ - func (n *Node) Append(child *Node) { n.children = append(n.children, child) if (Config.Debug.Debug) { @@ -175,12 +152,6 @@ func (n *Node) Append(child *Node) { // time.Sleep(3 * time.Second) } -/* -func (n *Node) List() { - findByIdDFS(n, "test") -} -*/ - var listChildrenParent *Node var listChildrenDepth int = 0 var defaultPadding = " " @@ -217,8 +188,7 @@ func (n *Node) ListChildren(dump bool) { log.Println("\t\t\tlistChildrenParent =",listChildrenParent.id) } if (listChildrenParent.id != n.parent.id) { - log.Println("parent.child does not match child.parent") - panic("parent.child does not match child.parent") + log.Fatalln("parent.child does not match child.parent") } } } diff --git a/toolkit/andlabs-direct/box.go b/toolkit/andlabs-direct/box.go new file mode 100644 index 0000000..29a8331 --- /dev/null +++ b/toolkit/andlabs-direct/box.go @@ -0,0 +1,66 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// create a new box +func (t *Toolkit) GetBox() *ui.Box { + return t.uiBox +} + +// create a new box +func (t *Toolkit) NewBox() *Toolkit { + if (DebugToolkit) { + log.Println("gui.Toolbox.NewBox() START create default") + } + t.Dump() + if (t.uiGroup != nil) { + if (DebugToolkit) { + log.Println("\tgui.Toolbox.NewBox() is a Group") + } + var newTK Toolkit + + vbox := ui.NewVerticalBox() + vbox.SetPadded(padded) + t.uiGroup.SetChild(vbox) + newTK.uiBox = vbox + + return &newTK + } + if (t.uiBox != nil) { + if (DebugToolkit) { + log.Println("\tgui.Toolbox.NewBox() is a Box") + } + var newTK Toolkit + + vbox := ui.NewVerticalBox() + vbox.SetPadded(padded) + t.uiBox.Append(vbox, stretchy) + newTK.uiBox = vbox + newTK.Name = t.Name + + return &newTK + } + if (t.uiWindow != nil) { + if (DebugToolkit) { + log.Println("\tgui.Toolbox.NewBox() is a Window") + } + var newT Toolkit + + vbox := ui.NewVerticalBox() + vbox.SetPadded(padded) + t.uiWindow.SetChild(vbox) + newT.uiBox = vbox + newT.Name = t.Name + + // panic("WTF") + return &newT + } + if (DebugToolkit) { + log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box") + } + t.Dump() + return nil +} diff --git a/toolkit/andlabs-direct/button.go b/toolkit/andlabs-direct/button.go new file mode 100644 index 0000000..e0b7d97 --- /dev/null +++ b/toolkit/andlabs-direct/button.go @@ -0,0 +1,79 @@ +package toolkit + +import "log" +// import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// make new Group here +func (t Toolkit) NewButton(name string) *Toolkit { + var newt Toolkit + var b *ui.Button + + if t.broken() { + return nil + } + + if (DebugToolkit) { + log.Println("gui.Toolbox.NewButton() create", name) + } + b = ui.NewButton(name) + newt.uiButton = b + + b.OnClicked(func(*ui.Button) { + log.Println("TODO: IN TOOLKIT GOROUTINE. SHOULD LEAVE HERE VIA channels. button name =", name) + t.Dump() + newt.Dump() + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() Should do something here") + } + if (newt.Custom == nil) { + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() toolkit.Custom == nil") + } + } else { + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() toolkit.Custom() START") + } + newt.Custom() + return + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() toolkit.Custom() END") + } + } + if (t.Custom == nil) { + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() parent toolkit.Custom == nil") + } + } else { + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() START (IS THIS A BAD IDEA?)") + } + t.Custom() + return + if (DebugToolkit) { + log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() END (IS THIS A BAD IDEA?)") + } + } + log.Println("TODO: LEFT TOOLKIT GOROUTINE WITH NOTHING TO DO button name =", name) + }) + + if (DebugToolkit) { + log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", name) + t.Dump() + log.Println("gui.Toolbox.NewButton() about to append to Box new t:", name) + newt.Dump() + } + if (t.uiBox != nil) { + t.uiBox.Append(b, stretchy) + } else if (t.uiWindow != nil) { + t.uiWindow.SetChild(b) + } else { + log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") + log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") + return &t + } + + return &newt +} diff --git a/toolkit/andlabs-direct/checkbox.go b/toolkit/andlabs-direct/checkbox.go new file mode 100644 index 0000000..b3b3121 --- /dev/null +++ b/toolkit/andlabs-direct/checkbox.go @@ -0,0 +1,34 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t Toolkit) NewCheckbox(name string) *Toolkit { + log.Println("gui.Toolkit.NewCheckbox()", name) + var newt Toolkit + + if t.broken() { + return nil + } + + c := ui.NewCheckbox(name) + newt.uiCheckbox = c + newt.uiBox = t.uiBox + t.uiBox.Append(c, stretchy) + + c.OnToggled(func(spin *ui.Checkbox) { + newt.commonChange("Checkbox") + }) + + return &newt +} + +func (t Toolkit) Checked() bool { + if t.broken() { + return false + } + + return t.uiCheckbox.Checked() +} diff --git a/toolkit/andlabs-direct/common.go b/toolkit/andlabs-direct/common.go new file mode 100644 index 0000000..451f9d6 --- /dev/null +++ b/toolkit/andlabs-direct/common.go @@ -0,0 +1,61 @@ +package toolkit + +import "log" + +func init() { + if (DebugToolkit) { + log.Println("gui/toolkit init() Setting defaultBehavior = true") + } + setDefaultBehavior(true) +} + +func (t Toolkit) commonChange(widget string) { + s := t.String() + if (DebugToolkit) { + log.Println("gui.Toolkit.ui.OnChanged() =", s) + } + if (t.OnChanged != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.OnChanged() trying to run toolkit.OnChanged() entered val =", s) + } + t.OnChanged(&t) + return + } + if (t.Custom != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.OnChanged() Running toolkit.Custom()") + t.Dump() + } + t.Custom() + return + } + if (DebugToolkit) { + log.Println("gui.Toolkit.OnChanged() ENDED without finding any callback") + } +} + +// 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 (?) +func (t *Toolkit) broken() bool { + if (t.uiBox == nil) { + if (t.uiWindow != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.UiBox == nil. This is an empty window. Try to add a box") + } + t.NewBox() + return false + } + log.Println("gui.Toolkit.UiBox == nil. I can't add a widget without a place to put it") + // log.Println("probably could just make a box here?") + // corruption or something horrible? + 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.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)") + forceDump(t) + return false + } + return false +} diff --git a/toolkit/andlabs-direct/demo.go b/toolkit/andlabs-direct/demo.go new file mode 100644 index 0000000..7ba1822 --- /dev/null +++ b/toolkit/andlabs-direct/demo.go @@ -0,0 +1,92 @@ +package toolkit + +import "log" + +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 *Toolkit) DemoNumbersPage() { + var w *ui.Window + + log.Println("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 +} diff --git a/toolkit/andlabs-direct/dropdown.go b/toolkit/andlabs-direct/dropdown.go new file mode 100644 index 0000000..ca09a99 --- /dev/null +++ b/toolkit/andlabs-direct/dropdown.go @@ -0,0 +1,55 @@ +package toolkit + +import "log" +import "os" +// import "time" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t *Toolkit) NewDropdown(title string) *Toolkit { + // make new node here + if (DebugToolkit) { + log.Println("gui.Toolbox.NewDropdownCombobox()", title) + } + var newt Toolkit + + if t.broken() { + return nil + } + + s := ui.NewCombobox() + newt.uiCombobox = s + newt.uiBox = t.uiBox + t.uiBox.Append(s, stretchy) + + // initialize the index + newt.c = 0 + newt.val = make(map[int]string) + + s.OnSelected(func(spin *ui.Combobox) { + i := spin.Selected() + if (newt.val == nil) { + log.Println("make map didn't work") + os.Exit(0) + } + newt.text = newt.val[i] + newt.commonChange("Dropdown") + }) + + return &newt +} + +func (t *Toolkit) AddDropdown(title string) { + t.uiCombobox.Append(title) + if (t.val == nil) { + log.Println("make map didn't work") + return + } + t.val[t.c] = title + t.c = t.c + 1 +} + +func (t Toolkit) SetDropdown(i int) { + t.uiCombobox.SetSelected(i) +} diff --git a/toolkit/andlabs-direct/group.go b/toolkit/andlabs-direct/group.go new file mode 100644 index 0000000..5b315a4 --- /dev/null +++ b/toolkit/andlabs-direct/group.go @@ -0,0 +1,42 @@ +package toolkit + +import "log" +import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// make new Group here +func (t Toolkit) NewGroup(title string) *Toolkit { + var newt Toolkit + + if (DebugToolkit) { + log.Println("gui.Toolbox.NewGroup() create", title) + } + g := ui.NewGroup(title) + g.SetMargined(margin) + + if (t.uiBox != nil) { + t.uiBox.Append(g, stretchy) + } else if (t.uiWindow != nil) { + t.uiWindow.SetChild(g) + } else { + log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") + log.Println("probably could just make a box here?") + os.Exit(0) + } + + hbox := ui.NewVerticalBox() + hbox.SetPadded(padded) + g.SetChild(hbox) + + newt.uiGroup = g + newt.uiBox = hbox + newt.uiWindow = t.uiWindow + newt.Name = title + + t.Dump() + newt.Dump() + // panic("toolkit.NewGroup") + return &newt +} diff --git a/toolkit/andlabs-direct/label.go b/toolkit/andlabs-direct/label.go new file mode 100644 index 0000000..2819ff1 --- /dev/null +++ b/toolkit/andlabs-direct/label.go @@ -0,0 +1,21 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t *Toolkit) NewLabel(name string) *Toolkit { + // make new node here + log.Println("gui.Toolbox.NewLabel", name) + + if t.broken() { + return nil + } + var newt Toolkit + newt.uiLabel = ui.NewLabel(name) + newt.uiBox = t.uiBox + t.uiBox.Append(newt.uiLabel, false) + + return &newt +} diff --git a/toolkit/andlabs-direct/main.go b/toolkit/andlabs-direct/main.go new file mode 100644 index 0000000..da639fa --- /dev/null +++ b/toolkit/andlabs-direct/main.go @@ -0,0 +1,31 @@ +package toolkit + +import ( + "log" + + "github.com/andlabs/ui" + // the _ means we only need this for the init() + _ "github.com/andlabs/ui/winmanifest" +) + +func Main(f func()) { + if (DebugToolkit) { + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + } + ui.Main(f) +} + +// Other goroutines must use this to access the GUI +// +// You can not acess / process the GUI thread directly from +// other goroutines. This is due to the nature of how +// Linux, MacOS and Windows work (they all work differently. suprise. surprise.) +// +// For example: Queue(NewWindow()) +// +func Queue(f func()) { + if (DebugToolkit) { + log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)") + } + ui.QueueMain(f) +} diff --git a/toolkit/andlabs-direct/old/area.go b/toolkit/andlabs-direct/old/area.go new file mode 100644 index 0000000..7c42c6c --- /dev/null +++ b/toolkit/andlabs-direct/old/area.go @@ -0,0 +1,136 @@ +package gui + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +import "github.com/davecgh/go-spew/spew" + +func makeGenericArea(gb *GuiBox, newText *ui.AttributedString, custom func(*GuiButton)) { + // make this button just to get the default font (but don't display the button) + // There should be another way to do this (?) + var newB *GuiButton + newB = CreateFontButton(gb, "AREA") + newB.Box = gb + newB.Custom = custom + + gw := gb.Window + // initialize the GuiArea{} + gw.Area = new(GuiArea) + gw.Area.Button = newB + gw.Area.Box = gb + gw.Area.UiAttrstr = newText + gw.Area.UiArea = ui.NewArea(gw.Area) + + if (Config.Debug) { + spew.Dump(gw.Area.UiArea) + log.Println("DEBUGGING", Config.Debug) + } else { + log.Println("NOT DEBUGGING AREA mhAH.Button =", gw.Area.Button) + } +} + +func AreaAppendText(newText *ui.AttributedString, what string, attrs ...ui.Attribute) { + start := len(newText.String()) + end := start + len(what) + newText.AppendUnattributed(what) + for _, a := range attrs { + newText.SetAttribute(a, start, end) + } +} + +func appendWithAttributes(newText *ui.AttributedString, what string, attrs ...ui.Attribute) { + start := len(newText.String()) + end := start + len(what) + newText.AppendUnattributed(what) + for _, a := range attrs { + newText.SetAttribute(a, start, end) + } +} + +func (ah GuiArea) Draw(a *ui.Area, p *ui.AreaDrawParams) { + tl := ui.DrawNewTextLayout(&ui.DrawTextLayoutParams{ + String: ah.UiAttrstr, + DefaultFont: ah.Button.FB.Font(), + Width: p.AreaWidth, + Align: ui.DrawTextAlign(1), + }) + p.Context.Text(tl, 0, 0) + defer tl.Free() +} + +func (ah GuiArea) MouseEvent(a *ui.Area, me *ui.AreaMouseEvent) { + if (Config.Debug) { + log.Println("GOT MouseEvent() ah.Button =", ah.Button) + spew.Dump(me) + } + if (me.Down == 1) { + log.Println("GOT MOUSE DOWN") + log.Println("GOT MOUSE DOWN ah.Button =", ah.Button) + log.Println("GOT MOUSE UP ah.Button.FB =", ah.Button.FB) + } + if (me.Up == 1) { + log.Println("GOT MOUSE UP") + log.Println("GOT MOUSE UP ah.Button =", ah.Button) + log.Println("GOT MOUSE UP ah.Button.FB =", ah.Button.FB) + if (ah.Button.Custom != nil) { + ah.Button.Custom(ah.Button) + } else if (Data.MouseClick != nil) { + Data.MouseClick(ah.Button) + } + } +} + +func (ah GuiArea) MouseCrossed(a *ui.Area, left bool) { + log.Println("GOT MouseCrossed()") +} + +func (ah GuiArea) DragBroken(a *ui.Area) { + log.Println("GOT DragBroken()") +} + +// TODO: fix KeyEvents +func (ah GuiArea) KeyEvent(a *ui.Area, ke *ui.AreaKeyEvent) (handled bool) { + log.Println("GOT KeyEvent()") + if (ke.Key == 10) { + log.Println("GOT ENTER") + log.Println("GOT ENTER") + log.Println("GOT ENTER") + } + if (ke.Key == 32) { + log.Println("GOT ENTER") + log.Println("GOT ENTER") + log.Println("GOT ENTER") + } + spew.Dump(ke) + return false +} + +func (b *GuiBox) ShowTextBox(newText *ui.AttributedString, custom func(*GuiButton), name string) { + log.Println("ShowTextBox() START") + + gw := b.Window + if (gw == nil) { + log.Println("ShowTextBox() ERROR gw = nil") + return + } + log.Println("ShowTextBox() START gw =", gw) + + /* + var newbox *GuiBox + newbox = new(GuiBox) + newbox.Window = gw + newbox.Name = name + hbox := ui.NewVerticalBox() + newbox.UiBox = hbox + */ + + // TODO: allow padded & axis here + b.UiBox.SetPadded(true) + + // add(gw.BoxMap["MAINBOX"], newbox) + + makeGenericArea(b, newText, custom) + b.UiBox.Append(b.Window.Area.UiArea, true) +} diff --git a/toolkit/andlabs-direct/old/color.go b/toolkit/andlabs-direct/old/color.go new file mode 100644 index 0000000..cf4a362 --- /dev/null +++ b/toolkit/andlabs-direct/old/color.go @@ -0,0 +1,31 @@ +package gui + +// +// convert between 'standard' golang Color and andlabs/ui Color +// + +// import "log" +// import "fmt" +import "image/color" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func libuiColorToGOlangColor(rgba color.RGBA) ui.TableColor { + /* a hack to see if colors work differently on macos or windows + if (rgba.R == 72) { + log.Println("SETTING COLOR TO NIL") + log.Println("SETTING COLOR TO NIL") + log.Println("SETTING COLOR TO NIL") + return ui.TableColor{} + } + */ + return ui.TableColor{float64(rgba.R) / 256, float64(rgba.G) / 256, float64(rgba.B) / 256, float64(rgba.A) / 256} +} + +/* +func golangColorGOlibuiColorTo (ui.TableColor) (rgba color.RGBA) { + color.RGBA{float64(, 100, 200, 100} + return ui.TableColor{float64(rgba.R) / 256, float64(rgba.G) / 256, float64(rgba.B) / 256, float64(rgba.A) / 256} +} +*/ diff --git a/toolkit/andlabs-direct/old/seperator.go b/toolkit/andlabs-direct/old/seperator.go new file mode 100644 index 0000000..ca152a8 --- /dev/null +++ b/toolkit/andlabs-direct/old/seperator.go @@ -0,0 +1,25 @@ +package gui + +import "log" +import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func HorizontalBreak(box *GuiBox) { + log.Println("VerticalSeparator added to box =", box.Name) + tmp := ui.NewHorizontalSeparator() + if (box == nil) { + return + } + if (box.UiBox == nil) { + return + } + box.UiBox.Append(tmp, false) +} + +func VerticalBreak(box *GuiBox) { + log.Println("VerticalSeparator added to box =", box.Name) + tmp := ui.NewVerticalSeparator() + box.UiBox.Append(tmp, false) +} diff --git a/toolkit/andlabs-direct/old/structs.go b/toolkit/andlabs-direct/old/structs.go new file mode 100644 index 0000000..4a16438 --- /dev/null +++ b/toolkit/andlabs-direct/old/structs.go @@ -0,0 +1,273 @@ +package gui + +import ( + "image/color" + + "github.com/andlabs/ui" +// "golang.org/x/image/font" + + // "github.com/davecgh/go-spew/spew" + + // _ "github.com/andlabs/ui/winmanifest" +) + +// +// All GUI Data Structures and functions that are external +// If you need cross platform support, these might only +// be the safe way to interact with the GUI +// +var Data GuiData +var Config GuiConfig + +type GuiConfig struct { + Title string + Width int + Height int + Exit func(*Node) + + Debug bool + DebugNode bool + DebugTabs bool + DebugTable bool + DebugWindow bool + DebugToolkit bool + + depth int + counter int // used to make unique ID's + prefix string +} + +type GuiData struct { + // a fallback default function to handle mouse events + // if nothing else is defined to handle them + MouseClick func(*GuiButton) + + // A map of all the entry boxes + // AllEntries []*GuiEntry + WindowMap map[string]*GuiWindow + + // Store access to everything via binary tree's + NodeMap map[string]*Node + NodeArray []*Node + NodeSlice []*Node + + // A map of all buttons everywhere on all + // windows, all tabs, across all goroutines + // This is "GLOBAL" + // + // This has to work this way because of how + // andlabs/ui & andlabs/libui work + AllButtons []*GuiButton +// buttonMap map[*ui.Button]*GuiButton +} + +/* +type GuiTab struct { + Name string // field for human readable name + Number int // the andlabs/ui tab index + Window *GuiWindow // the parent Window +} +*/ + +// +// stores information on the 'window' +// +// This merges the concept of andlabs/ui *Window and *Tab +// +// More than one Window is not supported in a cross platform +// sense & may never be. On Windows and MacOS, you have to have +// 'tabs'. Even under Linux, more than one Window is currently +// unstable +// +// This code will make a 'GuiWindow' regardless of if it is +// a stand alone window (which is more or less working on Linux) +// or a 'tab' inside a window (which is all that works on MacOS +// and MSWindows. +// +// This struct keeps track of what is in the window so you +// can destroy and replace it with something else +// +type GuiWindow struct { + Name string // field for human readable name + Width int + Height int + Axis int // does it add items to the X or Y axis + TabNumber *int // the andlabs/ui tab index + + // the callback function to make the window contents + // MakeWindow func(*GuiBox) *GuiBox + + // the components of the window + BoxMap map[string]*GuiBox + // EntryMap map[string]*GuiEntry + + node *Node + + // andlabs/ui abstraction mapping + UiWindow *ui.Window + UiTab *ui.Tab // if this != nil, the window is 'tabbed' +} + +/* +func (w *GuiWindow) Dump() { + log.Println("gui.GuiWindow.Dump() Name = ", w.Name) + log.Println("gui.GuiWindow.Dump() node = ", w.node) + log.Println("gui.GuiWindow.Dump() Width = ", w.Width) + log.Println("gui.GuiWindow.Dump() Height = ", w.Height) +} +*/ + +// GuiBox is any type of ui.Hbox or ui.Vbox +// There can be lots of these for each GuiWindow +type GuiBox struct { + Name string // field for human readable name + Axis int // does it add items to the X or Y axis + Window *GuiWindow // the parent Window + + node *Node + + // andlabs/ui abstraction mapping + UiBox *ui.Box +} + +func (b *GuiBox) Append(child ui.Control, x bool) { + if b.UiBox == nil { + // spew.Dump(b) + // b.Dump() + panic("GuiBox.Append() can't work. UiBox == nil") + return + } + b.UiBox.Append(child, x) +} + +// Note: every mouse click is handled +// as a 'Button' regardless of where +// the user clicks it. You could probably +// call this 'GuiMouseClick' +type GuiButton struct { + Name string // field for human readable name + Box *GuiBox // what box the button click was in + + // a callback function for the main application + Custom func(*GuiButton) + Values interface{} + Color color.RGBA + + // andlabs/ui abstraction mapping + B *ui.Button + FB *ui.FontButton + CB *ui.ColorButton +} + +/* +// +// AREA STRUCTURES START +// AREA STRUCTURES START +// AREA STRUCTURES START +// +type GuiArea struct { + Button *GuiButton // what button handles mouse events + Box *GuiBox + + UiAttrstr *ui.AttributedString + UiArea *ui.Area +} + +type FontString struct { + S string + Size int + F font.Face + W font.Weight +} + +// +// AREA STRUCTURES END +// AREA STRUCTURES END +// AREA STRUCTURES END +// + +// +// TABLE DATA STRUCTURES START +// TABLE DATA STRUCTURES START +// TABLE DATA STRUCTURES START +// + +// +// This is the structure that andlabs/ui uses to pass information +// to the GUI. This is the "authoritative" data. +// +type TableData struct { + RowCount int // This is the number of 'rows' which really means data elements not what the human sees + RowWidth int // This is how wide each row is + Rows []RowData // This is all the table data by row + generatedColumnTypes []ui.TableValue // generate this dynamically + + Cells [20]CellData + Human [20]HumanMap + + Box *GuiBox + + lastRow int + lastColumn int +} + +// +// This maps the andlabs/ui & libui components into a "human" +// readable cell reference list. The reason is that there +// are potentially 3 values for each cell. The Text, the Color +// and an image. These are not always needed so the number +// of fields varies between 1 and 3. Internally, the toolkit +// GUI abstraction needs to list all of them, but it's then +// hard to figure out which column goes with the columns that +// you see when you visually are looking at it like a spreadsheet +// +// This makes a map so that we can say "give me the value at +// row 4 and column 2" and find the fields that are needed +// +// TODO: re-add images and the progress bar (works in andlabs/ui) +// +type HumanCellData struct { + Name string // what kind of row is this? + Text string + TextID int + Color color.RGBA + ColorID int + Button *GuiButton +} + +type HumanMap struct { + Name string // what kind of row is this? + TextID int + ColorID int +} + +type TableColumnData struct { + Index int + CellType string + Heading string + Color string +} + +type CellData struct { + Index int + HumanID int + Name string // what type of cell is this? +} + +// hmm. will this stand the test of time? +type RowData struct { + Name string // what kind of row is this? + Status string // status of the row? + // + // TODO: These may or may not be implementable + // depending on if it's possible to detect the bgcolor or what row is selected + // click func() // what function to call if the user clicks on it + // doubleclick func() // what function to call if the user double clicks on it + // + HumanData [20]HumanCellData +} +*/ + +// +// TABLE DATA STRUCTURES END +// diff --git a/toolkit/andlabs-direct/old/table.go b/toolkit/andlabs-direct/old/table.go new file mode 100644 index 0000000..92ae871 --- /dev/null +++ b/toolkit/andlabs-direct/old/table.go @@ -0,0 +1,150 @@ +// based off andlabs/ui/examples/table.go + +package gui + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// import "github.com/davecgh/go-spew/spew" + +func initRowBTcolor(mh *TableData, intBG int, cell TableColumnData) { + humanInt := cell.Index + + // setup mapping from human readable indexes to internal libUI indexes + mh.Human[humanInt].Name = "BG" + mh.Human[humanInt].ColorID = intBG + mh.Human[humanInt].TextID = -1 + + mh.Cells[intBG].Name = "BG" + mh.Cells[intBG].HumanID = humanInt + + log.Println("intBG, humanInt", intBG, humanInt) +} + +func initRowButtonColumn(mh *TableData, buttonID int, junk string, cell TableColumnData) { + humanInt := cell.Index + + // setup mapping from human readable indexes to internal libUI indexes + mh.Human[humanInt].Name = "BUTTON" + mh.Human[humanInt].ColorID = -1 + mh.Human[humanInt].TextID = buttonID + + mh.Cells[buttonID].Name = "BUTTON" + mh.Cells[buttonID].HumanID = humanInt + + log.Println("buttonID, humanInt", buttonID, humanInt) +} + +func initRowTextColorColumn(mh *TableData, stringID int, colorID int, junk string, color ui.TableColor, cell TableColumnData) { + humanInt := cell.Index + + // setup mapping from human readable indexes to internal libUI indexes + mh.Human[humanInt].Name = "EDIT" + mh.Human[humanInt].ColorID = colorID + mh.Human[humanInt].TextID = stringID + + // text for Column humanInt + mh.Cells[stringID].Name = "EDIT" + mh.Cells[stringID].HumanID = humanInt + + mh.Cells[colorID].Name = "COLOR" + mh.Cells[colorID].HumanID = humanInt +} + +func initRowTextColumn(mh *TableData, stringID int, junk string, cell TableColumnData) { + humanInt := cell.Index + + // setup mapping from human readable indexes to internal libUI indexes + mh.Human[humanInt].Name = "EDIT" + mh.Human[humanInt].ColorID = -1 + mh.Human[humanInt].TextID = stringID + + mh.Cells[stringID].Name = "EDIT" + mh.Cells[stringID].HumanID = humanInt +} + +func InitColumns(mh *TableData, parts []TableColumnData) { + tmpBTindex := 0 + humanID := 0 + for key, foo := range parts { + log.Println("key, foo =", key, foo) + + parts[key].Index = humanID + humanID += 1 + + if (foo.CellType == "BG") { + mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{}) + initRowBTcolor (mh, tmpBTindex, parts[key]) + tmpBTindex += 1 + } else if (foo.CellType == "BUTTON") { + mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) + initRowButtonColumn (mh, tmpBTindex, parts[key].Heading, parts[key]) + tmpBTindex += 1 + } else if (foo.CellType == "TEXTCOLOR") { + mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) + mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{}) + initRowTextColorColumn(mh, tmpBTindex, tmpBTindex + 1, parts[key].Heading, ui.TableColor{0.0, 0, 0.9, 1}, parts[key]) + tmpBTindex += 2 + } else if (foo.CellType == "TEXT") { + mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) + initRowTextColumn (mh, tmpBTindex, parts[key].Heading, parts[key]) + tmpBTindex += 1 + } else { + panic("I don't know what this is in initColumnNames") + } + } +} + +func AddTableTab(gw *GuiWindow, name string, rowcount int, parts []TableColumnData) *TableData { + node := NewWindow() + b := node.box + return b.AddTableBox(name, rowcount, parts) +} + +func (b *GuiBox) AddTableBox(name string, rowcount int, parts []TableColumnData) *TableData { + mh := new(TableData) + + mh.RowCount = rowcount + mh.Rows = make([]RowData, mh.RowCount) + + InitColumns(mh, parts) + + model := ui.NewTableModel(mh) + table := ui.NewTable( + &ui.TableParams{ + Model: model, + RowBackgroundColorModelColumn: 0, // Row Background color is always index zero + }) + + tmpBTindex := 0 + for key, foo := range parts { + log.Println(key, foo) + if (foo.CellType == "BG") { + } else if (foo.CellType == "BUTTON") { + tmpBTindex += 1 + table.AppendButtonColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable) + } else if (foo.CellType == "TEXTCOLOR") { + tmpBTindex += 1 + table.AppendTextColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable, + &ui.TableTextColumnOptionalParams{ + ColorModelColumn: tmpBTindex + 1, + }); + tmpBTindex += 1 + } else if (foo.CellType == "TEXT") { + tmpBTindex += 1 + table.AppendTextColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable, nil) + } else { + panic("I don't know what this is in initColumnNames") + } + } + + // is this needed? + // gw.BoxMap[name] = box + mh.Box = b + + b.UiBox.Append(table, true) + + return mh +} diff --git a/toolkit/andlabs-direct/old/tableCallbacks.go b/toolkit/andlabs-direct/old/tableCallbacks.go new file mode 100644 index 0000000..6eefd8d --- /dev/null +++ b/toolkit/andlabs-direct/old/tableCallbacks.go @@ -0,0 +1,108 @@ +package gui + +// +// These functions are the hooks to the andlabs libui +// They eventually feed information to the OS native GUI toolkits +// and feed back user interaction with the GUI +// + +import "log" +// import "fmt" +import "image/color" +import "runtime" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (mh *TableData) NumRows(m *ui.TableModel) int { + if (Config.Debug) { + log.Println("NumRows = mh.RowCount = ", mh.RowCount, "(last Row & Column =", mh.lastRow, mh.lastColumn, ")") + } + return mh.RowCount +} + +// FYI: this routine seems to be called around 10 to 100 times a second for each table +func (mh *TableData) ColumnTypes(m *ui.TableModel) []ui.TableValue { + if (Config.DebugTable) { + log.Println("ColumnTypes = ", mh.generatedColumnTypes) + } + return mh.generatedColumnTypes +} + +// TODO: Figure out why this is being called 1000 times a second (10 times for each row & column) +// +// Nevermind that TODO. Who gives a shit. This is a really smart way to treat the OS toolkits +func (mh *TableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue { + if (Config.DebugTable) { + log.Println("CellValue() row, column =", row, column) + } + mh.lastRow = row + mh.lastColumn = column + humanID := mh.Cells[column].HumanID + if (column == mh.Human[humanID].TextID) { + return ui.TableString(mh.Rows[row].HumanData[humanID].Text) + } + if (column == mh.Human[humanID].ColorID) { + if (column == 0) { + // ignore BG color on windows for now + if (runtime.GOOS == "windows") { + // TODO: fix colors on windows + // log.Println("CellValue() WINDOWS is BG COLOR row, column =", row, column) + // return nil + } + + if (mh.Rows[row].HumanData[humanID].Color == color.RGBA{255, 255, 255, 255}) { + log.Println("CellValue() color.RGBA{255, 255, 255, 255} so return nil. row, column =", row, column) + return nil + } + + bgcolor := libuiColorToGOlangColor(mh.Rows[row].HumanData[humanID].Color) + if (Config.Debug) { + log.Println("CellValue() BGCOLOR =", bgcolor) + } + return bgcolor + } + return libuiColorToGOlangColor(mh.Rows[row].HumanData[humanID].Color) + } + log.Println("CellValue() FAILURE") + log.Println("CellValue() FAILURE") + log.Println("CellValue() row, column = ", row, column) + log.Println("CellValue() FAILURE") + log.Println("CellValue() FAILURE") + log.Println("CellValue() mh.Cells", mh.Cells) + log.Println("CellValue() mh.Human", mh.Human) + panic("CellValue() not sure what sort of ui.TableValue to return in CellValue()") + return ui.TableString("") +} + +func (mh *TableData) SetCellValue(m *ui.TableModel, row, column int, value ui.TableValue) { + log.Println("SetCellValue() START row=", row, "column=", column, "value=", value) + + defaultSetCellValue(mh, row, column) + + log.Println("mh.Cells[column].HumanID =", mh.Cells[column].HumanID) + // log.Println("mh.Rows[row].Cells[column].HumanID =", mh.Rows[row].Cells[column].HumanID) + + humanID := mh.Cells[column].HumanID + log.Println("mh.Human[humanID].ColorID =", mh.Human[humanID].ColorID) + log.Println("mh.Human[humanID].TextID =", mh.Human[humanID].TextID) + + log.Println("SetCellValue() END") +} + +func defaultSetCellValue(mh *TableData, row int, column int) { + if (mh.Cells[column].Name == "BUTTON") { + humanID := mh.Cells[column].HumanID + log.Println("defaultSetCellValue() FOUND THE TABLE BUTTON ", row, humanID) + + button := mh.Rows[row].HumanData[humanID].Button + if (button != nil) { + guiButtonClick(button) + return + } + log.Println("defaultSetCellValue() ERROR: UNKNOWN BUTTON IN TABLE") + if (Config.Debug) { + panic("defaultSetCellValue() GOT AN UNKNOWN BUTTON CLICK IN TABLE") + } + } +} diff --git a/toolkit/andlabs-direct/slider.go b/toolkit/andlabs-direct/slider.go new file mode 100644 index 0000000..ad801f8 --- /dev/null +++ b/toolkit/andlabs-direct/slider.go @@ -0,0 +1,31 @@ +package toolkit + +import "log" +import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit { + // make new node here + log.Println("gui.Toolkit.NewSpinbox()", x, y) + var newt Toolkit + + if (t.uiBox == nil) { + log.Println("gui.ToolkitNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") + log.Println("probably could just make a box here?") + os.Exit(0) + return nil + } + + s := ui.NewSlider(x, y) + newt.uiSlider = s + newt.uiBox = t.uiBox + t.uiBox.Append(s, stretchy) + + s.OnChanged(func(spin *ui.Slider) { + newt.commonChange("Slider") + }) + + return &newt +} diff --git a/toolkit/andlabs-direct/spinner.go b/toolkit/andlabs-direct/spinner.go new file mode 100644 index 0000000..885192c --- /dev/null +++ b/toolkit/andlabs-direct/spinner.go @@ -0,0 +1,30 @@ +package toolkit + +import "log" +import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t Toolkit) NewSpinner(title string, x int, y int) *Toolkit { + // make new node here + log.Println("gui.Toolkit.NewSpinner()", x, y) + var newt Toolkit + + if (t.uiBox == nil) { + log.Println("gui.ToolkitNode.NewSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it") + os.Exit(0) + return nil + } + + s := ui.NewSpinbox(x, y) + newt.uiSpinbox = s + newt.uiBox = t.uiBox + t.uiBox.Append(s, stretchy) + + s.OnChanged(func(s *ui.Spinbox) { + newt.commonChange("Spinner") + }) + + return &newt +} diff --git a/toolkit/andlabs-direct/structs.go b/toolkit/andlabs-direct/structs.go new file mode 100644 index 0000000..9bba671 --- /dev/null +++ b/toolkit/andlabs-direct/structs.go @@ -0,0 +1,249 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +import "github.com/davecgh/go-spew/spew" + +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 + +func setDefaultBehavior(s bool) { + defaultBehavior = s + if (defaultBehavior) { + if (DebugToolkit) { + log.Println("Setting this toolkit to use the default behavior.") + log.Println("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 + + DebugToolkit = false + } else { + log.Println("This toolkit is set to ignore the default behavior.") + } +} + +func SetDebugToolkit (s bool) { + DebugToolkit = s +} + +func GetDebugToolkit () bool { + return DebugToolkit +} + +// stores the raw toolkit internals +type Toolkit struct { + id string + + Name string + Width int + Height int + + OnChanged func(*Toolkit) + OnExit func(*Toolkit) + + Custom func() + + 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 + + // 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 + text string +} + +func (t *Toolkit) String() string { + return t.GetText() +} + +func forceDump(t *Toolkit) { + tmp := DebugToolkit + DebugToolkit = true + t.Dump() + DebugToolkit = tmp +} + +func (t *Toolkit) GetText() string { + t.Dump() + if (DebugToolkit) { + log.Println("gui.Toolkit.Text() Enter") + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(t) + } + if (t.uiEntry != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiEntry.Text()) + } + return t.uiEntry.Text() + } + if (t.uiMultilineEntry != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text()) + } + text := t.uiMultilineEntry.Text() + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() text =", text) + } + t.text = text + return text + } + if (t.uiCombobox != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.GetText() =", t.text) + } + return t.text + } + return "" +} + +func (t *Toolkit) SetText(s string) bool { + if (DebugToolkit) { + log.Println("gui.Toolkit.Text() Enter") + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(t) + } + if (t.uiEntry != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) + } + t.uiEntry.SetText(s) + return true + } + if (t.uiMultilineEntry != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text) + } + t.uiMultilineEntry.SetText(s) + return true + } + return false +} + +func sanity(t *Toolkit) bool { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() Enter") + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(t) + } + if (t.uiEntry == nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) + } + return false + } + return true +} + +func (t *Toolkit) SetValue(i int) bool { + log.Println("gui.Toolkit.SetValue() START") + if (sanity(t)) { + return false + } + t.Dump() + // panic("got to toolkit.SetValue") + return true +} + +func (t *Toolkit) Value() int { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() Enter") + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(t) + } + if (t == nil) { + log.Println("gui.Toolkit.Value() can not get value t == nil") + return 0 + } + if (t.uiSlider != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiSlider.Value) + } + return t.uiSlider.Value() + } + if (t.uiSpinbox != nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiSpinbox.Value) + } + return t.uiSpinbox.Value() + } + log.Println("gui.Toolkit.Value() Could not find a ui element to get a value from") + return 0 +} + +func (t *Toolkit) Dump() { + if ! DebugToolkit { + return + } + log.Println("gui.Toolkit.Dump() Name = ", t.Name, t.Width, t.Height) + if (t.uiBox != nil) { + log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox) + } + if (t.uiButton != nil) { + log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton) + } + if (t.uiCombobox != nil) { + log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox) + } + if (t.uiWindow != nil) { + log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow) + } + if (t.uiTab != nil) { + log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab) + } + if (t.uiGroup != nil) { + log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup) + } + if (t.uiEntry != nil) { + log.Println("gui.Toolkit.Dump() uiEntry =", t.uiEntry) + } + if (t.uiMultilineEntry != nil) { + log.Println("gui.Toolkit.Dump() uiMultilineEntry =", t.uiMultilineEntry) + } + if (t.uiSlider != nil) { + log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider) + } + if (t.uiCheckbox != nil) { + log.Println("gui.Toolkit.Dump() uiCheckbox =", t.uiCheckbox) + } + if (t.OnExit != nil) { + log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit) + } + if (t.Custom != nil) { + log.Println("gui.Toolkit.Dump() Custom =", t.Custom) + } + log.Println("gui.Toolkit.Dump() c =", t.c) + log.Println("gui.Toolkit.Dump() val =", t.val) + log.Println("gui.Toolkit.Dump() text =", t.text) +} diff --git a/toolkit/andlabs-direct/tab.go b/toolkit/andlabs-direct/tab.go new file mode 100644 index 0000000..c641fc0 --- /dev/null +++ b/toolkit/andlabs-direct/tab.go @@ -0,0 +1,133 @@ +package toolkit + +import ( + "log" + "time" + + "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 (t *Toolkit) AddTab(name string) *Toolkit { + // var w *ui.Window + var newt *Toolkit + + log.Println("gui.toolkit.AddTab() sleep 3") + + if (t.uiWindow == nil) { + log.Println("gui.Toolkit.UiWindow == nil. I can't add a toolbar without window") + return nil + } + + if (t.uiTab == nil) { + // this means you have to make a new tab + log.Println("gui.toolkit.NewTab() GOOD. This should be the first tab:", name) + newt = newTab(t.uiWindow, name) + t.uiTab = newt.uiTab + } else { + // this means you have to append a tab + log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name) + newt = t.appendTab(name) + } + + newt.Name = name + + if (DebugToolkit) { + log.Println("t:") + t.Dump() + log.Println("newt:") + newt.Dump() + } + + return newt +} + +// This sets _all_ the tabs to Margin = true +// +// TODO: do proper tab tracking (will be complicated). low priority +func tabSetMargined(tab *ui.Tab) { + c := tab.NumPages() + for i := 0; i < c; i++ { + if (DebugToolkit) { + log.Println("SetMargined", i, margin) + } + tab.SetMargined(i, margin) + } +} + +func newTab(w *ui.Window, name string) *Toolkit { + var t Toolkit + if (DebugToolkit) { + log.Println("gui.toolkit.NewTab() ADD", name) + } + + if (w == nil) { + log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") + log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") + log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") + time.Sleep(1 * time.Second) + return nil + } + if (DebugToolkit) { + log.Println("gui.toolkit.AddTab() START name =", name) + } + tab := ui.NewTab() + w.SetMargined(margin) + + hbox := ui.NewHorizontalBox() // this makes everything go along the horizon + hbox.SetPadded(padded) + tab.Append(name, hbox) + tabSetMargined(tab) // TODO: run this in the right place(?) + w.SetChild(tab) + + t.uiWindow = w + t.uiTab = tab + t.uiBox = hbox + return &t +} + +func (t *Toolkit) appendTab(name string) *Toolkit { + var newT Toolkit + if (DebugToolkit) { + log.Println("gui.toolkit.NewTab() ADD", name) + } + + if (t.uiTab == nil) { + log.Println("gui.Toolkit.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") + } + if (DebugToolkit) { + log.Println("gui.toolkit.AddTab() 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 +} diff --git a/toolkit/andlabs-direct/textbox.go b/toolkit/andlabs-direct/textbox.go new file mode 100644 index 0000000..44946b8 --- /dev/null +++ b/toolkit/andlabs-direct/textbox.go @@ -0,0 +1,34 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +func (t Toolkit) NewTextbox(name string) *Toolkit { + if (DebugToolkit) { + log.Println("gui.Toolkit.NewTextbox()", name) + } + var newt Toolkit + + if t.broken() { + return nil + } + + c := ui.NewNonWrappingMultilineEntry() + newt.uiMultilineEntry = c + + newt.uiBox = t.uiBox + newt.Name = name + if (defaultBehavior) { + t.uiBox.Append(c, true) + } else { + t.uiBox.Append(c, stretchy) + } + + c.OnChanged(func(spin *ui.MultilineEntry) { + newt.commonChange("Textbox") + }) + + return &newt +} diff --git a/toolkit/andlabs-direct/window.go b/toolkit/andlabs-direct/window.go new file mode 100644 index 0000000..efbd672 --- /dev/null +++ b/toolkit/andlabs-direct/window.go @@ -0,0 +1,66 @@ +package toolkit + +import ( + "log" + + "github.com/andlabs/ui" + _ "github.com/andlabs/ui/winmanifest" +) + +func (t *Toolkit) MessageWindow(msg1 string, msg2 string) { + ui.MsgBox(t.uiWindow, msg1, msg2) +} + +func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) { + ui.MsgBoxError(t.uiWindow, msg1, msg2) +} + +func NewWindow(title string, x int, y int) *Toolkit { + var t Toolkit + if (DebugToolkit) { + log.Println("toolkit NewWindow", title, x, y) + } + w := ui.NewWindow(title, x, y, menubar) + w.SetBorderless(canvas) + w.SetMargined(margin) + w.OnClosing(func(*ui.Window) bool { + if (DebugToolkit) { + log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here") + t.Dump() + } + if (t.OnExit != nil) { + if (DebugToolkit) { + log.Println("ui.Window().OnExit() ATTEMPTING toolkit.OnExit CALLBACK") + } + t.OnExit(&t) + } + if (t.Custom != nil) { + if (DebugToolkit) { + log.Println("ui.Window().Custom() ATTEMPTING toolkit.Custom CALLBACK") + } + t.Custom() + } + if (DebugToolkit) { + log.Println("ui.Window().OnExit() Toolkit.OnExit is nil") + } + return true + }) + w.Show() + t.uiWindow = w + t.UiWindowBad = w // deprecate this as soon as possible + return &t +} + +func (t *Toolkit) SetWindowTitle(title string) { + if (DebugToolkit) { + log.Println("toolkit NewWindow", t.Name, "title", title) + } + win := t.uiWindow + if (win != nil) { + win.SetTitle(title) + } else { + if (DebugToolkit) { + log.Println("Setting the window title", title) + } + } +} diff --git a/toolkit/andlabs/Makefile b/toolkit/andlabs/Makefile new file mode 100644 index 0000000..8b0502c --- /dev/null +++ b/toolkit/andlabs/Makefile @@ -0,0 +1,4 @@ +all: plugin + +plugin: + GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so diff --git a/toolkit/andlabs/box.go b/toolkit/andlabs/box.go index 29a8331..bb9945e 100644 --- a/toolkit/andlabs/box.go +++ b/toolkit/andlabs/box.go @@ -1,4 +1,4 @@ -package toolkit +package main import "log" @@ -6,12 +6,12 @@ import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" // create a new box -func (t *Toolkit) GetBox() *ui.Box { +func (t *andlabsT) GetBox() *ui.Box { return t.uiBox } // create a new box -func (t *Toolkit) NewBox() *Toolkit { +func (t *andlabsT) NewBox() *andlabsT { if (DebugToolkit) { log.Println("gui.Toolbox.NewBox() START create default") } @@ -20,7 +20,7 @@ func (t *Toolkit) NewBox() *Toolkit { if (DebugToolkit) { log.Println("\tgui.Toolbox.NewBox() is a Group") } - var newTK Toolkit + var newTK andlabsT vbox := ui.NewVerticalBox() vbox.SetPadded(padded) @@ -33,7 +33,7 @@ func (t *Toolkit) NewBox() *Toolkit { if (DebugToolkit) { log.Println("\tgui.Toolbox.NewBox() is a Box") } - var newTK Toolkit + var newTK andlabsT vbox := ui.NewVerticalBox() vbox.SetPadded(padded) @@ -47,7 +47,7 @@ func (t *Toolkit) NewBox() *Toolkit { if (DebugToolkit) { log.Println("\tgui.Toolbox.NewBox() is a Window") } - var newT Toolkit + var newT andlabsT vbox := ui.NewVerticalBox() vbox.SetPadded(padded) diff --git a/toolkit/andlabs/button.go b/toolkit/andlabs/button.go index e0b7d97..bd80683 100644 --- a/toolkit/andlabs/button.go +++ b/toolkit/andlabs/button.go @@ -1,68 +1,56 @@ -package toolkit +package main import "log" // import "os" + import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -// make new Group here -func (t Toolkit) NewButton(name string) *Toolkit { - var newt Toolkit +import "git.wit.org/wit/gui/toolkit" +func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) { + var t, newt *andlabsT var b *ui.Button + log.Println("gui.andlabs.NewButton()", w.Name) - if t.broken() { - return nil + t = mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewButton() toolkit struct == nil. name=", parentW.Name, w.Name) + return } - if (DebugToolkit) { - log.Println("gui.Toolbox.NewButton() create", name) + if t.broken() { + return } - b = ui.NewButton(name) + newt = new(andlabsT) + + b = ui.NewButton(w.Name) newt.uiButton = b b.OnClicked(func(*ui.Button) { - log.Println("TODO: IN TOOLKIT GOROUTINE. SHOULD LEAVE HERE VIA channels. button name =", name) - t.Dump() - newt.Dump() if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() Should do something here") + log.Println("TODO: IN TOOLKIT GOROUTINE. SHOULD LEAVE HERE VIA channels. button name =", w.Name) + log.Println("FOUND WIDGET!", w) } - if (newt.Custom == nil) { - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() toolkit.Custom == nil") - } - } else { - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() toolkit.Custom() START") - } - newt.Custom() + if (w.Custom != nil) { + w.Custom() return - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() toolkit.Custom() END") - } } - if (t.Custom == nil) { - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() parent toolkit.Custom == nil") - } - } else { - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() START (IS THIS A BAD IDEA?)") - } - t.Custom() + if (w.Event != nil) { + w.Event(w) return - if (DebugToolkit) { - log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() END (IS THIS A BAD IDEA?)") - } } - log.Println("TODO: LEFT TOOLKIT GOROUTINE WITH NOTHING TO DO button name =", name) + t.Dump() + newt.Dump() + if (DebugToolkit) { + log.Println("TODO: LEFT TOOLKIT GOROUTINE WITH NOTHING TO DO button name =", w.Name) + } }) if (DebugToolkit) { - log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", name) + log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", w.Name) t.Dump() - log.Println("gui.Toolbox.NewButton() about to append to Box new t:", name) + log.Println("gui.Toolbox.NewButton() about to append to Box new t:", w.Name) newt.Dump() } if (t.uiBox != nil) { @@ -72,8 +60,8 @@ func (t Toolkit) NewButton(name string) *Toolkit { } else { log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") - return &t + return } - return &newt + mapWidgetsToolkits(w, newt) } diff --git a/toolkit/andlabs/checkbox.go b/toolkit/andlabs/checkbox.go index b3b3121..b4b1524 100644 --- a/toolkit/andlabs/checkbox.go +++ b/toolkit/andlabs/checkbox.go @@ -1,13 +1,13 @@ -package toolkit +package main import "log" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func (t Toolkit) NewCheckbox(name string) *Toolkit { +func (t andlabsT) NewCheckbox(name string) *andlabsT { log.Println("gui.Toolkit.NewCheckbox()", name) - var newt Toolkit + var newt andlabsT if t.broken() { return nil @@ -25,7 +25,7 @@ func (t Toolkit) NewCheckbox(name string) *Toolkit { return &newt } -func (t Toolkit) Checked() bool { +func (t andlabsT) Checked() bool { if t.broken() { return false } diff --git a/toolkit/andlabs/common.go b/toolkit/andlabs/common.go index 451f9d6..fc6cbe8 100644 --- a/toolkit/andlabs/common.go +++ b/toolkit/andlabs/common.go @@ -1,4 +1,4 @@ -package toolkit +package main import "log" @@ -9,7 +9,7 @@ func init() { setDefaultBehavior(true) } -func (t Toolkit) commonChange(widget string) { +func (t andlabsT) commonChange(widget string) { s := t.String() if (DebugToolkit) { log.Println("gui.Toolkit.ui.OnChanged() =", s) @@ -36,7 +36,7 @@ func (t Toolkit) commonChange(widget string) { // 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 (?) -func (t *Toolkit) broken() bool { +func (t *andlabsT) broken() bool { if (t.uiBox == nil) { if (t.uiWindow != nil) { if (DebugToolkit) { diff --git a/toolkit/andlabs/demo.go b/toolkit/andlabs/demo.go index 7ba1822..0781f88 100644 --- a/toolkit/andlabs/demo.go +++ b/toolkit/andlabs/demo.go @@ -1,4 +1,4 @@ -package toolkit +package main import "log" @@ -19,7 +19,7 @@ func BlankWindow(w *ui.Window) *ui.Box { return hbox } -func (t *Toolkit) DemoNumbersPage() { +func (t *andlabsT) DemoNumbersPage() { var w *ui.Window log.Println("Starting wit/gui toolkit andlabs/ui DemoNumbersPage()") diff --git a/toolkit/andlabs/dropdown.go b/toolkit/andlabs/dropdown.go index ca09a99..1e1886a 100644 --- a/toolkit/andlabs/dropdown.go +++ b/toolkit/andlabs/dropdown.go @@ -1,18 +1,19 @@ -package toolkit +package main import "log" -import "os" // import "time" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func (t *Toolkit) NewDropdown(title string) *Toolkit { +import "git.wit.org/wit/gui/toolkit" + +func (t *andlabsT) NewDropdown(title string) *andlabsT { // make new node here if (DebugToolkit) { log.Println("gui.Toolbox.NewDropdownCombobox()", title) } - var newt Toolkit + var newt andlabsT if t.broken() { return nil @@ -31,7 +32,7 @@ func (t *Toolkit) NewDropdown(title string) *Toolkit { i := spin.Selected() if (newt.val == nil) { log.Println("make map didn't work") - os.Exit(0) + newt.text = "error" } newt.text = newt.val[i] newt.commonChange("Dropdown") @@ -40,7 +41,7 @@ func (t *Toolkit) NewDropdown(title string) *Toolkit { return &newt } -func (t *Toolkit) AddDropdown(title string) { +func (t *andlabsT) AddDropdownName(title string) { t.uiCombobox.Append(title) if (t.val == nil) { log.Println("make map didn't work") @@ -50,6 +51,40 @@ func (t *Toolkit) AddDropdown(title string) { t.c = t.c + 1 } -func (t Toolkit) SetDropdown(i int) { +func (t andlabsT) SetDropdown(i int) { t.uiCombobox.SetSelected(i) } + +func NewDropdown(parentW *toolkit.Widget, w *toolkit.Widget) { + log.Println("gui.andlabs.NewDropdown()", w.Name) + + t := mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewDropdown() toolkit struct == nil. name=", parentW.Name, w.Name) + listMap() + } + newt := t.NewDropdown(w.Name) + mapWidgetsToolkits(w, newt) +} + +func AddDropdownName(w *toolkit.Widget, s string) { + log.Println("gui.andlabs.AddDropdownName()", w.Name, "add:", s) + + t := mapToolkits[w] + if (t == nil) { + log.Println("go.andlabs.AddDropdownName() toolkit struct == nil. name=", w.Name, s) + listMap() + } + t.AddDropdownName(s) +} + +func SetDropdown(w *toolkit.Widget, i int) { + log.Println("gui.andlabs.SetDropdown()", i) + + t := mapToolkits[w] + if (t == nil) { + log.Println("go.andlabs.SetDropdown() toolkit struct == nil. name=", w.Name, i) + listMap() + } + t.SetDropdown(i) +} diff --git a/toolkit/andlabs/group.go b/toolkit/andlabs/group.go index 5b315a4..e93247a 100644 --- a/toolkit/andlabs/group.go +++ b/toolkit/andlabs/group.go @@ -1,14 +1,29 @@ -package toolkit +package main -import "log" -import "os" +import ( + "log" -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" + "git.wit.org/wit/gui/toolkit" + + "github.com/andlabs/ui" + _ "github.com/andlabs/ui/winmanifest" +) + +func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) { + log.Println("gui.andlabs.NewGroup()", w.Name) + + t := mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewGroup() toolkit struct == nil. name=", parentW.Name, w.Name) + listMap() + } + newt := t.NewGroup(w.Name) + mapWidgetsToolkits(w, newt) +} // make new Group here -func (t Toolkit) NewGroup(title string) *Toolkit { - var newt Toolkit +func (t andlabsT) NewGroup(title string) *andlabsT { + var newt andlabsT if (DebugToolkit) { log.Println("gui.Toolbox.NewGroup() create", title) @@ -22,8 +37,7 @@ func (t Toolkit) NewGroup(title string) *Toolkit { t.uiWindow.SetChild(g) } else { log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") - log.Println("probably could just make a box here?") - os.Exit(0) + log.Fatalln("probably could just make a box here?") } hbox := ui.NewVerticalBox() diff --git a/toolkit/andlabs/label.go b/toolkit/andlabs/label.go index 2819ff1..c5a6896 100644 --- a/toolkit/andlabs/label.go +++ b/toolkit/andlabs/label.go @@ -1,21 +1,42 @@ -package toolkit +package main import "log" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func (t *Toolkit) NewLabel(name string) *Toolkit { - // make new node here - log.Println("gui.Toolbox.NewLabel", name) +import "git.wit.org/wit/gui/toolkit" + +func NewLabel(parentW *toolkit.Widget, w *toolkit.Widget) { + var t, newt *andlabsT + log.Println("gui.andlabs.NewButton()", w.Name) + + t = mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewButton() toolkit struct == nil. name=", parentW.Name, w.Name) + return + } if t.broken() { - return nil + return } - var newt Toolkit - newt.uiLabel = ui.NewLabel(name) + newt = new(andlabsT) + + newt.uiLabel = ui.NewLabel(w.Name) newt.uiBox = t.uiBox - t.uiBox.Append(newt.uiLabel, false) - return &newt + if (DebugToolkit) { + log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", w.Name) + t.Dump() + log.Println("gui.Toolbox.NewButton() about to append to Box new t:", w.Name) + newt.Dump() + } + if (t.uiBox != nil) { + t.uiBox.Append(newt.uiLabel, false) + } else { + log.Println("ERROR: wit/gui andlabs couldn't place this label in a box") + return + } + + mapWidgetsToolkits(w, newt) } diff --git a/toolkit/andlabs/main.go b/toolkit/andlabs/main.go index da639fa..85e6913 100644 --- a/toolkit/andlabs/main.go +++ b/toolkit/andlabs/main.go @@ -1,7 +1,10 @@ -package toolkit +package main import ( "log" +// "time" + + "git.wit.org/wit/gui/toolkit" "github.com/andlabs/ui" // the _ means we only need this for the init() @@ -12,7 +15,17 @@ func Main(f func()) { if (DebugToolkit) { log.Println("Starting gui.Main() (using gtk via andlabs/ui)") } - ui.Main(f) + ui.Main( func() { + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + log.Println("Starting gui.Main() (using gtk via andlabs/ui)") + // time.Sleep(1 * time.Second) + // NewWindow2("helloworld2", 200, 100) + f() + }) } // Other goroutines must use this to access the GUI @@ -25,7 +38,20 @@ func Main(f func()) { // func Queue(f func()) { if (DebugToolkit) { - log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)") + log.Println("Sending function to ui.QueueMain() (using gtk via andlabs/ui)") } - ui.QueueMain(f) + //ui.QueueMain(f) + f() +} + +func Init() { + log.Println("should Init() here") + + mapWidgets = make(map[*andlabsT]*toolkit.Widget) + mapToolkits = make(map[*toolkit.Widget]*andlabsT) +} + +func Quit() { + log.Println("should Quit() here") + // myExit(nil) } diff --git a/toolkit/andlabs/old/area.go b/toolkit/andlabs/old/area.go deleted file mode 100644 index 7c42c6c..0000000 --- a/toolkit/andlabs/old/area.go +++ /dev/null @@ -1,136 +0,0 @@ -package gui - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "github.com/davecgh/go-spew/spew" - -func makeGenericArea(gb *GuiBox, newText *ui.AttributedString, custom func(*GuiButton)) { - // make this button just to get the default font (but don't display the button) - // There should be another way to do this (?) - var newB *GuiButton - newB = CreateFontButton(gb, "AREA") - newB.Box = gb - newB.Custom = custom - - gw := gb.Window - // initialize the GuiArea{} - gw.Area = new(GuiArea) - gw.Area.Button = newB - gw.Area.Box = gb - gw.Area.UiAttrstr = newText - gw.Area.UiArea = ui.NewArea(gw.Area) - - if (Config.Debug) { - spew.Dump(gw.Area.UiArea) - log.Println("DEBUGGING", Config.Debug) - } else { - log.Println("NOT DEBUGGING AREA mhAH.Button =", gw.Area.Button) - } -} - -func AreaAppendText(newText *ui.AttributedString, what string, attrs ...ui.Attribute) { - start := len(newText.String()) - end := start + len(what) - newText.AppendUnattributed(what) - for _, a := range attrs { - newText.SetAttribute(a, start, end) - } -} - -func appendWithAttributes(newText *ui.AttributedString, what string, attrs ...ui.Attribute) { - start := len(newText.String()) - end := start + len(what) - newText.AppendUnattributed(what) - for _, a := range attrs { - newText.SetAttribute(a, start, end) - } -} - -func (ah GuiArea) Draw(a *ui.Area, p *ui.AreaDrawParams) { - tl := ui.DrawNewTextLayout(&ui.DrawTextLayoutParams{ - String: ah.UiAttrstr, - DefaultFont: ah.Button.FB.Font(), - Width: p.AreaWidth, - Align: ui.DrawTextAlign(1), - }) - p.Context.Text(tl, 0, 0) - defer tl.Free() -} - -func (ah GuiArea) MouseEvent(a *ui.Area, me *ui.AreaMouseEvent) { - if (Config.Debug) { - log.Println("GOT MouseEvent() ah.Button =", ah.Button) - spew.Dump(me) - } - if (me.Down == 1) { - log.Println("GOT MOUSE DOWN") - log.Println("GOT MOUSE DOWN ah.Button =", ah.Button) - log.Println("GOT MOUSE UP ah.Button.FB =", ah.Button.FB) - } - if (me.Up == 1) { - log.Println("GOT MOUSE UP") - log.Println("GOT MOUSE UP ah.Button =", ah.Button) - log.Println("GOT MOUSE UP ah.Button.FB =", ah.Button.FB) - if (ah.Button.Custom != nil) { - ah.Button.Custom(ah.Button) - } else if (Data.MouseClick != nil) { - Data.MouseClick(ah.Button) - } - } -} - -func (ah GuiArea) MouseCrossed(a *ui.Area, left bool) { - log.Println("GOT MouseCrossed()") -} - -func (ah GuiArea) DragBroken(a *ui.Area) { - log.Println("GOT DragBroken()") -} - -// TODO: fix KeyEvents -func (ah GuiArea) KeyEvent(a *ui.Area, ke *ui.AreaKeyEvent) (handled bool) { - log.Println("GOT KeyEvent()") - if (ke.Key == 10) { - log.Println("GOT ENTER") - log.Println("GOT ENTER") - log.Println("GOT ENTER") - } - if (ke.Key == 32) { - log.Println("GOT ENTER") - log.Println("GOT ENTER") - log.Println("GOT ENTER") - } - spew.Dump(ke) - return false -} - -func (b *GuiBox) ShowTextBox(newText *ui.AttributedString, custom func(*GuiButton), name string) { - log.Println("ShowTextBox() START") - - gw := b.Window - if (gw == nil) { - log.Println("ShowTextBox() ERROR gw = nil") - return - } - log.Println("ShowTextBox() START gw =", gw) - - /* - var newbox *GuiBox - newbox = new(GuiBox) - newbox.Window = gw - newbox.Name = name - hbox := ui.NewVerticalBox() - newbox.UiBox = hbox - */ - - // TODO: allow padded & axis here - b.UiBox.SetPadded(true) - - // add(gw.BoxMap["MAINBOX"], newbox) - - makeGenericArea(b, newText, custom) - b.UiBox.Append(b.Window.Area.UiArea, true) -} diff --git a/toolkit/andlabs/old/color.go b/toolkit/andlabs/old/color.go deleted file mode 100644 index cf4a362..0000000 --- a/toolkit/andlabs/old/color.go +++ /dev/null @@ -1,31 +0,0 @@ -package gui - -// -// convert between 'standard' golang Color and andlabs/ui Color -// - -// import "log" -// import "fmt" -import "image/color" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -func libuiColorToGOlangColor(rgba color.RGBA) ui.TableColor { - /* a hack to see if colors work differently on macos or windows - if (rgba.R == 72) { - log.Println("SETTING COLOR TO NIL") - log.Println("SETTING COLOR TO NIL") - log.Println("SETTING COLOR TO NIL") - return ui.TableColor{} - } - */ - return ui.TableColor{float64(rgba.R) / 256, float64(rgba.G) / 256, float64(rgba.B) / 256, float64(rgba.A) / 256} -} - -/* -func golangColorGOlibuiColorTo (ui.TableColor) (rgba color.RGBA) { - color.RGBA{float64(, 100, 200, 100} - return ui.TableColor{float64(rgba.R) / 256, float64(rgba.G) / 256, float64(rgba.B) / 256, float64(rgba.A) / 256} -} -*/ diff --git a/toolkit/andlabs/old/seperator.go b/toolkit/andlabs/old/seperator.go deleted file mode 100644 index ca152a8..0000000 --- a/toolkit/andlabs/old/seperator.go +++ /dev/null @@ -1,25 +0,0 @@ -package gui - -import "log" -import "os" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -func HorizontalBreak(box *GuiBox) { - log.Println("VerticalSeparator added to box =", box.Name) - tmp := ui.NewHorizontalSeparator() - if (box == nil) { - return - } - if (box.UiBox == nil) { - return - } - box.UiBox.Append(tmp, false) -} - -func VerticalBreak(box *GuiBox) { - log.Println("VerticalSeparator added to box =", box.Name) - tmp := ui.NewVerticalSeparator() - box.UiBox.Append(tmp, false) -} diff --git a/toolkit/andlabs/old/structs.go b/toolkit/andlabs/old/structs.go deleted file mode 100644 index 4a16438..0000000 --- a/toolkit/andlabs/old/structs.go +++ /dev/null @@ -1,273 +0,0 @@ -package gui - -import ( - "image/color" - - "github.com/andlabs/ui" -// "golang.org/x/image/font" - - // "github.com/davecgh/go-spew/spew" - - // _ "github.com/andlabs/ui/winmanifest" -) - -// -// All GUI Data Structures and functions that are external -// If you need cross platform support, these might only -// be the safe way to interact with the GUI -// -var Data GuiData -var Config GuiConfig - -type GuiConfig struct { - Title string - Width int - Height int - Exit func(*Node) - - Debug bool - DebugNode bool - DebugTabs bool - DebugTable bool - DebugWindow bool - DebugToolkit bool - - depth int - counter int // used to make unique ID's - prefix string -} - -type GuiData struct { - // a fallback default function to handle mouse events - // if nothing else is defined to handle them - MouseClick func(*GuiButton) - - // A map of all the entry boxes - // AllEntries []*GuiEntry - WindowMap map[string]*GuiWindow - - // Store access to everything via binary tree's - NodeMap map[string]*Node - NodeArray []*Node - NodeSlice []*Node - - // A map of all buttons everywhere on all - // windows, all tabs, across all goroutines - // This is "GLOBAL" - // - // This has to work this way because of how - // andlabs/ui & andlabs/libui work - AllButtons []*GuiButton -// buttonMap map[*ui.Button]*GuiButton -} - -/* -type GuiTab struct { - Name string // field for human readable name - Number int // the andlabs/ui tab index - Window *GuiWindow // the parent Window -} -*/ - -// -// stores information on the 'window' -// -// This merges the concept of andlabs/ui *Window and *Tab -// -// More than one Window is not supported in a cross platform -// sense & may never be. On Windows and MacOS, you have to have -// 'tabs'. Even under Linux, more than one Window is currently -// unstable -// -// This code will make a 'GuiWindow' regardless of if it is -// a stand alone window (which is more or less working on Linux) -// or a 'tab' inside a window (which is all that works on MacOS -// and MSWindows. -// -// This struct keeps track of what is in the window so you -// can destroy and replace it with something else -// -type GuiWindow struct { - Name string // field for human readable name - Width int - Height int - Axis int // does it add items to the X or Y axis - TabNumber *int // the andlabs/ui tab index - - // the callback function to make the window contents - // MakeWindow func(*GuiBox) *GuiBox - - // the components of the window - BoxMap map[string]*GuiBox - // EntryMap map[string]*GuiEntry - - node *Node - - // andlabs/ui abstraction mapping - UiWindow *ui.Window - UiTab *ui.Tab // if this != nil, the window is 'tabbed' -} - -/* -func (w *GuiWindow) Dump() { - log.Println("gui.GuiWindow.Dump() Name = ", w.Name) - log.Println("gui.GuiWindow.Dump() node = ", w.node) - log.Println("gui.GuiWindow.Dump() Width = ", w.Width) - log.Println("gui.GuiWindow.Dump() Height = ", w.Height) -} -*/ - -// GuiBox is any type of ui.Hbox or ui.Vbox -// There can be lots of these for each GuiWindow -type GuiBox struct { - Name string // field for human readable name - Axis int // does it add items to the X or Y axis - Window *GuiWindow // the parent Window - - node *Node - - // andlabs/ui abstraction mapping - UiBox *ui.Box -} - -func (b *GuiBox) Append(child ui.Control, x bool) { - if b.UiBox == nil { - // spew.Dump(b) - // b.Dump() - panic("GuiBox.Append() can't work. UiBox == nil") - return - } - b.UiBox.Append(child, x) -} - -// Note: every mouse click is handled -// as a 'Button' regardless of where -// the user clicks it. You could probably -// call this 'GuiMouseClick' -type GuiButton struct { - Name string // field for human readable name - Box *GuiBox // what box the button click was in - - // a callback function for the main application - Custom func(*GuiButton) - Values interface{} - Color color.RGBA - - // andlabs/ui abstraction mapping - B *ui.Button - FB *ui.FontButton - CB *ui.ColorButton -} - -/* -// -// AREA STRUCTURES START -// AREA STRUCTURES START -// AREA STRUCTURES START -// -type GuiArea struct { - Button *GuiButton // what button handles mouse events - Box *GuiBox - - UiAttrstr *ui.AttributedString - UiArea *ui.Area -} - -type FontString struct { - S string - Size int - F font.Face - W font.Weight -} - -// -// AREA STRUCTURES END -// AREA STRUCTURES END -// AREA STRUCTURES END -// - -// -// TABLE DATA STRUCTURES START -// TABLE DATA STRUCTURES START -// TABLE DATA STRUCTURES START -// - -// -// This is the structure that andlabs/ui uses to pass information -// to the GUI. This is the "authoritative" data. -// -type TableData struct { - RowCount int // This is the number of 'rows' which really means data elements not what the human sees - RowWidth int // This is how wide each row is - Rows []RowData // This is all the table data by row - generatedColumnTypes []ui.TableValue // generate this dynamically - - Cells [20]CellData - Human [20]HumanMap - - Box *GuiBox - - lastRow int - lastColumn int -} - -// -// This maps the andlabs/ui & libui components into a "human" -// readable cell reference list. The reason is that there -// are potentially 3 values for each cell. The Text, the Color -// and an image. These are not always needed so the number -// of fields varies between 1 and 3. Internally, the toolkit -// GUI abstraction needs to list all of them, but it's then -// hard to figure out which column goes with the columns that -// you see when you visually are looking at it like a spreadsheet -// -// This makes a map so that we can say "give me the value at -// row 4 and column 2" and find the fields that are needed -// -// TODO: re-add images and the progress bar (works in andlabs/ui) -// -type HumanCellData struct { - Name string // what kind of row is this? - Text string - TextID int - Color color.RGBA - ColorID int - Button *GuiButton -} - -type HumanMap struct { - Name string // what kind of row is this? - TextID int - ColorID int -} - -type TableColumnData struct { - Index int - CellType string - Heading string - Color string -} - -type CellData struct { - Index int - HumanID int - Name string // what type of cell is this? -} - -// hmm. will this stand the test of time? -type RowData struct { - Name string // what kind of row is this? - Status string // status of the row? - // - // TODO: These may or may not be implementable - // depending on if it's possible to detect the bgcolor or what row is selected - // click func() // what function to call if the user clicks on it - // doubleclick func() // what function to call if the user double clicks on it - // - HumanData [20]HumanCellData -} -*/ - -// -// TABLE DATA STRUCTURES END -// diff --git a/toolkit/andlabs/old/table.go b/toolkit/andlabs/old/table.go deleted file mode 100644 index 92ae871..0000000 --- a/toolkit/andlabs/old/table.go +++ /dev/null @@ -1,150 +0,0 @@ -// based off andlabs/ui/examples/table.go - -package gui - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -// import "github.com/davecgh/go-spew/spew" - -func initRowBTcolor(mh *TableData, intBG int, cell TableColumnData) { - humanInt := cell.Index - - // setup mapping from human readable indexes to internal libUI indexes - mh.Human[humanInt].Name = "BG" - mh.Human[humanInt].ColorID = intBG - mh.Human[humanInt].TextID = -1 - - mh.Cells[intBG].Name = "BG" - mh.Cells[intBG].HumanID = humanInt - - log.Println("intBG, humanInt", intBG, humanInt) -} - -func initRowButtonColumn(mh *TableData, buttonID int, junk string, cell TableColumnData) { - humanInt := cell.Index - - // setup mapping from human readable indexes to internal libUI indexes - mh.Human[humanInt].Name = "BUTTON" - mh.Human[humanInt].ColorID = -1 - mh.Human[humanInt].TextID = buttonID - - mh.Cells[buttonID].Name = "BUTTON" - mh.Cells[buttonID].HumanID = humanInt - - log.Println("buttonID, humanInt", buttonID, humanInt) -} - -func initRowTextColorColumn(mh *TableData, stringID int, colorID int, junk string, color ui.TableColor, cell TableColumnData) { - humanInt := cell.Index - - // setup mapping from human readable indexes to internal libUI indexes - mh.Human[humanInt].Name = "EDIT" - mh.Human[humanInt].ColorID = colorID - mh.Human[humanInt].TextID = stringID - - // text for Column humanInt - mh.Cells[stringID].Name = "EDIT" - mh.Cells[stringID].HumanID = humanInt - - mh.Cells[colorID].Name = "COLOR" - mh.Cells[colorID].HumanID = humanInt -} - -func initRowTextColumn(mh *TableData, stringID int, junk string, cell TableColumnData) { - humanInt := cell.Index - - // setup mapping from human readable indexes to internal libUI indexes - mh.Human[humanInt].Name = "EDIT" - mh.Human[humanInt].ColorID = -1 - mh.Human[humanInt].TextID = stringID - - mh.Cells[stringID].Name = "EDIT" - mh.Cells[stringID].HumanID = humanInt -} - -func InitColumns(mh *TableData, parts []TableColumnData) { - tmpBTindex := 0 - humanID := 0 - for key, foo := range parts { - log.Println("key, foo =", key, foo) - - parts[key].Index = humanID - humanID += 1 - - if (foo.CellType == "BG") { - mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{}) - initRowBTcolor (mh, tmpBTindex, parts[key]) - tmpBTindex += 1 - } else if (foo.CellType == "BUTTON") { - mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) - initRowButtonColumn (mh, tmpBTindex, parts[key].Heading, parts[key]) - tmpBTindex += 1 - } else if (foo.CellType == "TEXTCOLOR") { - mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) - mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableColor{}) - initRowTextColorColumn(mh, tmpBTindex, tmpBTindex + 1, parts[key].Heading, ui.TableColor{0.0, 0, 0.9, 1}, parts[key]) - tmpBTindex += 2 - } else if (foo.CellType == "TEXT") { - mh.generatedColumnTypes = append(mh.generatedColumnTypes, ui.TableString("")) - initRowTextColumn (mh, tmpBTindex, parts[key].Heading, parts[key]) - tmpBTindex += 1 - } else { - panic("I don't know what this is in initColumnNames") - } - } -} - -func AddTableTab(gw *GuiWindow, name string, rowcount int, parts []TableColumnData) *TableData { - node := NewWindow() - b := node.box - return b.AddTableBox(name, rowcount, parts) -} - -func (b *GuiBox) AddTableBox(name string, rowcount int, parts []TableColumnData) *TableData { - mh := new(TableData) - - mh.RowCount = rowcount - mh.Rows = make([]RowData, mh.RowCount) - - InitColumns(mh, parts) - - model := ui.NewTableModel(mh) - table := ui.NewTable( - &ui.TableParams{ - Model: model, - RowBackgroundColorModelColumn: 0, // Row Background color is always index zero - }) - - tmpBTindex := 0 - for key, foo := range parts { - log.Println(key, foo) - if (foo.CellType == "BG") { - } else if (foo.CellType == "BUTTON") { - tmpBTindex += 1 - table.AppendButtonColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable) - } else if (foo.CellType == "TEXTCOLOR") { - tmpBTindex += 1 - table.AppendTextColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable, - &ui.TableTextColumnOptionalParams{ - ColorModelColumn: tmpBTindex + 1, - }); - tmpBTindex += 1 - } else if (foo.CellType == "TEXT") { - tmpBTindex += 1 - table.AppendTextColumn(foo.Heading, tmpBTindex, ui.TableModelColumnAlwaysEditable, nil) - } else { - panic("I don't know what this is in initColumnNames") - } - } - - // is this needed? - // gw.BoxMap[name] = box - mh.Box = b - - b.UiBox.Append(table, true) - - return mh -} diff --git a/toolkit/andlabs/old/tableCallbacks.go b/toolkit/andlabs/old/tableCallbacks.go deleted file mode 100644 index 6eefd8d..0000000 --- a/toolkit/andlabs/old/tableCallbacks.go +++ /dev/null @@ -1,108 +0,0 @@ -package gui - -// -// These functions are the hooks to the andlabs libui -// They eventually feed information to the OS native GUI toolkits -// and feed back user interaction with the GUI -// - -import "log" -// import "fmt" -import "image/color" -import "runtime" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -func (mh *TableData) NumRows(m *ui.TableModel) int { - if (Config.Debug) { - log.Println("NumRows = mh.RowCount = ", mh.RowCount, "(last Row & Column =", mh.lastRow, mh.lastColumn, ")") - } - return mh.RowCount -} - -// FYI: this routine seems to be called around 10 to 100 times a second for each table -func (mh *TableData) ColumnTypes(m *ui.TableModel) []ui.TableValue { - if (Config.DebugTable) { - log.Println("ColumnTypes = ", mh.generatedColumnTypes) - } - return mh.generatedColumnTypes -} - -// TODO: Figure out why this is being called 1000 times a second (10 times for each row & column) -// -// Nevermind that TODO. Who gives a shit. This is a really smart way to treat the OS toolkits -func (mh *TableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue { - if (Config.DebugTable) { - log.Println("CellValue() row, column =", row, column) - } - mh.lastRow = row - mh.lastColumn = column - humanID := mh.Cells[column].HumanID - if (column == mh.Human[humanID].TextID) { - return ui.TableString(mh.Rows[row].HumanData[humanID].Text) - } - if (column == mh.Human[humanID].ColorID) { - if (column == 0) { - // ignore BG color on windows for now - if (runtime.GOOS == "windows") { - // TODO: fix colors on windows - // log.Println("CellValue() WINDOWS is BG COLOR row, column =", row, column) - // return nil - } - - if (mh.Rows[row].HumanData[humanID].Color == color.RGBA{255, 255, 255, 255}) { - log.Println("CellValue() color.RGBA{255, 255, 255, 255} so return nil. row, column =", row, column) - return nil - } - - bgcolor := libuiColorToGOlangColor(mh.Rows[row].HumanData[humanID].Color) - if (Config.Debug) { - log.Println("CellValue() BGCOLOR =", bgcolor) - } - return bgcolor - } - return libuiColorToGOlangColor(mh.Rows[row].HumanData[humanID].Color) - } - log.Println("CellValue() FAILURE") - log.Println("CellValue() FAILURE") - log.Println("CellValue() row, column = ", row, column) - log.Println("CellValue() FAILURE") - log.Println("CellValue() FAILURE") - log.Println("CellValue() mh.Cells", mh.Cells) - log.Println("CellValue() mh.Human", mh.Human) - panic("CellValue() not sure what sort of ui.TableValue to return in CellValue()") - return ui.TableString("") -} - -func (mh *TableData) SetCellValue(m *ui.TableModel, row, column int, value ui.TableValue) { - log.Println("SetCellValue() START row=", row, "column=", column, "value=", value) - - defaultSetCellValue(mh, row, column) - - log.Println("mh.Cells[column].HumanID =", mh.Cells[column].HumanID) - // log.Println("mh.Rows[row].Cells[column].HumanID =", mh.Rows[row].Cells[column].HumanID) - - humanID := mh.Cells[column].HumanID - log.Println("mh.Human[humanID].ColorID =", mh.Human[humanID].ColorID) - log.Println("mh.Human[humanID].TextID =", mh.Human[humanID].TextID) - - log.Println("SetCellValue() END") -} - -func defaultSetCellValue(mh *TableData, row int, column int) { - if (mh.Cells[column].Name == "BUTTON") { - humanID := mh.Cells[column].HumanID - log.Println("defaultSetCellValue() FOUND THE TABLE BUTTON ", row, humanID) - - button := mh.Rows[row].HumanData[humanID].Button - if (button != nil) { - guiButtonClick(button) - return - } - log.Println("defaultSetCellValue() ERROR: UNKNOWN BUTTON IN TABLE") - if (Config.Debug) { - panic("defaultSetCellValue() GOT AN UNKNOWN BUTTON CLICK IN TABLE") - } - } -} diff --git a/toolkit/andlabs/plugin.go b/toolkit/andlabs/plugin.go new file mode 100644 index 0000000..f78e95e --- /dev/null +++ b/toolkit/andlabs/plugin.go @@ -0,0 +1,43 @@ +package main + +import ( + "log" + + "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() { + log.Println("listMap() HERE") + log.Println("listMap() HERE") + log.Println("listMap() HERE mapWidgets()") + for t, w := range mapWidgets { + log.Println("andlabs =", t.Name, "widget =", w.Name) + } + log.Println("listMap() HERE mapToolkits()") + for w, t := range mapToolkits { + log.Println("andlabs =", t, "widget =", w.Name) + forceDump(t) + } +} + +func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) { + if (mapToolkits[w] == nil) { + mapToolkits[w] = t + } else { + log.Println("WTF: mapToolkits already installed") + panic("WTF") + } + + if (mapWidgets[t] == nil) { + mapWidgets[t] = w + } else { + log.Println("WTF: mapWidgets already installed") + panic("WTF") + } +} diff --git a/toolkit/andlabs/slider.go b/toolkit/andlabs/slider.go index ad801f8..f9ff0f3 100644 --- a/toolkit/andlabs/slider.go +++ b/toolkit/andlabs/slider.go @@ -1,15 +1,19 @@ -package toolkit +package main -import "log" -import "os" +import ( + "log" + "os" -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" + "git.wit.org/wit/gui/toolkit" -func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit { + "github.com/andlabs/ui" + _ "github.com/andlabs/ui/winmanifest" +) + +func (t andlabsT) NewSlider(title string, x int, y int) *andlabsT { // make new node here log.Println("gui.Toolkit.NewSpinbox()", x, y) - var newt Toolkit + var newt andlabsT if (t.uiBox == nil) { log.Println("gui.ToolkitNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") @@ -29,3 +33,16 @@ func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit { return &newt } + +func NewSlider(parentW *toolkit.Widget, w *toolkit.Widget) { + var newt *andlabsT + log.Println("gui.andlabs.NewTab()", w.Name) + + t := mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) + return + } + newt = t.NewSlider(w.Name, w.X, w.Y) + mapWidgetsToolkits(w, newt) +} diff --git a/toolkit/andlabs/spinner.go b/toolkit/andlabs/spinner.go index 885192c..6505b48 100644 --- a/toolkit/andlabs/spinner.go +++ b/toolkit/andlabs/spinner.go @@ -1,4 +1,4 @@ -package toolkit +package main import "log" import "os" @@ -6,10 +6,10 @@ import "os" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func (t Toolkit) NewSpinner(title string, x int, y int) *Toolkit { +func (t andlabsT) NewSpinner(title string, x int, y int) *andlabsT { // make new node here log.Println("gui.Toolkit.NewSpinner()", x, y) - var newt Toolkit + var newt andlabsT if (t.uiBox == nil) { log.Println("gui.ToolkitNode.NewSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it") diff --git a/toolkit/andlabs/structs.go b/toolkit/andlabs/structs.go index 9bba671..2f3fa72 100644 --- a/toolkit/andlabs/structs.go +++ b/toolkit/andlabs/structs.go @@ -1,4 +1,4 @@ -package toolkit +package main import "log" @@ -47,15 +47,15 @@ func GetDebugToolkit () bool { } // stores the raw toolkit internals -type Toolkit struct { +type andlabsT struct { id string Name string Width int Height int - OnChanged func(*Toolkit) - OnExit func(*Toolkit) + OnChanged func(*andlabsT) + OnExit func(*andlabsT) Custom func() @@ -84,18 +84,18 @@ type Toolkit struct { text string } -func (t *Toolkit) String() string { +func (t *andlabsT) String() string { return t.GetText() } -func forceDump(t *Toolkit) { +func forceDump(t *andlabsT) { tmp := DebugToolkit DebugToolkit = true t.Dump() DebugToolkit = tmp } -func (t *Toolkit) GetText() string { +func (t *andlabsT) GetText() string { t.Dump() if (DebugToolkit) { log.Println("gui.Toolkit.Text() Enter") @@ -128,7 +128,7 @@ func (t *Toolkit) GetText() string { return "" } -func (t *Toolkit) SetText(s string) bool { +func (t *andlabsT) SetText(s string) bool { if (DebugToolkit) { log.Println("gui.Toolkit.Text() Enter") scs := spew.ConfigState{MaxDepth: 1} @@ -151,7 +151,7 @@ func (t *Toolkit) SetText(s string) bool { return false } -func sanity(t *Toolkit) bool { +func sanity(t *andlabsT) bool { if (DebugToolkit) { log.Println("gui.Toolkit.Value() Enter") scs := spew.ConfigState{MaxDepth: 1} @@ -166,7 +166,7 @@ func sanity(t *Toolkit) bool { return true } -func (t *Toolkit) SetValue(i int) bool { +func (t *andlabsT) SetValue(i int) bool { log.Println("gui.Toolkit.SetValue() START") if (sanity(t)) { return false @@ -176,7 +176,7 @@ func (t *Toolkit) SetValue(i int) bool { return true } -func (t *Toolkit) Value() int { +func (t *andlabsT) Value() int { if (DebugToolkit) { log.Println("gui.Toolkit.Value() Enter") scs := spew.ConfigState{MaxDepth: 1} @@ -202,7 +202,7 @@ func (t *Toolkit) Value() int { return 0 } -func (t *Toolkit) Dump() { +func (t *andlabsT) Dump() { if ! DebugToolkit { return } diff --git a/toolkit/andlabs/tab.go b/toolkit/andlabs/tab.go index c641fc0..0556fb9 100644 --- a/toolkit/andlabs/tab.go +++ b/toolkit/andlabs/tab.go @@ -1,12 +1,13 @@ -package toolkit +package main import ( "log" "time" + "git.wit.org/wit/gui/toolkit" + "github.com/andlabs/ui" _ "github.com/andlabs/ui/winmanifest" - ) /* @@ -21,9 +22,9 @@ import ( once there is one. If you send a Window here, it will replace any existing tabs rather than adding a new one */ -func (t *Toolkit) AddTab(name string) *Toolkit { +func (t *andlabsT) newTab(name string) *andlabsT { // var w *ui.Window - var newt *Toolkit + var newt *andlabsT log.Println("gui.toolkit.AddTab() sleep 3") @@ -68,8 +69,8 @@ func tabSetMargined(tab *ui.Tab) { } } -func newTab(w *ui.Window, name string) *Toolkit { - var t Toolkit +func newTab(w *ui.Window, name string) *andlabsT { + var t andlabsT if (DebugToolkit) { log.Println("gui.toolkit.NewTab() ADD", name) } @@ -99,8 +100,8 @@ func newTab(w *ui.Window, name string) *Toolkit { return &t } -func (t *Toolkit) appendTab(name string) *Toolkit { - var newT Toolkit +func (t *andlabsT) appendTab(name string) *andlabsT { + var newT andlabsT if (DebugToolkit) { log.Println("gui.toolkit.NewTab() ADD", name) } @@ -131,3 +132,16 @@ func (t *Toolkit) appendTab(name string) *Toolkit { newT.uiBox = hbox return &newT } + +func NewTab(parentW *toolkit.Widget, w *toolkit.Widget) { + var newt *andlabsT + log.Println("gui.andlabs.NewTab()", w.Name) + + t := mapToolkits[parentW] + if (t == nil) { + log.Println("go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) + return + } + newt = t.newTab(w.Name) + mapWidgetsToolkits(w, newt) +} diff --git a/toolkit/andlabs/textbox.go b/toolkit/andlabs/textbox.go index 44946b8..c7a9390 100644 --- a/toolkit/andlabs/textbox.go +++ b/toolkit/andlabs/textbox.go @@ -1,16 +1,18 @@ -package toolkit +package main import "log" +import "git.wit.org/wit/gui/toolkit" + import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func (t Toolkit) NewTextbox(name string) *Toolkit { +func (t andlabsT) NewTextbox(name string) *andlabsT { + var newt andlabsT + if (DebugToolkit) { log.Println("gui.Toolkit.NewTextbox()", name) } - var newt Toolkit - if t.broken() { return nil } @@ -32,3 +34,37 @@ func (t Toolkit) NewTextbox(name string) *Toolkit { return &newt } + +func NewTextbox(parentW *toolkit.Widget, w *toolkit.Widget) { + var t, newt *andlabsT + log.Println("gui.andlabs.NewTextbox()", w.Name) + + t = mapToolkits[parentW] + if (t == nil) { + log.Println("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 + + if (DebugToolkit) { + log.Println("gui.Toolbox.NewTextbox() about to append to Box parent t:", w.Name) + t.Dump() + log.Println("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.Println("ERROR: wit/gui andlabs couldn't place this Textbox in a box") + return + } + + mapWidgetsToolkits(w, newt) +} diff --git a/toolkit/andlabs/window.go b/toolkit/andlabs/window.go index efbd672..b360cb8 100644 --- a/toolkit/andlabs/window.go +++ b/toolkit/andlabs/window.go @@ -1,57 +1,69 @@ -package toolkit +package main import ( "log" "github.com/andlabs/ui" _ "github.com/andlabs/ui/winmanifest" + + "git.wit.org/wit/gui/toolkit" ) -func (t *Toolkit) MessageWindow(msg1 string, msg2 string) { +func (t *andlabsT) MessageWindow(msg1 string, msg2 string) { ui.MsgBox(t.uiWindow, msg1, msg2) } -func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) { +func (t *andlabsT) ErrorWindow(msg1 string, msg2 string) { ui.MsgBoxError(t.uiWindow, msg1, msg2) } -func NewWindow(title string, x int, y int) *Toolkit { - var t Toolkit +func NewWindow(w *toolkit.Widget) { + var t *andlabsT + if (DebugToolkit) { - log.Println("toolkit NewWindow", title, x, y) + log.Println("toolkit NewWindow", w.Name, w.Width, w.Height) + } + + if (w == nil) { + log.Println("wit/gui plugin error. widget == nil") + return } - w := ui.NewWindow(title, x, y, menubar) - w.SetBorderless(canvas) - w.SetMargined(margin) - w.OnClosing(func(*ui.Window) bool { + t = new(andlabsT) + // t = NewWindow2(w.Name, w.Width, w.Height) + +// 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 { if (DebugToolkit) { log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here") t.Dump() } - if (t.OnExit != nil) { - if (DebugToolkit) { - log.Println("ui.Window().OnExit() ATTEMPTING toolkit.OnExit CALLBACK") - } - t.OnExit(&t) + if (w.Custom != nil) { + w.Custom() + return true } - if (t.Custom != nil) { - if (DebugToolkit) { - log.Println("ui.Window().Custom() ATTEMPTING toolkit.Custom CALLBACK") - } - t.Custom() + if (w.Event != nil) { + w.Event(w) + return true } if (DebugToolkit) { - log.Println("ui.Window().OnExit() Toolkit.OnExit is nil") + log.Println("andlabs.ui.Window().OnClosing() was not defined") } - return true + return false }) - w.Show() - t.uiWindow = w - t.UiWindowBad = w // deprecate this as soon as possible - return &t + win.Show() + t.uiWindow = win + t.UiWindowBad = win // deprecate this as soon as possible + t.Name = w.Name + + mapWidgetsToolkits(w, t) + return } -func (t *Toolkit) SetWindowTitle(title string) { +func (t *andlabsT) SetWindowTitle(title string) { if (DebugToolkit) { log.Println("toolkit NewWindow", t.Name, "title", title) } diff --git a/toolkit/andlabs2/Makefile b/toolkit/andlabs2/Makefile deleted file mode 100644 index 54cf7f5..0000000 --- a/toolkit/andlabs2/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -all: plugin - -plugin: - GO111MODULE="off" go build -buildmode=plugin -o ../andlabs2.so diff --git a/toolkit/andlabs2/box.go b/toolkit/andlabs2/box.go deleted file mode 100644 index bb9945e..0000000 --- a/toolkit/andlabs2/box.go +++ /dev/null @@ -1,66 +0,0 @@ -package main - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -// create a new box -func (t *andlabsT) GetBox() *ui.Box { - return t.uiBox -} - -// create a new box -func (t *andlabsT) NewBox() *andlabsT { - if (DebugToolkit) { - log.Println("gui.Toolbox.NewBox() START create default") - } - t.Dump() - if (t.uiGroup != nil) { - if (DebugToolkit) { - log.Println("\tgui.Toolbox.NewBox() is a Group") - } - var newTK andlabsT - - vbox := ui.NewVerticalBox() - vbox.SetPadded(padded) - t.uiGroup.SetChild(vbox) - newTK.uiBox = vbox - - return &newTK - } - if (t.uiBox != nil) { - if (DebugToolkit) { - log.Println("\tgui.Toolbox.NewBox() is a Box") - } - var newTK andlabsT - - vbox := ui.NewVerticalBox() - vbox.SetPadded(padded) - t.uiBox.Append(vbox, stretchy) - newTK.uiBox = vbox - newTK.Name = t.Name - - return &newTK - } - if (t.uiWindow != nil) { - if (DebugToolkit) { - log.Println("\tgui.Toolbox.NewBox() is a Window") - } - var newT andlabsT - - vbox := ui.NewVerticalBox() - vbox.SetPadded(padded) - t.uiWindow.SetChild(vbox) - newT.uiBox = vbox - newT.Name = t.Name - - // panic("WTF") - return &newT - } - if (DebugToolkit) { - log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box") - } - t.Dump() - return nil -} diff --git a/toolkit/andlabs2/button.go b/toolkit/andlabs2/button.go deleted file mode 100644 index bd80683..0000000 --- a/toolkit/andlabs2/button.go +++ /dev/null @@ -1,67 +0,0 @@ -package main - -import "log" -// import "os" - - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "git.wit.org/wit/gui/toolkit" -func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) { - var t, newt *andlabsT - var b *ui.Button - log.Println("gui.andlabs.NewButton()", w.Name) - - t = mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewButton() toolkit struct == nil. name=", parentW.Name, w.Name) - return - } - - if t.broken() { - return - } - newt = new(andlabsT) - - b = ui.NewButton(w.Name) - newt.uiButton = b - - b.OnClicked(func(*ui.Button) { - if (DebugToolkit) { - log.Println("TODO: IN TOOLKIT GOROUTINE. SHOULD LEAVE HERE VIA channels. button name =", w.Name) - log.Println("FOUND WIDGET!", w) - } - if (w.Custom != nil) { - w.Custom() - return - } - if (w.Event != nil) { - w.Event(w) - return - } - t.Dump() - newt.Dump() - if (DebugToolkit) { - log.Println("TODO: LEFT TOOLKIT GOROUTINE WITH NOTHING TO DO button name =", w.Name) - } - }) - - if (DebugToolkit) { - log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", w.Name) - t.Dump() - log.Println("gui.Toolbox.NewButton() about to append to Box new t:", w.Name) - newt.Dump() - } - if (t.uiBox != nil) { - t.uiBox.Append(b, stretchy) - } else if (t.uiWindow != nil) { - t.uiWindow.SetChild(b) - } else { - log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") - log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window") - return - } - - mapWidgetsToolkits(w, newt) -} diff --git a/toolkit/andlabs2/checkbox.go b/toolkit/andlabs2/checkbox.go deleted file mode 100644 index b4b1524..0000000 --- a/toolkit/andlabs2/checkbox.go +++ /dev/null @@ -1,34 +0,0 @@ -package main - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -func (t andlabsT) NewCheckbox(name string) *andlabsT { - log.Println("gui.Toolkit.NewCheckbox()", name) - var newt andlabsT - - if t.broken() { - return nil - } - - c := ui.NewCheckbox(name) - newt.uiCheckbox = c - newt.uiBox = t.uiBox - t.uiBox.Append(c, stretchy) - - c.OnToggled(func(spin *ui.Checkbox) { - newt.commonChange("Checkbox") - }) - - return &newt -} - -func (t andlabsT) Checked() bool { - if t.broken() { - return false - } - - return t.uiCheckbox.Checked() -} diff --git a/toolkit/andlabs2/common.go b/toolkit/andlabs2/common.go deleted file mode 100644 index fc6cbe8..0000000 --- a/toolkit/andlabs2/common.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import "log" - -func init() { - if (DebugToolkit) { - log.Println("gui/toolkit init() Setting defaultBehavior = true") - } - setDefaultBehavior(true) -} - -func (t andlabsT) commonChange(widget string) { - s := t.String() - if (DebugToolkit) { - log.Println("gui.Toolkit.ui.OnChanged() =", s) - } - if (t.OnChanged != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.OnChanged() trying to run toolkit.OnChanged() entered val =", s) - } - t.OnChanged(&t) - return - } - if (t.Custom != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.OnChanged() Running toolkit.Custom()") - t.Dump() - } - t.Custom() - return - } - if (DebugToolkit) { - log.Println("gui.Toolkit.OnChanged() ENDED without finding any callback") - } -} - -// 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 (?) -func (t *andlabsT) broken() bool { - if (t.uiBox == nil) { - if (t.uiWindow != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.UiBox == nil. This is an empty window. Try to add a box") - } - t.NewBox() - return false - } - log.Println("gui.Toolkit.UiBox == nil. I can't add a widget without a place to put it") - // log.Println("probably could just make a box here?") - // corruption or something horrible? - 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.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)") - forceDump(t) - return false - } - return false -} diff --git a/toolkit/andlabs2/demo.go b/toolkit/andlabs2/demo.go deleted file mode 100644 index 0781f88..0000000 --- a/toolkit/andlabs2/demo.go +++ /dev/null @@ -1,92 +0,0 @@ -package main - -import "log" - -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 *andlabsT) DemoNumbersPage() { - var w *ui.Window - - log.Println("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 -} diff --git a/toolkit/andlabs2/dropdown.go b/toolkit/andlabs2/dropdown.go deleted file mode 100644 index 1e1886a..0000000 --- a/toolkit/andlabs2/dropdown.go +++ /dev/null @@ -1,90 +0,0 @@ -package main - -import "log" -// import "time" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "git.wit.org/wit/gui/toolkit" - -func (t *andlabsT) NewDropdown(title string) *andlabsT { - // make new node here - if (DebugToolkit) { - log.Println("gui.Toolbox.NewDropdownCombobox()", title) - } - var newt andlabsT - - if t.broken() { - return nil - } - - s := ui.NewCombobox() - newt.uiCombobox = s - newt.uiBox = t.uiBox - t.uiBox.Append(s, stretchy) - - // initialize the index - newt.c = 0 - newt.val = make(map[int]string) - - s.OnSelected(func(spin *ui.Combobox) { - i := spin.Selected() - if (newt.val == nil) { - log.Println("make map didn't work") - newt.text = "error" - } - newt.text = newt.val[i] - newt.commonChange("Dropdown") - }) - - return &newt -} - -func (t *andlabsT) AddDropdownName(title string) { - t.uiCombobox.Append(title) - if (t.val == nil) { - log.Println("make map didn't work") - return - } - t.val[t.c] = title - t.c = t.c + 1 -} - -func (t andlabsT) SetDropdown(i int) { - t.uiCombobox.SetSelected(i) -} - -func NewDropdown(parentW *toolkit.Widget, w *toolkit.Widget) { - log.Println("gui.andlabs.NewDropdown()", w.Name) - - t := mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewDropdown() toolkit struct == nil. name=", parentW.Name, w.Name) - listMap() - } - newt := t.NewDropdown(w.Name) - mapWidgetsToolkits(w, newt) -} - -func AddDropdownName(w *toolkit.Widget, s string) { - log.Println("gui.andlabs.AddDropdownName()", w.Name, "add:", s) - - t := mapToolkits[w] - if (t == nil) { - log.Println("go.andlabs.AddDropdownName() toolkit struct == nil. name=", w.Name, s) - listMap() - } - t.AddDropdownName(s) -} - -func SetDropdown(w *toolkit.Widget, i int) { - log.Println("gui.andlabs.SetDropdown()", i) - - t := mapToolkits[w] - if (t == nil) { - log.Println("go.andlabs.SetDropdown() toolkit struct == nil. name=", w.Name, i) - listMap() - } - t.SetDropdown(i) -} diff --git a/toolkit/andlabs2/group.go b/toolkit/andlabs2/group.go deleted file mode 100644 index 39f740b..0000000 --- a/toolkit/andlabs2/group.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import "log" -import "os" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "git.wit.org/wit/gui/toolkit" - -func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) { - log.Println("gui.andlabs.NewGroup()", w.Name) - - t := mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewGroup() toolkit struct == nil. name=", parentW.Name, w.Name) - listMap() - } - newt := t.NewGroup(w.Name) - mapWidgetsToolkits(w, newt) -} - -// make new Group here -func (t andlabsT) NewGroup(title string) *andlabsT { - var newt andlabsT - - if (DebugToolkit) { - log.Println("gui.Toolbox.NewGroup() create", title) - } - g := ui.NewGroup(title) - g.SetMargined(margin) - - if (t.uiBox != nil) { - t.uiBox.Append(g, stretchy) - } else if (t.uiWindow != nil) { - t.uiWindow.SetChild(g) - } else { - log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") - log.Println("probably could just make a box here?") - os.Exit(0) - } - - hbox := ui.NewVerticalBox() - hbox.SetPadded(padded) - g.SetChild(hbox) - - newt.uiGroup = g - newt.uiBox = hbox - newt.uiWindow = t.uiWindow - newt.Name = title - - t.Dump() - newt.Dump() - // panic("toolkit.NewGroup") - return &newt -} diff --git a/toolkit/andlabs2/label.go b/toolkit/andlabs2/label.go deleted file mode 100644 index c5a6896..0000000 --- a/toolkit/andlabs2/label.go +++ /dev/null @@ -1,42 +0,0 @@ -package main - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "git.wit.org/wit/gui/toolkit" - -func NewLabel(parentW *toolkit.Widget, w *toolkit.Widget) { - var t, newt *andlabsT - log.Println("gui.andlabs.NewButton()", w.Name) - - t = mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewButton() 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 - - if (DebugToolkit) { - log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", w.Name) - t.Dump() - log.Println("gui.Toolbox.NewButton() about to append to Box new t:", w.Name) - newt.Dump() - } - if (t.uiBox != nil) { - t.uiBox.Append(newt.uiLabel, false) - } else { - log.Println("ERROR: wit/gui andlabs couldn't place this label in a box") - return - } - - mapWidgetsToolkits(w, newt) -} diff --git a/toolkit/andlabs2/main.go b/toolkit/andlabs2/main.go deleted file mode 100644 index 8a28710..0000000 --- a/toolkit/andlabs2/main.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "log" -// "time" - - "git.wit.org/wit/gui/toolkit" - - "github.com/andlabs/ui" - // the _ means we only need this for the init() - _ "github.com/andlabs/ui/winmanifest" -) - -func Main(f func()) { - if (DebugToolkit) { - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - } - ui.Main( func() { - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - log.Println("Starting gui.Main() (using gtk via andlabs/ui)") - // time.Sleep(1 * time.Second) - // NewWindow2("helloworld2", 200, 100) - f() - }) -} - -// Other goroutines must use this to access the GUI -// -// You can not acess / process the GUI thread directly from -// other goroutines. This is due to the nature of how -// Linux, MacOS and Windows work (they all work differently. suprise. surprise.) -// -// For example: Queue(NewWindow()) -// -func Queue(f func()) { - if (DebugToolkit) { - log.Println("Sending function to ui.QueueMain() (using gtk via andlabs/ui)") - } - ui.QueueMain(f) -} - -func Init() { - log.Println("should Init() here") - - mapWidgets = make(map[*andlabsT]*toolkit.Widget) - mapToolkits = make(map[*toolkit.Widget]*andlabsT) -} - -func Quit() { - log.Println("should Quit() here") - // myExit(nil) -} diff --git a/toolkit/andlabs2/plugin.go b/toolkit/andlabs2/plugin.go deleted file mode 100644 index f78e95e..0000000 --- a/toolkit/andlabs2/plugin.go +++ /dev/null @@ -1,43 +0,0 @@ -package main - -import ( - "log" - - "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() { - log.Println("listMap() HERE") - log.Println("listMap() HERE") - log.Println("listMap() HERE mapWidgets()") - for t, w := range mapWidgets { - log.Println("andlabs =", t.Name, "widget =", w.Name) - } - log.Println("listMap() HERE mapToolkits()") - for w, t := range mapToolkits { - log.Println("andlabs =", t, "widget =", w.Name) - forceDump(t) - } -} - -func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) { - if (mapToolkits[w] == nil) { - mapToolkits[w] = t - } else { - log.Println("WTF: mapToolkits already installed") - panic("WTF") - } - - if (mapWidgets[t] == nil) { - mapWidgets[t] = w - } else { - log.Println("WTF: mapWidgets already installed") - panic("WTF") - } -} diff --git a/toolkit/andlabs2/slider.go b/toolkit/andlabs2/slider.go deleted file mode 100644 index f9ff0f3..0000000 --- a/toolkit/andlabs2/slider.go +++ /dev/null @@ -1,48 +0,0 @@ -package main - -import ( - "log" - "os" - - "git.wit.org/wit/gui/toolkit" - - "github.com/andlabs/ui" - _ "github.com/andlabs/ui/winmanifest" -) - -func (t andlabsT) NewSlider(title string, x int, y int) *andlabsT { - // make new node here - log.Println("gui.Toolkit.NewSpinbox()", x, y) - var newt andlabsT - - if (t.uiBox == nil) { - log.Println("gui.ToolkitNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it") - log.Println("probably could just make a box here?") - os.Exit(0) - return nil - } - - s := ui.NewSlider(x, y) - newt.uiSlider = s - newt.uiBox = t.uiBox - t.uiBox.Append(s, stretchy) - - s.OnChanged(func(spin *ui.Slider) { - newt.commonChange("Slider") - }) - - return &newt -} - -func NewSlider(parentW *toolkit.Widget, w *toolkit.Widget) { - var newt *andlabsT - log.Println("gui.andlabs.NewTab()", w.Name) - - t := mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) - return - } - newt = t.NewSlider(w.Name, w.X, w.Y) - mapWidgetsToolkits(w, newt) -} diff --git a/toolkit/andlabs2/spinner.go b/toolkit/andlabs2/spinner.go deleted file mode 100644 index 6505b48..0000000 --- a/toolkit/andlabs2/spinner.go +++ /dev/null @@ -1,30 +0,0 @@ -package main - -import "log" -import "os" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -func (t andlabsT) NewSpinner(title string, x int, y int) *andlabsT { - // make new node here - log.Println("gui.Toolkit.NewSpinner()", x, y) - var newt andlabsT - - if (t.uiBox == nil) { - log.Println("gui.ToolkitNode.NewSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it") - os.Exit(0) - return nil - } - - s := ui.NewSpinbox(x, y) - newt.uiSpinbox = s - newt.uiBox = t.uiBox - t.uiBox.Append(s, stretchy) - - s.OnChanged(func(s *ui.Spinbox) { - newt.commonChange("Spinner") - }) - - return &newt -} diff --git a/toolkit/andlabs2/structs.go b/toolkit/andlabs2/structs.go deleted file mode 100644 index 2f3fa72..0000000 --- a/toolkit/andlabs2/structs.go +++ /dev/null @@ -1,249 +0,0 @@ -package main - -import "log" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - -import "github.com/davecgh/go-spew/spew" - -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 - -func setDefaultBehavior(s bool) { - defaultBehavior = s - if (defaultBehavior) { - if (DebugToolkit) { - log.Println("Setting this toolkit to use the default behavior.") - log.Println("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 - - DebugToolkit = false - } else { - log.Println("This toolkit is set to ignore the default behavior.") - } -} - -func SetDebugToolkit (s bool) { - DebugToolkit = s -} - -func GetDebugToolkit () bool { - return DebugToolkit -} - -// stores the raw toolkit internals -type andlabsT struct { - id string - - Name string - Width int - Height int - - OnChanged func(*andlabsT) - OnExit func(*andlabsT) - - Custom func() - - 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 - - // 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 - text string -} - -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 { - t.Dump() - if (DebugToolkit) { - log.Println("gui.Toolkit.Text() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t.uiEntry != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiEntry.Text()) - } - return t.uiEntry.Text() - } - if (t.uiMultilineEntry != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text()) - } - text := t.uiMultilineEntry.Text() - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() text =", text) - } - t.text = text - return text - } - if (t.uiCombobox != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.GetText() =", t.text) - } - return t.text - } - return "" -} - -func (t *andlabsT) SetText(s string) bool { - if (DebugToolkit) { - log.Println("gui.Toolkit.Text() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t.uiEntry != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) - } - t.uiEntry.SetText(s) - return true - } - if (t.uiMultilineEntry != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text) - } - t.uiMultilineEntry.SetText(s) - return true - } - return false -} - -func sanity(t *andlabsT) bool { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t.uiEntry == nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) - } - return false - } - return true -} - -func (t *andlabsT) SetValue(i int) bool { - log.Println("gui.Toolkit.SetValue() START") - if (sanity(t)) { - return false - } - t.Dump() - // panic("got to toolkit.SetValue") - return true -} - -func (t *andlabsT) Value() int { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() Enter") - scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) - } - if (t == nil) { - log.Println("gui.Toolkit.Value() can not get value t == nil") - return 0 - } - if (t.uiSlider != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiSlider.Value) - } - return t.uiSlider.Value() - } - if (t.uiSpinbox != nil) { - if (DebugToolkit) { - log.Println("gui.Toolkit.Value() =", t.uiSpinbox.Value) - } - return t.uiSpinbox.Value() - } - log.Println("gui.Toolkit.Value() Could not find a ui element to get a value from") - return 0 -} - -func (t *andlabsT) Dump() { - if ! DebugToolkit { - return - } - log.Println("gui.Toolkit.Dump() Name = ", t.Name, t.Width, t.Height) - if (t.uiBox != nil) { - log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox) - } - if (t.uiButton != nil) { - log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton) - } - if (t.uiCombobox != nil) { - log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox) - } - if (t.uiWindow != nil) { - log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow) - } - if (t.uiTab != nil) { - log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab) - } - if (t.uiGroup != nil) { - log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup) - } - if (t.uiEntry != nil) { - log.Println("gui.Toolkit.Dump() uiEntry =", t.uiEntry) - } - if (t.uiMultilineEntry != nil) { - log.Println("gui.Toolkit.Dump() uiMultilineEntry =", t.uiMultilineEntry) - } - if (t.uiSlider != nil) { - log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider) - } - if (t.uiCheckbox != nil) { - log.Println("gui.Toolkit.Dump() uiCheckbox =", t.uiCheckbox) - } - if (t.OnExit != nil) { - log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit) - } - if (t.Custom != nil) { - log.Println("gui.Toolkit.Dump() Custom =", t.Custom) - } - log.Println("gui.Toolkit.Dump() c =", t.c) - log.Println("gui.Toolkit.Dump() val =", t.val) - log.Println("gui.Toolkit.Dump() text =", t.text) -} diff --git a/toolkit/andlabs2/tab.go b/toolkit/andlabs2/tab.go deleted file mode 100644 index 0556fb9..0000000 --- a/toolkit/andlabs2/tab.go +++ /dev/null @@ -1,147 +0,0 @@ -package main - -import ( - "log" - "time" - - "git.wit.org/wit/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 (t *andlabsT) newTab(name string) *andlabsT { - // var w *ui.Window - var newt *andlabsT - - log.Println("gui.toolkit.AddTab() sleep 3") - - if (t.uiWindow == nil) { - log.Println("gui.Toolkit.UiWindow == nil. I can't add a toolbar without window") - return nil - } - - if (t.uiTab == nil) { - // this means you have to make a new tab - log.Println("gui.toolkit.NewTab() GOOD. This should be the first tab:", name) - newt = newTab(t.uiWindow, name) - t.uiTab = newt.uiTab - } else { - // this means you have to append a tab - log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name) - newt = t.appendTab(name) - } - - newt.Name = name - - if (DebugToolkit) { - log.Println("t:") - t.Dump() - log.Println("newt:") - newt.Dump() - } - - return newt -} - -// This sets _all_ the tabs to Margin = true -// -// TODO: do proper tab tracking (will be complicated). low priority -func tabSetMargined(tab *ui.Tab) { - c := tab.NumPages() - for i := 0; i < c; i++ { - if (DebugToolkit) { - log.Println("SetMargined", i, margin) - } - tab.SetMargined(i, margin) - } -} - -func newTab(w *ui.Window, name string) *andlabsT { - var t andlabsT - if (DebugToolkit) { - log.Println("gui.toolkit.NewTab() ADD", name) - } - - if (w == nil) { - log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") - log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") - log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") - time.Sleep(1 * time.Second) - return nil - } - if (DebugToolkit) { - log.Println("gui.toolkit.AddTab() START name =", name) - } - tab := ui.NewTab() - w.SetMargined(margin) - - hbox := ui.NewHorizontalBox() // this makes everything go along the horizon - hbox.SetPadded(padded) - tab.Append(name, hbox) - tabSetMargined(tab) // TODO: run this in the right place(?) - w.SetChild(tab) - - t.uiWindow = w - t.uiTab = tab - t.uiBox = hbox - return &t -} - -func (t *andlabsT) appendTab(name string) *andlabsT { - var newT andlabsT - if (DebugToolkit) { - log.Println("gui.toolkit.NewTab() ADD", name) - } - - if (t.uiTab == nil) { - log.Println("gui.Toolkit.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") - } - if (DebugToolkit) { - log.Println("gui.toolkit.AddTab() 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 -} - -func NewTab(parentW *toolkit.Widget, w *toolkit.Widget) { - var newt *andlabsT - log.Println("gui.andlabs.NewTab()", w.Name) - - t := mapToolkits[parentW] - if (t == nil) { - log.Println("go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name) - return - } - newt = t.newTab(w.Name) - mapWidgetsToolkits(w, newt) -} diff --git a/toolkit/andlabs2/textbox.go b/toolkit/andlabs2/textbox.go deleted file mode 100644 index c7a9390..0000000 --- a/toolkit/andlabs2/textbox.go +++ /dev/null @@ -1,70 +0,0 @@ -package main - -import "log" - -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 - - if (DebugToolkit) { - log.Println("gui.Toolkit.NewTextbox()", name) - } - if t.broken() { - return nil - } - - c := ui.NewNonWrappingMultilineEntry() - newt.uiMultilineEntry = c - - newt.uiBox = t.uiBox - newt.Name = name - if (defaultBehavior) { - t.uiBox.Append(c, true) - } else { - t.uiBox.Append(c, stretchy) - } - - c.OnChanged(func(spin *ui.MultilineEntry) { - newt.commonChange("Textbox") - }) - - return &newt -} - -func NewTextbox(parentW *toolkit.Widget, w *toolkit.Widget) { - var t, newt *andlabsT - log.Println("gui.andlabs.NewTextbox()", w.Name) - - t = mapToolkits[parentW] - if (t == nil) { - log.Println("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 - - if (DebugToolkit) { - log.Println("gui.Toolbox.NewTextbox() about to append to Box parent t:", w.Name) - t.Dump() - log.Println("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.Println("ERROR: wit/gui andlabs couldn't place this Textbox in a box") - return - } - - mapWidgetsToolkits(w, newt) -} diff --git a/toolkit/andlabs2/window.go b/toolkit/andlabs2/window.go deleted file mode 100644 index b360cb8..0000000 --- a/toolkit/andlabs2/window.go +++ /dev/null @@ -1,78 +0,0 @@ -package main - -import ( - "log" - - "github.com/andlabs/ui" - _ "github.com/andlabs/ui/winmanifest" - - "git.wit.org/wit/gui/toolkit" -) - -func (t *andlabsT) MessageWindow(msg1 string, msg2 string) { - ui.MsgBox(t.uiWindow, msg1, msg2) -} - -func (t *andlabsT) ErrorWindow(msg1 string, msg2 string) { - ui.MsgBoxError(t.uiWindow, msg1, msg2) -} - -func NewWindow(w *toolkit.Widget) { - var t *andlabsT - - if (DebugToolkit) { - log.Println("toolkit NewWindow", w.Name, w.Width, w.Height) - } - - if (w == nil) { - log.Println("wit/gui plugin error. widget == nil") - return - } - t = new(andlabsT) - // t = NewWindow2(w.Name, w.Width, w.Height) - -// 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 { - if (DebugToolkit) { - log.Println("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 - } - if (DebugToolkit) { - log.Println("andlabs.ui.Window().OnClosing() was not defined") - } - return false - }) - win.Show() - t.uiWindow = win - t.UiWindowBad = win // deprecate this as soon as possible - t.Name = w.Name - - mapWidgetsToolkits(w, t) - return -} - -func (t *andlabsT) SetWindowTitle(title string) { - if (DebugToolkit) { - log.Println("toolkit NewWindow", t.Name, "title", title) - } - win := t.uiWindow - if (win != nil) { - win.SetTitle(title) - } else { - if (DebugToolkit) { - log.Println("Setting the window title", title) - } - } -} diff --git a/toolkit/gocui/gocui.go b/toolkit/gocui/gocui.go index d614387..0d7c5a5 100644 --- a/toolkit/gocui/gocui.go +++ b/toolkit/gocui/gocui.go @@ -28,6 +28,7 @@ var ( helpLabel *gocui.View err error ch chan(func ()) + outf *os.File ) func Init() { @@ -50,6 +51,16 @@ func Init() { stringWidget = make(map[string]*toolkit.Widget) ch = make(chan func()) + + outf, err = os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + // hmm. where to put this? + // defer outf.Close() + + log.SetOutput(outf) + log.Println("This is a test log entry") } func Queue(f func()) { @@ -58,6 +69,8 @@ func Queue(f func()) { } func Main(f func()) { + // close the STDOUT log file + defer outf.Close() if (baseGui == nil) { panic("WTF Main()") } @@ -76,7 +89,7 @@ func layout(g *gocui.Gui) error { var err error maxX, _ := g.Size() - helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 11, 0) + helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 12, 0) if err != nil { if !errors.Is(err, gocui.ErrUnknownView) { return err @@ -90,6 +103,7 @@ func layout(g *gocui.Gui) error { 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, "STDOUT: /tmp/witgui.log") fmt.Fprintln(helpLabel, "Ctrl-C or Q: Exit") } return nil diff --git a/toolkit/gocui/keybindings.go b/toolkit/gocui/keybindings.go index 69def39..48edf71 100644 --- a/toolkit/gocui/keybindings.go +++ b/toolkit/gocui/keybindings.go @@ -130,7 +130,7 @@ func initKeybindings(g *gocui.Gui) error { g.SetCurrentView("help") // moveView(g, tmp, 0, -delta) if err := g.DeleteView("help"); err != nil { - panic(err) + log.Fatalln("gocui SetKeybinding()", err) } return nil }); err != nil { diff --git a/window.go b/window.go index 99e5880..9072bdd 100644 --- a/window.go +++ b/window.go @@ -14,7 +14,6 @@ import ( // my guess). func NewWindow() *Node { var newNode *Node -// var t *toolkit.Toolkit title := Config.Title // Windows are created off of the master node of the Binary Tree @@ -38,9 +37,6 @@ func NewWindow() *Node { log.Println("gui.Node.Window()", title) - // t = toolkit.NewWindow(title, w, h) - // n.toolkit = t - for _, aplug := range allPlugins { log.Println("gui.Node.NewWindow() toolkit plugin =", aplug.name) if (aplug.NewWindow == nil) { @@ -50,9 +46,5 @@ func NewWindow() *Node { aplug.NewWindow(&newNode.Widget) } - // TODO: this is still confusing and probably wrong. This needs to communicate through a channel - // newNode.toolkit = n.toolkit.NewButton(name) - // newNode.toolkit.Custom = newNode.Widget.Custom - return newNode } -- cgit v1.2.3