summaryrefslogtreecommitdiff
path: root/toolkit/andlabs2
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2022-11-13 08:53:03 -0600
committerJeff Carr <[email protected]>2022-11-13 08:53:03 -0600
commit207cf7ea16f1da8fa9f893504d77a2856298cc22 (patch)
tree54d513b83ce797be75268f7d8867e0b01ab8f23e /toolkit/andlabs2
parented382bec55be25039e4dcf020d1512139855c9bb (diff)
Massive refactor to use go plugins. This is neat.
update README.md set xterm title. make os.Exit() default on window close add a toolkit.Widget to the node structure remove 'Greeter' symbol mapping scheme removed the testing greeter code plugins: attempt to load plugins in a sensible order andlabs/ui: working andlabs/ui plugin (andlabs2) buttons work in andlabs plugin TODO: re-implement non-plugin version for Windows mswindows doesn't support go plugins yet gocui: put the gocui console so file in the binary does a full init of gocui plugin Button() and Group() working very well with gogui cleanly exit gocui technically you can load two toolkits at the same time kinda both working at the same time. esoteric two working plugins at the same time give up working on two gui's at the same time this is fun, but _not interesting wow. this actually works. NewButton() from both toolkits examples: all the examples run again remove early helloplugin example buttonplugin example cmd code buttonplugin runs and ldd is minimum Signed-off-by: Jeff Carr <[email protected]>
Diffstat (limited to 'toolkit/andlabs2')
-rw-r--r--toolkit/andlabs2/Makefile4
-rw-r--r--toolkit/andlabs2/box.go66
-rw-r--r--toolkit/andlabs2/button.go67
-rw-r--r--toolkit/andlabs2/checkbox.go34
-rw-r--r--toolkit/andlabs2/common.go61
-rw-r--r--toolkit/andlabs2/demo.go92
-rw-r--r--toolkit/andlabs2/dropdown.go90
-rw-r--r--toolkit/andlabs2/group.go56
-rw-r--r--toolkit/andlabs2/label.go42
-rw-r--r--toolkit/andlabs2/main.go56
-rw-r--r--toolkit/andlabs2/plugin.go43
-rw-r--r--toolkit/andlabs2/slider.go48
-rw-r--r--toolkit/andlabs2/spinner.go30
-rw-r--r--toolkit/andlabs2/structs.go249
-rw-r--r--toolkit/andlabs2/tab.go147
-rw-r--r--toolkit/andlabs2/textbox.go70
-rw-r--r--toolkit/andlabs2/window.go78
17 files changed, 1233 insertions, 0 deletions
diff --git a/toolkit/andlabs2/Makefile b/toolkit/andlabs2/Makefile
new file mode 100644
index 0000000..54cf7f5
--- /dev/null
+++ b/toolkit/andlabs2/Makefile
@@ -0,0 +1,4 @@
+all: plugin
+
+plugin:
+ GO111MODULE="off" go build -buildmode=plugin -o ../andlabs2.so
diff --git a/toolkit/andlabs2/box.go b/toolkit/andlabs2/box.go
new file mode 100644
index 0000000..bb9945e
--- /dev/null
+++ b/toolkit/andlabs2/box.go
@@ -0,0 +1,66 @@
+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
new file mode 100644
index 0000000..bd80683
--- /dev/null
+++ b/toolkit/andlabs2/button.go
@@ -0,0 +1,67 @@
+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
new file mode 100644
index 0000000..b4b1524
--- /dev/null
+++ b/toolkit/andlabs2/checkbox.go
@@ -0,0 +1,34 @@
+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
new file mode 100644
index 0000000..fc6cbe8
--- /dev/null
+++ b/toolkit/andlabs2/common.go
@@ -0,0 +1,61 @@
+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
new file mode 100644
index 0000000..0781f88
--- /dev/null
+++ b/toolkit/andlabs2/demo.go
@@ -0,0 +1,92 @@
+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
new file mode 100644
index 0000000..1e1886a
--- /dev/null
+++ b/toolkit/andlabs2/dropdown.go
@@ -0,0 +1,90 @@
+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
new file mode 100644
index 0000000..39f740b
--- /dev/null
+++ b/toolkit/andlabs2/group.go
@@ -0,0 +1,56 @@
+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
new file mode 100644
index 0000000..c5a6896
--- /dev/null
+++ b/toolkit/andlabs2/label.go
@@ -0,0 +1,42 @@
+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
new file mode 100644
index 0000000..8a28710
--- /dev/null
+++ b/toolkit/andlabs2/main.go
@@ -0,0 +1,56 @@
+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
new file mode 100644
index 0000000..f78e95e
--- /dev/null
+++ b/toolkit/andlabs2/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/andlabs2/slider.go b/toolkit/andlabs2/slider.go
new file mode 100644
index 0000000..f9ff0f3
--- /dev/null
+++ b/toolkit/andlabs2/slider.go
@@ -0,0 +1,48 @@
+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
new file mode 100644
index 0000000..6505b48
--- /dev/null
+++ b/toolkit/andlabs2/spinner.go
@@ -0,0 +1,30 @@
+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
new file mode 100644
index 0000000..2f3fa72
--- /dev/null
+++ b/toolkit/andlabs2/structs.go
@@ -0,0 +1,249 @@
+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
new file mode 100644
index 0000000..0556fb9
--- /dev/null
+++ b/toolkit/andlabs2/tab.go
@@ -0,0 +1,147 @@
+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
new file mode 100644
index 0000000..c7a9390
--- /dev/null
+++ b/toolkit/andlabs2/textbox.go
@@ -0,0 +1,70 @@
+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
new file mode 100644
index 0000000..b360cb8
--- /dev/null
+++ b/toolkit/andlabs2/window.go
@@ -0,0 +1,78 @@
+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)
+ }
+ }
+}