summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2024-01-17 21:31:49 -0600
committerJeff Carr <[email protected]>2024-01-17 21:31:49 -0600
commit841e6252c95244f0ee7faf2c01d33f69a8ab483a (patch)
treeef400228622b87611168db2227269ba7fd56625d
parentba95c13799740b5f55541fc5e8ab9f1d34f7e421 (diff)
common tree package for toolkitsv0.12.4
This update provides *lots* of toolkit updates. This will allow the next step of debugging the gocui toolkit to make it work again. There are new common routines for handling the plugin channel communication Signed-off-by: Jeff Carr <[email protected]>
-rw-r--r--andlabs/action.go146
-rw-r--r--andlabs/add.go58
-rw-r--r--andlabs/addText.go34
-rw-r--r--andlabs/box.go15
-rw-r--r--andlabs/button.go19
-rw-r--r--andlabs/checkbox.go15
-rw-r--r--andlabs/combobox.go54
-rw-r--r--[l---------]andlabs/common.go62
-rw-r--r--andlabs/debug.go4
-rw-r--r--andlabs/dropdown.go72
-rw-r--r--andlabs/grid.go10
-rw-r--r--andlabs/group.go12
-rw-r--r--andlabs/image.go2
-rw-r--r--andlabs/label.go11
-rw-r--r--andlabs/main.go49
-rw-r--r--andlabs/place.go87
-rw-r--r--andlabs/setText.go43
-rw-r--r--andlabs/slider.go19
-rw-r--r--andlabs/spinner.go15
-rw-r--r--andlabs/structs.go12
-rw-r--r--andlabs/textbox.go19
-rw-r--r--andlabs/tree.go31
-rw-r--r--andlabs/widget.go6
-rw-r--r--andlabs/window.go12
-rw-r--r--common/addNode.go68
-rw-r--r--[l---------]gocui/common.go219
-rw-r--r--gocui/plugin.go2
-rw-r--r--gocui/view.go3
-rw-r--r--gocui/widget.go4
-rw-r--r--nocui/action.go159
-rw-r--r--nocui/common.go218
-rw-r--r--nocui/event.go19
-rw-r--r--nocui/go.mod7
-rw-r--r--nocui/go.sum10
-rw-r--r--nocui/main.go55
-rw-r--r--nocui/stdin.go79
-rw-r--r--nocui/structs.go9
-rw-r--r--nocui/tree.go24
-rw-r--r--nocui/widget.go30
-rw-r--r--tree/addNode.go47
-rw-r--r--tree/common.go35
-rw-r--r--tree/debug.go44
-rw-r--r--tree/event.go88
-rw-r--r--tree/init.go58
-rw-r--r--tree/plugin.go (renamed from common/plugin.go)33
-rw-r--r--tree/structs.go (renamed from common/structs.go)32
46 files changed, 1186 insertions, 864 deletions
diff --git a/andlabs/action.go b/andlabs/action.go
index b1046ba..28c78d5 100644
--- a/andlabs/action.go
+++ b/andlabs/action.go
@@ -1,47 +1,99 @@
package main
import (
- "strconv"
- "go.wit.com/dev/andlabs/ui"
+ "errors"
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
+// this will check to make sure that the node
+// is valid for making a New TK andlabs widget
+// Basically, it makes sure there is a parent ID
+// and that there already a widget created
+func notNew(n *tree.Node) bool {
+ if n == nil {
+ log.Warn("ready() n = nil")
+ return true
+ }
+ if n.TK != nil {
+ log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
+ return true
+ }
+ if n.Parent == nil {
+ log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
+ return true
+ }
+ if n.Parent.TK == nil {
+ log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
+ log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
+ return true
+ }
+ // this means you can add a new widgets
+ return false
+}
+
+func ready(n *tree.Node) bool {
+ if n == nil {
+ log.Warn("ready() n = nil")
+ return false
+ }
+ if n.TK == nil {
+ log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
+ return false
+ }
+ if n.Parent == nil {
+ log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
+ return false
+ }
+ if n.Parent.TK == nil {
+ log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
+ log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
+ return false
+ }
+ return true
+}
func (n *node) ready() bool {
if n == nil { return false }
if n.tk == nil { return false }
return true
}
-func (n *node) show(b bool) {
- if n.tk == nil {
+func show(n *tree.Node, b bool) {
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
+ // tk = getTK(n)
+
+ if tk == nil {
return
}
- if n.tk.uiControl == nil {
+ if tk.uiControl == nil {
return
}
if (b) {
- n.tk.uiControl.Show()
+ tk.uiControl.Show()
} else {
- n.tk.uiControl.Hide()
+ tk.uiControl.Hide()
}
}
-func (n *node) enable(b bool) {
+func enable(n *tree.Node, b bool) {
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
if n == nil {
panic("WHAT? enable was passed nil. How does this even happen?")
}
- if n.tk == nil {
+ if tk == nil {
return
}
- if n.tk.uiControl == nil {
+ if tk.uiControl == nil {
return
}
if (b) {
- n.tk.uiControl.Enable()
+ tk.uiControl.Enable()
} else {
- n.tk.uiControl.Disable()
+ tk.uiControl.Disable()
}
}
@@ -152,73 +204,88 @@ func (n *node) Delete() {
func rawAction(a *widget.Action) {
log.Log(INFO, "rawAction() START a.ActionType =", a.ActionType, "a.Value", a.Value)
- if (a.ActionType == widget.InitToolkit) {
- // TODO: make sure to only do this once
- // go uiMain.Do(func() {
- // ui.Main(demoUI)
- // go catchActionChannel()
- // })
- // try doing this on toolkit load in init()
+ if (a.ActionType == widget.ToolkitInit) {
+ Init()
+ return
+ }
+ switch a.WidgetType {
+ case widget.Root:
+ me.treeRoot = me.myTree.AddNode(a)
+ log.Log(INFO, "doAction() found treeRoot")
return
}
- log.Log(INFO, "rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
+ log.Warn("andlabs rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId, a.ActionType)
switch a.WidgetType {
case widget.Flag:
log.Log(ERROR, "rawAction() RE-IMPLEMENT LOG FLAGS")
return
}
- n := me.rootNode.findWidgetId(a.WidgetId)
+ if me.treeRoot == nil {
+ panic("me.treeRoot == nil")
+ }
+
+ n := me.treeRoot.FindWidgetId(a.WidgetId)
if (a.ActionType == widget.Add) {
- ui.QueueMain(func() {
+ me.treeRoot.ListWidgets()
+ // ui.QueueMain(func() {
add(a)
- })
+ // })
// TODO: remove this artificial delay
// sleep(.001)
return
}
if (a.ActionType == widget.Dump) {
- log.Log(NOW, "rawAction() Dump =", a.ActionType, a.WidgetType, n.progname)
- me.rootNode.listChildren(true)
+ log.Log(NOW, "rawAction() Dump =", a.ActionType, a.WidgetType, n.State.ProgName)
+ // me.rootNode.listChildren(true)
return
}
if (n == nil) {
- me.rootNode.listChildren(true)
- log.Log(NOW, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
+ log.Error(errors.New("andlabs rawAction() ERROR findWidgetId found nil"), a.ActionType, a.WidgetType)
log.Log(NOW, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
log.Log(NOW, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
log.Log(NOW, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
+ me.treeRoot.ListWidgets()
return
- panic("findWidgetId found nil for id = " + strconv.Itoa(a.WidgetId))
+ panic("findWidgetId found nil for id = " + string(a.WidgetId))
}
switch a.ActionType {
case widget.Show:
- n.show(true)
+ show(n, true)
+ // n.show(true)
case widget.Hide:
- n.show(false)
+ show(n, false)
+ //n.show(false)
case widget.Enable:
- n.enable(true)
+ enable(n, true)
+ // n.enable(true)
case widget.Disable:
- log.Warn("andlabs got disable for", n.WidgetId, n.progname)
- n.enable(false)
+ log.Warn("andlabs got disable for", n.WidgetId, n.State.ProgName)
+ enable(n, false)
+ // n.enable(false)
case widget.Get:
- n.setText(a)
+ // n.setText(a)
+ setText(n, a)
case widget.GetText:
switch a.WidgetType {
case widget.Textbox:
- a.Value = n.value
+ a.Value = n.State.Value
}
case widget.Set:
- n.setText(a)
+ setText(n, a)
+ // n.setText(a)
case widget.SetText:
- n.setText(a)
+ setText(n, a)
+ // n.setText(a)
case widget.AddText:
- n.addText(a)
+ addText(n, a)
+ // n.addText(a)
+ /*
case widget.Margin:
n.pad(true)
case widget.Unmargin:
@@ -231,8 +298,7 @@ func rawAction(a *widget.Action) {
n.Delete()
case widget.Move:
log.Log(NOW, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
- newParent := me.rootNode.findWidgetId(a.ParentId)
- n.move(newParent)
+ */
default:
log.Log(ERROR, "rawAction() Unknown =", a.ActionType, a.WidgetType)
}
diff --git a/andlabs/add.go b/andlabs/add.go
index ffe2cc4..a47d697 100644
--- a/andlabs/add.go
+++ b/andlabs/add.go
@@ -6,57 +6,67 @@ import (
)
func add(a *widget.Action) {
+ log.Warn("andlabs add()", a.WidgetId, a.State.ProgName)
if (a.WidgetType == widget.Root) {
- me.rootNode = addNode(a)
+ if me.treeRoot == nil {
+ me.treeRoot = me.myTree.AddNode(a)
+ }
return
}
- n := addNode(a)
+ // n := addNode(a)
+ n := me.myTree.AddNode(a)
- p := n.parent
+ p := n.Parent
switch n.WidgetType {
case widget.Window:
- newWindow(n)
+ log.Warn("SPEEDY Add window", n.WidgetId, n.GetProgName())
+ newWindow(p, n)
return
+ case widget.Group:
+ log.Warn("SPEEDY Add Group", n.WidgetId, n.GetProgName())
+ newGroup(p, n)
+ return
+ case widget.Grid:
+ newGrid(n)
+ return
+ case widget.Box:
+ newBox(n)
+ return
+ /*
case widget.Tab:
- p.newTab(n)
+ newTab(n)
return
+ */
case widget.Label:
- p.newLabel(n)
+ newLabel(p, n)
return
case widget.Button:
- p.newButton(n)
- return
- case widget.Grid:
- p.newGrid(n)
+ newButton(p, n)
return
case widget.Checkbox:
- p.newCheckbox(n)
+ newCheckbox(p, n)
return
case widget.Spinner:
- p.newSpinner(n)
+ newSpinner(p, n)
return
case widget.Slider:
- p.newSlider(n)
+ newSlider(p, n)
return
case widget.Dropdown:
- p.newDropdown(n)
+ newDropdown(p, n)
return
case widget.Combobox:
- p.newCombobox(n)
+ newCombobox(p, n)
return
case widget.Textbox:
- p.newTextbox(n)
- return
- case widget.Group:
- p.newGroup(n)
- return
- case widget.Box:
- p.newBox(n)
+ newTextbox(p, n)
return
+ /*
case widget.Image:
- p.newImage(n)
+ newImage(p, n)
return
+ */
default:
- log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.progname)
+ log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.State.ProgName)
}
}
diff --git a/andlabs/addText.go b/andlabs/addText.go
index cbc9269..d335be2 100644
--- a/andlabs/addText.go
+++ b/andlabs/addText.go
@@ -3,22 +3,40 @@ package main
import (
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-func (n *node) addText(a *widget.Action) {
- log.Log(CHANGE, "addText() START with a.Value =", a.Value)
- t := n.tk
- if (t == nil) {
- log.Log(ERROR, "addText error. tk == nil", n.progname, n.WidgetId)
+func compareStrings(n *tree.Node, ss []string) {
+}
+
+// func (n *node) addText(a *widget.Action) {
+func addText(n *tree.Node, a *widget.Action) {
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
+ log.Warn("andlabs addText() START with a.Value =", a.Value)
+ if (tk == nil) {
+ log.Log(ERROR, "addText error. tk == nil", n.State.ProgName, n.WidgetId)
return
}
- log.Log(CHANGE, "addText() Attempt on", n.WidgetType, "with", a.Value)
+ log.Warn("andlabs addText() Attempt on", n.WidgetType, "with", a.Value)
switch n.WidgetType {
case widget.Dropdown:
- n.addDropdownName(widget.GetString(a.Value))
+ for i, s := range a.State.Strings {
+ log.Warn("andlabs a.State.Strings =", i, s)
+ _, ok := n.Strings[s]
+ // If the key exists
+ if ok {
+ log.Warn("andlabs a.State.Strings is here", i, s)
+ } else {
+ log.Warn("andlabs is not here", i, s)
+ addDropdownName(n, s)
+ // TODO: make numbers
+ n.Strings[s] = 21
+ }
+ }
case widget.Combobox:
- n.addComboboxName(widget.GetString(a.Value))
+ addComboboxName(n, widget.GetString(a.Value))
default:
log.Log(ERROR, "plugin Send() Don't know how to addText on", n.WidgetType, "yet", a.ActionType)
}
diff --git a/andlabs/box.go b/andlabs/box.go
index d06bf60..df4cfba 100644
--- a/andlabs/box.go
+++ b/andlabs/box.go
@@ -2,17 +2,19 @@ package main
import (
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
// make new Box here
-func (p *node) newBox(n *node) {
+func newBox(n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
var box *ui.Box
- if n.direction == widget.Horizontal {
+ if n.State.Direction == widget.Horizontal {
box = ui.NewHorizontalBox()
} else {
box = ui.NewVerticalBox()
@@ -22,8 +24,8 @@ func (p *node) newBox(n *node) {
newt.uiBox = box
newt.uiControl = box
newt.boxC = 0
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(n.Parent, n)
}
/*
@@ -46,10 +48,11 @@ func (p *node) newBox(n *node) {
TODO: handle user killing/closing a window using the OS
*/
-func (n *node) rawBox() *ui.Box {
+// func (n *node) rawBox() *ui.Box {
+func rawBox(n *tree.Node) *ui.Box {
var box *ui.Box
- if n.direction == widget.Horizontal {
+ if n.State.Direction == widget.Horizontal {
box = ui.NewHorizontalBox()
} else {
box = ui.NewVerticalBox()
diff --git a/andlabs/button.go b/andlabs/button.go
index 0cc4f52..4bbc8f2 100644
--- a/andlabs/button.go
+++ b/andlabs/button.go
@@ -1,25 +1,28 @@
package main
import (
- "go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newButton(n *node) {
- t := p.tk
+// func (p *node) newButton(n *node) {
+func newButton(p *tree.Node, n *tree.Node) {
+ if notNew(n) { return }
+ var ptk *guiWidget
+ ptk = p.TK.(*guiWidget)
newt := new(guiWidget)
- b := ui.NewButton(widget.GetString(n.value))
+ b := ui.NewButton(n.GetLabel())
newt.uiButton = b
newt.uiControl = b
- newt.parent = t
+ newt.parent = ptk
b.OnClicked(func(*ui.Button) {
- n.doUserEvent()
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/checkbox.go b/andlabs/checkbox.go
index d44e458..d447baf 100644
--- a/andlabs/checkbox.go
+++ b/andlabs/checkbox.go
@@ -1,23 +1,26 @@
package main
import (
+ "go.wit.com/gui/toolkits/tree"
+
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newCheckbox(n *node) {
+func newCheckbox(p *tree.Node, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- newt.uiCheckbox = ui.NewCheckbox(n.label)
+ newt.uiCheckbox = ui.NewCheckbox(n.GetLabel())
newt.uiControl = newt.uiCheckbox
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
- n.value = newt.checked()
- n.doUserEvent()
+ n.SetValue(newt.checked())
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
func (t *guiWidget) checked() bool {
diff --git a/andlabs/combobox.go b/andlabs/combobox.go
index 0dd16c6..adfea36 100644
--- a/andlabs/combobox.go
+++ b/andlabs/combobox.go
@@ -5,10 +5,11 @@ import (
_ "go.wit.com/dev/andlabs/ui/winmanifest"
"go.wit.com/log"
- "go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-func (p *node) newCombobox(n *node) {
+func newCombobox(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
cb := ui.NewEditableCombobox()
@@ -20,46 +21,53 @@ func (p *node) newCombobox(n *node) {
newt.val = make(map[int]string)
cb.OnChanged(func(spin *ui.EditableCombobox) {
- n.value = spin.Text()
+ n.SetValue(spin.Text())
log.Warn("combobox changed =" + spin.Text() + ".")
- n.doUserEvent()
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
+ log.Warn("add combobox entries on create:", n.State.Strings)
+ log.Warn("add combobox entries on create:", n.State.Strings)
+ log.Warn("add combobox entries on create:", n.State.Strings)
// add the initial combobox entries
- for i, s := range n.strings {
- log.Warn("add combobox entries on create", n.progname, i, s)
- n.addComboboxName(s)
+ for i, s := range n.State.Strings {
+ log.Warn("add combobox entries on create", n.GetProgName(), i, s)
+ addComboboxName(n, s)
}
- cur := widget.GetString(n.value)
- log.Warn("add combobox: TODO: set default value on create", n.progname, cur)
- n.setComboboxName(cur)
+ cur := n.String()
+ log.Warn("add combobox: TODO: set default value on create", n.GetProgName(), cur)
+ setComboboxName(n, cur)
}
-func (n *node) addComboboxName(s string) {
- if ! n.ready() { return }
+func addComboboxName(n *tree.Node, s string) {
+ if ! ready(n) { return }
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
log.Log(INFO, "addComboboxName()", n.WidgetId, "add:", s)
- n.tk.uiEditableCombobox.Append(s)
- if (n.tk.val == nil) {
+ tk.uiEditableCombobox.Append(s)
+ if (tk.val == nil) {
log.Log(INFO, "make map didn't work")
return
}
- n.tk.val[n.tk.c] = s
+ tk.val[tk.c] = s
// If this is the first menu added, set the dropdown to it
- if (n.tk.c == 0) {
+ if (tk.c == 0) {
log.Log(INFO, "THIS IS THE FIRST combobox", s)
- n.tk.uiEditableCombobox.SetText(s)
+ tk.uiEditableCombobox.SetText(s)
}
- n.tk.c = n.tk.c + 1
+ tk.c = tk.c + 1
}
-func (n *node) setComboboxName(s string) bool {
- if ! n.ready() { return false}
+func setComboboxName(n *tree.Node, s string) bool {
+ if ! ready(n) { return false}
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
log.Log(INFO, "SetComboboxName()", n.WidgetId, ",", s)
- n.tk.uiEditableCombobox.SetText(s)
+ tk.uiEditableCombobox.SetText(s)
return false
}
diff --git a/andlabs/common.go b/andlabs/common.go
index 35417a1..1cfac84 120000..100644
--- a/andlabs/common.go
+++ b/andlabs/common.go
@@ -1 +1,61 @@
-../nocui/common.go \ No newline at end of file
+package main
+
+import (
+ "go.wit.com/gui/widget"
+)
+
+type node struct {
+ parent *node
+ children []*node
+
+ WidgetId int // widget ID
+ WidgetType widget.WidgetType
+ ParentId int // parent ID
+
+ state widget.State
+
+ // a reference name for programming and debuggign. Must be unique
+ progname string
+
+ // the text used for button labesl, window titles, checkbox names, etc
+ label string
+
+ // horizontal means layout widgets like books on a bookshelf
+ // vertical means layout widgets like books in a stack
+ // direction widget.Orientation
+ direction widget.Orientation
+
+ // This is how the values are passed back and forth
+ // values from things like checkboxes & dropdown's
+ value any
+
+ strings []string
+
+ // This is used for things like a slider(0,100)
+ X int
+ Y int
+
+ // This is for the grid size & widget position
+ W int
+ H int
+ AtW int
+ AtH int
+
+ vals []string // dropdown menu items
+
+ // horizontal bool `default:false`
+
+ hasTabs bool // does the window have tabs?
+ currentTab bool // the visible tab
+
+ // the internal plugin toolkit structure
+ // in the gtk plugin, it has gtk things like margin & border settings
+ // in the text console one, it has text console things like colors for menus & buttons
+ tk *guiWidget
+}
+
+/*
+func (n *node) doUserEvent() {
+ log.Log(ERROR, "doUserEvent() ERROR")
+}
+*/
diff --git a/andlabs/debug.go b/andlabs/debug.go
index 7e6bb24..51048d5 100644
--- a/andlabs/debug.go
+++ b/andlabs/debug.go
@@ -1,8 +1,6 @@
package main
import (
- "strconv"
-
"go.wit.com/log"
// "go.wit.com/gui/widget"
)
@@ -94,7 +92,7 @@ func (n *node) dumpWidget(b bool) {
}
info = n.WidgetType.String()
- d = strconv.Itoa(n.WidgetId) + " " + info + " " + n.progname
+ d = string(n.WidgetId) + " " + info + " " + n.progname
var tabs string
for i := 0; i < listChildrenDepth; i++ {
diff --git a/andlabs/dropdown.go b/andlabs/dropdown.go
index 0795264..6a1bd64 100644
--- a/andlabs/dropdown.go
+++ b/andlabs/dropdown.go
@@ -5,12 +5,13 @@ import (
_ "go.wit.com/dev/andlabs/ui/winmanifest"
"go.wit.com/log"
- "go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-func (p *node) newDropdown(n *node) {
+func newDropdown(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- log.Log(INFO, "gui.Toolbox.newDropdown() START", n.progname)
+ log.Log(INFO, "gui.Toolbox.newDropdown() START", n.GetProgName())
cb := ui.NewCombobox()
newt.uiCombobox = cb
@@ -24,60 +25,69 @@ func (p *node) newDropdown(n *node) {
i := spin.Selected()
if (newt.val == nil) {
log.Log(ERROR, "make map didn't work")
- n.value = "map did not work. ui.Combobox error"
+ n.SetValue("map did not work. ui.Combobox error")
} else {
- n.value = newt.val[i]
+ n.SetValue(newt.val[i])
}
- n.doUserEvent()
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
- if n.strings == nil {return}
+ log.Warn("add dropdown entries on create:", n.State.Strings)
+ log.Warn("add dropdown entries on create:", n.State.Strings)
+ log.Warn("add dropdown entries on create:", n.State.Strings)
+ if n.State.Strings == nil {return}
// add the initial dropdown entries
- for i, s := range n.strings {
- log.Warn("add dropdown: add entries on create", n.progname, i, s)
- n.addDropdownName(s)
+ for i, s := range n.State.Strings {
+ log.Warn("add dropdown: add entries on create", n.GetProgName(), i, s)
+ addDropdownName(n, s)
}
- cur := widget.GetString(n.value)
- log.Warn("add dropdown: set default value on create", n.progname, cur)
- n.setDropdownName(cur)
+ cur := n.String()
+ log.Warn("add dropdown: set default value on create", n.GetProgName(), cur)
+ setDropdownName(n, cur)
}
-func (n *node) SetDropdownInt(i int) {
- if ! n.ready() { return }
- n.tk.uiCombobox.SetSelected(i)
+func setDropdownInt(n *tree.Node, i int) {
+ if ! ready(n) { return }
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
+ tk.uiCombobox.SetSelected(i)
}
-func (n *node) addDropdownName(s string) {
- if ! n.ready() { return }
+func addDropdownName(n *tree.Node, s string) {
+ if ! ready(n) { return }
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
log.Log(INFO, "addDropdownName()", n.WidgetId, "add:", s)
- n.tk.uiCombobox.Append(s)
- if (n.tk.val == nil) {
+ tk.uiCombobox.Append(s)
+ if (tk.val == nil) {
log.Log(INFO, "make map didn't work")
return
}
- n.tk.val[n.tk.c] = s
+ tk.val[tk.c] = s
// If this is the first menu added, set the dropdown to it
- if (n.tk.c == 0) {
+ if (tk.c == 0) {
log.Log(INFO, "THIS IS THE FIRST Dropdown", s)
- n.tk.uiCombobox.SetSelected(0)
+ tk.uiCombobox.SetSelected(0)
}
- n.tk.c = n.tk.c + 1
+ tk.c = tk.c + 1
}
-func (n *node) setDropdownName(s string) bool {
- if ! n.ready() { return false}
+func setDropdownName(n *tree.Node, s string) bool {
+ if ! ready(n) { return false}
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
log.Log(INFO, "SetDropdownName()", n.WidgetId, ",", s)
- for i, tmp := range n.tk.val {
+ for i, tmp := range tk.val {
if s == tmp {
- n.value = s
- n.SetDropdownInt(i)
+ n.SetValue(s)
+ setDropdownInt(n, i)
log.Warn("SetDropdownInt() worked", tmp, i)
return true
}
diff --git a/andlabs/grid.go b/andlabs/grid.go
index 2561648..bbb2c8b 100644
--- a/andlabs/grid.go
+++ b/andlabs/grid.go
@@ -1,6 +1,8 @@
package main
import (
+ "go.wit.com/gui/toolkits/tree"
+
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
@@ -10,9 +12,9 @@ import (
// -- (1,1) -- (2,1) -- (3,1) --
// -- (1,2) -- (2,1) -- (3,1) --
// -----------------------------
-func (p *node) newGrid(n *node) {
+func newGrid(n *tree.Node) {
+ if notNew(n) { return }
var newt *guiWidget
-
newt = new(guiWidget)
c := ui.NewGrid()
@@ -20,6 +22,6 @@ func (p *node) newGrid(n *node) {
newt.uiControl = c
c.SetPadded(true)
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(n.Parent, n)
}
diff --git a/andlabs/group.go b/andlabs/group.go
index 8faa6a4..efbabd9 100644
--- a/andlabs/group.go
+++ b/andlabs/group.go
@@ -1,20 +1,22 @@
package main
import (
- "go.wit.com/gui/widget"
+ // "go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newGroup(n *node) {
+func newGroup(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- g := ui.NewGroup(widget.GetString(n.value))
+ g := ui.NewGroup(n.GetLabel())
g.SetMargined(true)
newt.uiGroup = g
newt.uiControl = g
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/image.go b/andlabs/image.go
index f5cf941..badd8b4 100644
--- a/andlabs/image.go
+++ b/andlabs/image.go
@@ -16,7 +16,7 @@ func (p *node) newImage(n *node) {
// newt.uiControl = img
n.tk = newt
- p.place(n)
+ // p.place(n)
}
/*
if (a.Name == "image") {
diff --git a/andlabs/label.go b/andlabs/label.go
index bcdaf7a..12bc9c1 100644
--- a/andlabs/label.go
+++ b/andlabs/label.go
@@ -1,18 +1,19 @@
package main
import (
- "go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newLabel(n *node) {
+func newLabel(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- c := ui.NewLabel(widget.GetString(n.value))
+ c := ui.NewLabel(n.GetLabel())
newt.uiLabel = c
newt.uiControl = c
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/main.go b/andlabs/main.go
index 5a6d383..b1e0e47 100644
--- a/andlabs/main.go
+++ b/andlabs/main.go
@@ -2,8 +2,11 @@ package main
import (
"sync"
+ "runtime/debug"
+
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
"go.wit.com/dev/andlabs/ui"
// the _ means we only need this for the init()
@@ -17,7 +20,11 @@ var muAction sync.Mutex
func queueMain(currentA widget.Action) {
defer func() {
if r := recover(); r != nil {
- log.Warn("YAHOOOO Recovered in main application:", r)
+ log.Warn("YAHOOOO Recovered in queueMain() application:", r)
+ log.Println("Recovered from panic:", r)
+ log.Println("Stack trace:")
+ debug.PrintStack()
+ me.myTree.DoToolkitPanic()
}
}()
ui.QueueMain( func() {
@@ -25,29 +32,14 @@ func queueMain(currentA widget.Action) {
})
}
-func catchActionChannel() {
- log.Log(INFO, "catchActionChannel() START")
- for {
- log.Log(INFO, "catchActionChannel() for loop")
- select {
- case a := <-pluginChan:
- log.Log(INFO, "catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
- log.Log(INFO, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
- muAction.Lock()
- // TODO ui.QueueMain(f)
- // TODO ui.QueueMain( func() {rawAction(a)} )
- // rawAction(a)
- queueMain(a)
- muAction.Unlock()
- log.Log(INFO, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
- }
- }
-}
-
func guiMain() {
defer func() {
if r := recover(); r != nil {
- log.Warn("YAHOOOO Recovered in main application:", r)
+ log.Warn("YAHOOOO Recovered in guiMain application:", r)
+ log.Println("Recovered from panic:", r)
+ log.Println("Stack trace:")
+ debug.PrintStack()
+ me.myTree.DoToolkitPanic()
}
}()
ui.Main(func() {
@@ -55,6 +47,10 @@ func guiMain() {
})
}
+func Init() {
+ log.Warn("Init() TODO: move init() to here")
+}
+
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func init() {
log.Log(INFO, "Init() START")
@@ -63,15 +59,12 @@ func init() {
// log.Log(INFO, "init() Setting defaultBehavior = true")
setDefaultBehavior(true)
+ me.myTree = tree.New()
+ me.myTree.PluginName = "andlabs"
+ me.myTree.ActionFromChannel = queueMain
+
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
// actually, this probably breaks the macos build
go guiMain()
-
- // andlabs = make(map[int]*andlabsT)
- pluginChan = make(chan widget.Action, 1)
-
- log.Log(INFO, "Init() start channel reciever")
- go catchActionChannel()
- log.Log(INFO, "Init() END")
}
diff --git a/andlabs/place.go b/andlabs/place.go
index 94a16b2..25672e7 100644
--- a/andlabs/place.go
+++ b/andlabs/place.go
@@ -1,12 +1,15 @@
package main
import (
+ // "os"
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
"go.wit.com/log"
"go.wit.com/gui/widget"
+
+ "go.wit.com/gui/toolkits/tree"
)
// This routine is very specific to this toolkit
@@ -33,62 +36,78 @@ import (
// -- (0,0) -- (1,0) -- (1,0) --
// -- (0,1) -- (1,1) -- (1,1) --
// -----------------------------
-func (p *node) place(n *node) bool {
- log.Log(INFO, "place() START", n.WidgetType, n.progname)
- if (p.tk == nil) {
- log.Log(ERROR, "p.tk == nil", p.progname, p.ParentId, p.WidgetType, p.tk)
- log.Log(ERROR, "n = ", n.progname, n.ParentId, n.WidgetType, n.tk)
- panic("p.tk == nil")
+func place(p *tree.Node, n *tree.Node) bool {
+ log.Warn("SPEEDY newplace() 1 START", n.WidgetId, n.GetProgName(), n.GetLabel(), n.String())
+ log.Warn("SPEEDY newplace() n.State.Strings =", n.State.Strings)
+ log.Log(INFO, "place() 1 START", n.WidgetType, n.GetProgName(), n.GetLabel())
+ if ! ready(n) {
+ log.Warn("place() 1 START not ready()")
+ return false
+ }
+ log.Log(INFO, "place() 1 START ready()")
+ var tk, ptk *guiWidget
+ tk = n.TK.(*guiWidget)
+ ptk = p.TK.(*guiWidget)
+ log.Warn("SPEEDY newplace() 2 START", n.WidgetId, n.GetProgName(), n.GetLabel())
+
+ if (ptk == nil) {
+ log.Log(ERROR, "ptk == nil", p.GetProgName(), p.ParentId, p.WidgetType, ptk)
+ log.Log(ERROR, "n = ", n.GetProgName(), n.ParentId, n.WidgetType, tk)
+ log.Warn("SPEEDY ptk == nil", n.WidgetId, n.GetProgName())
+ log.Sleep(1)
+ panic("ptk == nil")
}
log.Log(INFO, "place() switch", p.WidgetType)
+ log.Warn("SPEEDY newplace() before switch", n.WidgetId, n.GetProgName())
switch p.WidgetType {
case widget.Grid:
- log.Log(INFO, "place() Grid try at Parent X,Y =", n.X, n.Y)
- n.tk.gridX = n.AtW - 1
- n.tk.gridY = n.AtH - 1
- log.Log(INFO, "place() Grid try at gridX,gridY", n.tk.gridX, n.tk.gridY)
- // at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
- p.tk.uiGrid.Append(n.tk.uiControl,
- n.tk.gridX, n.tk.gridY, 1, 1,
+ tk.gridX = n.State.GridOffset.X - 1
+ tk.gridY = n.State.GridOffset.Y - 1
+ log.Warn("place() on Grid at gridX,gridY", tk.gridX, tk.gridY)
+ ptk.uiGrid.Append(tk.uiControl,
+ tk.gridX, tk.gridY, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
return true
case widget.Group:
- if (p.tk.uiBox == nil) {
- log.Log(WARN, "place() andlabs hack group to use add a box", n.progname, n.WidgetType)
- p.tk.uiBox = n.rawBox()
- p.tk.uiGroup.SetChild(p.tk.uiBox)
+ if (ptk.uiBox == nil) {
+ log.Log(WARN, "place() andlabs hack group to use add a box", n.GetProgName(), n.WidgetType)
+ ptk.uiBox = rawBox(n)
+ ptk.uiGroup.SetChild(ptk.uiBox)
}
- p.tk.uiBox.Append(n.tk.uiControl, stretchy)
+ ptk.uiBox.Append(tk.uiControl, stretchy)
return true
case widget.Tab:
- if (p.tk.uiTab == nil) {
- log.Log(ERROR, "p.tk.uiTab == nil for n.WidgetId =", n.WidgetId, "p.tk =", p.tk)
- panic("p.tk.uiTab == nil")
+ if (ptk.uiTab == nil) {
+ log.Log(ERROR, "ptk.uiTab == nil for n.WidgetId =", n.WidgetId, "ptk =", ptk)
+ panic("ptk.uiTab == nil")
}
- if (n.tk.uiControl == nil) {
- log.Log(ERROR, "n.tk.uiControl == nil for n.WidgetId =", n.WidgetId, "n.tk =", n.tk)
- panic("n.tk.uiControl == nil")
+ if (tk.uiControl == nil) {
+ log.Log(ERROR, "tk.uiControl == nil for n.WidgetId =", n.WidgetId, "tk =", tk)
+ panic("tk.uiControl == nil")
}
log.Log(ERROR, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
- // log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.progname, n.Text, n.WidgetType)
- // log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.progname, p.Text, p.WidgetType)
- // panic("n.tk.uiControl == nil")
- p.tk.uiTab.Append(widget.GetString(n.value), n.tk.uiControl)
- p.tk.boxC += 1
+ // log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.GetProgName(), n.Text, n.WidgetType)
+ // log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.GetProgName(), p.Text, p.WidgetType)
+ // panic("tk.uiControl == nil")
+ ptk.uiTab.Append(widget.GetString(n.State.Value), tk.uiControl)
+ ptk.boxC += 1
return true
case widget.Box:
- log.Log(INFO, "place() uiBox =", p.tk.uiBox)
- log.Log(INFO, "place() uiControl =", n.tk.uiControl)
- p.tk.uiBox.Append(n.tk.uiControl, stretchy)
- p.tk.boxC += 1
+ log.Warn("SPEEDY Add Something to Box", n.WidgetId, n.GetProgName())
+ log.Log(INFO, "place() uiBox =", ptk.uiBox)
+ log.Log(INFO, "place() uiControl =", tk.uiControl)
+ ptk.uiBox.Append(tk.uiControl, stretchy)
+ ptk.boxC += 1
return true
case widget.Window:
- p.tk.uiWindow.SetChild(n.tk.uiControl)
+ log.Warn("SPEEDY Add Something to Window", n.WidgetId, n.GetProgName())
+ ptk.uiWindow.SetChild(tk.uiControl)
return true
default:
log.Log(ERROR, "place() how? Parent =", p.WidgetId, p.WidgetType)
}
+ log.Warn("SPEEDY newplace() return", n.WidgetId, n.GetProgName())
return false
}
diff --git a/andlabs/setText.go b/andlabs/setText.go
index 77beb5c..c5453db 100644
--- a/andlabs/setText.go
+++ b/andlabs/setText.go
@@ -3,15 +3,18 @@ package main
import (
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-func (n *node) setText(a *widget.Action) {
+// func (n *node) setText(a *widget.Action) {
+func setText(n *tree.Node, a *widget.Action) {
name := widget.GetString(a.Value)
+ var tk *guiWidget
+ tk = n.TK.(*guiWidget)
log.Log(CHANGE, "setText() START with text =", name)
- t := n.tk
- if (t == nil) {
- log.Log(ERROR, "setText error. tk == nil", n.progname, n.WidgetId)
+ if (tk == nil) {
+ log.Log(ERROR, "setText error. tk == nil", n.GetProgName(), n.WidgetId)
return
}
log.Log(CHANGE, "setText() Attempt on", n.WidgetType, "with", name)
@@ -19,38 +22,38 @@ func (n *node) setText(a *widget.Action) {
switch n.WidgetType {
case widget.Window:
log.Warn("setText() Attempt to set the title to", name)
- t.uiWindow.SetTitle(name)
+ tk.uiWindow.SetTitle(name)
case widget.Tab:
case widget.Group:
- t.uiGroup.SetTitle(name)
+ tk.uiGroup.SetTitle(name)
case widget.Checkbox:
- t.uiCheckbox.SetText(name)
+ tk.uiCheckbox.SetText(name)
case widget.Textbox:
- if (t.uiEntry != nil) {
- t.uiEntry.SetText(name)
+ if (tk.uiEntry != nil) {
+ tk.uiEntry.SetText(name)
}
- if (t.uiMultilineEntry != nil) {
- t.uiMultilineEntry.SetText(name)
+ if (tk.uiMultilineEntry != nil) {
+ tk.uiMultilineEntry.SetText(name)
}
case widget.Label:
- t.uiLabel.SetText(name)
+ tk.uiLabel.SetText(name)
case widget.Button:
- t.uiButton.SetText(name)
+ tk.uiButton.SetText(name)
case widget.Slider:
- log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.progname)
+ log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.GetProgName())
case widget.Spinner:
- log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.progname)
+ log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.GetProgName())
case widget.Dropdown:
var orig int
var i int = -1
var s string
- orig = t.uiCombobox.Selected()
+ orig = tk.uiCombobox.Selected()
log.Log(CHANGE, "try to set the Dropdown to", name, "from", orig)
// try to find the string
- for i, s = range t.val {
+ for i, s = range tk.val {
log.Log(CHANGE, "i, s", i, s)
if (name == s) {
- t.uiCombobox.SetSelected(i)
+ tk.uiCombobox.SetSelected(i)
log.Log(CHANGE, "setText() Dropdown worked.", name)
return
}
@@ -62,10 +65,10 @@ func (n *node) setText(a *widget.Action) {
}
// if the string was never set, then set the dropdown to the last thing added to the menu
if (orig == -1) {
- t.uiCombobox.SetSelected(i)
+ tk.uiCombobox.SetSelected(i)
}
case widget.Combobox:
- t.uiEditableCombobox.SetText(name)
+ tk.uiEditableCombobox.SetText(name)
default:
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
}
diff --git a/andlabs/slider.go b/andlabs/slider.go
index 0da06f3..5ce393a 100644
--- a/andlabs/slider.go
+++ b/andlabs/slider.go
@@ -1,22 +1,29 @@
package main
import (
+ "go.wit.com/gui/toolkits/tree"
+
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newSlider(n *node) {
+func newSlider(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- s := ui.NewSlider(n.X, n.Y)
+ var x, y int
+ x = n.State.Range.Low
+ y = n.State.Range.High
+
+ s := ui.NewSlider(x, y)
newt.uiSlider = s
newt.uiControl = s
s.OnChanged(func(spin *ui.Slider) {
- n.value = newt.uiSlider.Value()
- n.doUserEvent()
+ n.SetValue(newt.uiSlider.Value())
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/spinner.go b/andlabs/spinner.go
index 01d3b26..65bd7db 100644
--- a/andlabs/spinner.go
+++ b/andlabs/spinner.go
@@ -1,22 +1,25 @@
package main
import (
+ "go.wit.com/gui/toolkits/tree"
+
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newSpinner(n *node) {
+func newSpinner(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- s := ui.NewSpinbox(n.X, n.Y)
+ s := ui.NewSpinbox(n.State.Range.Low,n.State.Range.High)
newt.uiSpinbox = s
newt.uiControl = s
s.OnChanged(func(s *ui.Spinbox) {
- n.value = newt.uiSpinbox.Value()
- n.doUserEvent()
+ n.SetValue(newt.uiSpinbox.Value())
+ me.myTree.DoUserEvent(n)
})
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/structs.go b/andlabs/structs.go
index 87e88e1..e39cbe7 100644
--- a/andlabs/structs.go
+++ b/andlabs/structs.go
@@ -1,7 +1,11 @@
package main
-import "go.wit.com/dev/andlabs/ui"
-import _ "go.wit.com/dev/andlabs/ui/winmanifest"
+import (
+ "go.wit.com/gui/toolkits/tree"
+
+ "go.wit.com/dev/andlabs/ui"
+ _ "go.wit.com/dev/andlabs/ui/winmanifest"
+)
// var andlabs map[int]*andlabsT
// var callback func(int) bool
@@ -11,7 +15,9 @@ import _ "go.wit.com/dev/andlabs/ui/winmanifest"
var me config
type config struct {
- rootNode *node // the base of the binary tree. it should have id == 0
+ rootNode *tree.Node // the base of the binary tree. it should have id == 0
+ treeRoot *tree.Node // the base of the binary tree. it should have id == 0
+ myTree *tree.TreeInfo
}
// stores the raw toolkit internals
diff --git a/andlabs/textbox.go b/andlabs/textbox.go
index 30671cd..3748a14 100644
--- a/andlabs/textbox.go
+++ b/andlabs/textbox.go
@@ -1,21 +1,24 @@
package main
import (
+ "go.wit.com/gui/toolkits/tree"
+
"go.wit.com/dev/andlabs/ui"
_ "go.wit.com/dev/andlabs/ui/winmanifest"
)
-func (p *node) newTextbox(n *node) {
+func newTextbox(p, n *tree.Node) {
+ if notNew(n) { return }
newt := new(guiWidget)
- if (n.X == 1) {
+ if (n.State.Range.Low == 1) {
e := ui.NewEntry()
newt.uiEntry = e
newt.uiControl = e
e.OnChanged(func(spin *ui.Entry) {
- n.value = spin.Text()
- n.doUserEvent()
+ n.SetValue(spin.Text())
+ me.myTree.DoUserEvent(n)
})
} else {
e := ui.NewNonWrappingMultilineEntry()
@@ -23,10 +26,10 @@ func (p *node) newTextbox(n *node) {
newt.uiControl = e
e.OnChanged(func(spin *ui.MultilineEntry) {
- n.value = spin.Text()
- n.doUserEvent()
+ n.SetValue(spin.Text())
+ me.myTree.DoUserEvent(n)
})
}
- n.tk = newt
- p.place(n)
+ n.TK = newt
+ place(p, n)
}
diff --git a/andlabs/tree.go b/andlabs/tree.go
new file mode 100644
index 0000000..400bee4
--- /dev/null
+++ b/andlabs/tree.go
@@ -0,0 +1,31 @@
+package main
+
+/*
+ This code should be common to all gui plugins
+
+ There are some helper functions that are probably going to be
+ the same everywhere. Mostly due to handling the binary tree structure
+ and the channel communication
+
+ For now, it's just a symlink to the 'master' version in
+ ./toolkit/nocui/common.go
+*/
+
+import (
+ "go.wit.com/gui/widget"
+)
+
+// 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.)
+//
+// this sets the channel to send user events back from the plugin
+func Callback(guiCallback chan widget.Action) {
+ me.myTree.Callback(guiCallback)
+}
+
+func PluginChannel() chan widget.Action {
+ return me.myTree.PluginChannel()
+}
diff --git a/andlabs/widget.go b/andlabs/widget.go
index 414ca3d..d6d89ba 100644
--- a/andlabs/widget.go
+++ b/andlabs/widget.go
@@ -2,16 +2,16 @@ package main
import (
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-// this is specific to the nocui toolkit
-func initWidget(n *node) *guiWidget {
+func initWidget(n *tree.Node) *guiWidget {
var w *guiWidget
w = new(guiWidget)
if n.WidgetType == widget.Root {
n.WidgetId = 0
- me.rootNode = n
+ me.treeRoot = n
return w
}
return w
diff --git a/andlabs/window.go b/andlabs/window.go
index d52648e..d517f86 100644
--- a/andlabs/window.go
+++ b/andlabs/window.go
@@ -6,6 +6,7 @@ import (
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
@@ -16,23 +17,24 @@ func (t *guiWidget) ErrorWindow(msg1 string, msg2 string) {
ui.MsgBoxError(t.uiWindow, msg1, msg2)
}
-func newWindow(n *node) {
+func newWindow(p, n *tree.Node) {
var newt *guiWidget
newt = new(guiWidget)
// menubar bool is if the OS defined border on the window should be used
- win := ui.NewWindow(n.progname, n.X, n.Y, menubar)
+ win := ui.NewWindow(n.GetProgName(), 640, 480, menubar)
win.SetBorderless(canvas)
win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool {
- n.show(false)
- n.doUserEvent()
+ // show(n, false)
+ me.myTree.DoWindowCloseEvent(n)
return false
})
newt.uiWindow = win
newt.uiControl = win
- n.tk = newt
+ n.TK = newt
+ place(p, n)
win.Show()
return
}
diff --git a/common/addNode.go b/common/addNode.go
deleted file mode 100644
index be769fc..0000000
--- a/common/addNode.go
+++ /dev/null
@@ -1,68 +0,0 @@
-package main
-
-/*
- These code should be common to all gui plugins
-
- There are some helper functions that are probably going to be
- the same everywhere. Mostly due to handling the binary tree structure
- and the channel communication
-
- For now, it's just a symlink to the 'master' version in
- ./toolkit/nocui/common.go
-*/
-
-import (
- "reflect"
- "strconv"
-
- "go.wit.com/log"
- "go.wit.com/gui/widget"
-)
-
-// this is in common.go, do not move it
-func addNode(a *widget.Action) *node {
- n := new(node)
- n.WidgetType = a.WidgetType
- n.WidgetId = a.WidgetId
- n.ParentId = a.ParentId
-
- n.state = a.State
-
- // copy the data from the action message
- n.progname = a.ProgName
- n.value = a.Value
- n.direction = a.Direction
- n.strings = a.Strings
-
- // TODO: these need to be rethought
- n.X = a.X
- n.Y = a.Y
- n.W = a.W
- n.H = a.H
- n.AtW = a.AtW
- n.AtH = a.AtH
-
- // store the internal toolkit information
- n.tk = initWidget(n)
- // n.tk = new(guiWidget)
-
- if (a.WidgetType == widget.Root) {
- log.Log(INFO, "addNode() Root")
- return n
- }
-
- if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
- log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
- return me.rootNode.findWidgetId(a.WidgetId)
- }
-
- // add this new widget on the binary tree
- n.parent = me.rootNode.findWidgetId(a.ParentId)
- if n.parent != nil {
- n.parent.children = append(n.parent.children, n)
- //w := n.tk
- //w.parent = n.parent.tk
- //w.parent.children = append(w.parent.children, w)
- }
- return n
-}
diff --git a/gocui/common.go b/gocui/common.go
index 35417a1..3c67133 120000..100644
--- a/gocui/common.go
+++ b/gocui/common.go
@@ -1 +1,218 @@
-../nocui/common.go \ No newline at end of file
+package main
+
+/*
+ These code should be common to all gui plugins
+
+ There are some helper functions that are probably going to be
+ the same everywhere. Mostly due to handling the binary tree structure
+ and the channel communication
+
+ For now, it's just a symlink to the 'master' version in
+ ./toolkit/nocui/common.go
+*/
+
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/widget"
+)
+
+// this is the channel we send user events like
+// mouse clicks or keyboard events back to the program
+var callback chan widget.Action
+
+// this is the channel we get requests to make widgets
+var pluginChan chan widget.Action
+
+type node struct {
+ parent *node
+ children []*node
+
+ WidgetId int // widget ID
+ WidgetType widget.WidgetType
+ ParentId int // parent ID
+
+ state widget.State
+
+ // a reference name for programming and debuggign. Must be unique
+ progname string
+
+ // the text used for button labesl, window titles, checkbox names, etc
+ label string
+
+ // horizontal means layout widgets like books on a bookshelf
+ // vertical means layout widgets like books in a stack
+ // direction widget.Orientation
+ direction widget.Orientation
+
+ // This is how the values are passed back and forth
+ // values from things like checkboxes & dropdown's
+ value any
+
+ strings []string
+
+ // This is used for things like a slider(0,100)
+ X int
+ Y int
+
+ // This is for the grid size & widget position
+ W int
+ H int
+ AtW int
+ AtH int
+
+ vals []string // dropdown menu items
+
+ // horizontal bool `default:false`
+
+ hasTabs bool // does the window have tabs?
+ currentTab bool // the visible tab
+
+ // the internal plugin toolkit structure
+ // in the gtk plugin, it has gtk things like margin & border settings
+ // in the text console one, it has text console things like colors for menus & buttons
+ tk *guiWidget
+}
+
+// searches the binary tree for a WidgetId
+func (n *node) findWidgetId(id int) *node {
+ if (n == nil) {
+ return nil
+ }
+
+ if n.WidgetId == id {
+ return n
+ }
+
+ for _, child := range n.children {
+ newN := child.findWidgetId(id)
+ if (newN != nil) {
+ return newN
+ }
+ }
+ return nil
+}
+
+func (n *node) doUserEvent() {
+ if (callback == nil) {
+ log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
+ return
+ }
+ var a widget.Action
+ a.WidgetId = n.WidgetId
+ a.Value = n.value
+ a.ActionType = widget.User
+ log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
+ callback <- a
+ log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
+ return
+}
+
+// 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.)
+//
+// this sets the channel to send user events back from the plugin
+func Callback(guiCallback chan widget.Action) {
+ callback = guiCallback
+}
+
+func PluginChannel() chan widget.Action {
+ return pluginChan
+}
+
+/*
+func convertString(val any) string {
+ switch v := val.(type) {
+ case bool:
+ n.B = val.(bool)
+ case string:
+ n.label = val.(string)
+ n.S = val.(string)
+ case int:
+ n.I = val.(int)
+ default:
+ log.Error(errors.New("Set() unknown type"), "v =", v)
+ }
+}
+*/
+
+/*
+// this is in common.go, do not move it
+func getString(A any) string {
+ if A == nil {
+ log.Warn("getString() got nil")
+ return ""
+ }
+ var k reflect.Kind
+ k = reflect.TypeOf(A).Kind()
+
+ switch k {
+ case reflect.Int:
+ var i int
+ i = A.(int)
+ return string(i)
+ case reflect.String:
+ return A.(string)
+ case reflect.Bool:
+ if A.(bool) == true {
+ return "true"
+ } else {
+ return "false"
+ }
+ default:
+ log.Warn("getString uknown kind", k, "value =", A)
+ return ""
+ }
+ return ""
+}
+*/
+
+// this is in common.go, do not move it
+func addNode(a *widget.Action) *node {
+ n := new(node)
+ n.WidgetType = a.WidgetType
+ n.WidgetId = a.WidgetId
+ n.ParentId = a.ParentId
+
+ n.state = a.State
+
+ // copy the data from the action message
+ n.progname = a.ProgName
+ n.value = a.Value
+ n.direction = a.Direction
+ n.strings = a.Strings
+
+ // TODO: these need to be rethought
+ n.X = a.X
+ n.Y = a.Y
+ n.W = a.W
+ n.H = a.H
+ n.AtW = a.AtW
+ n.AtH = a.AtH
+
+ // store the internal toolkit information
+ n.tk = initWidget(n)
+ // n.tk = new(guiWidget)
+
+ if (a.WidgetType == widget.Root) {
+ log.Log(INFO, "addNode() Root")
+ return n
+ }
+
+ if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
+ log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
+ return me.rootNode.findWidgetId(a.WidgetId)
+ }
+
+ // add this new widget on the binary tree
+ n.parent = me.rootNode.findWidgetId(a.ParentId)
+ if n.parent != nil {
+ n.parent.children = append(n.parent.children, n)
+ //w := n.tk
+ //w.parent = n.parent.tk
+ //w.parent.children = append(w.parent.children, w)
+ }
+ return n
+}
diff --git a/gocui/plugin.go b/gocui/plugin.go
index f1834a1..3a122e3 100644
--- a/gocui/plugin.go
+++ b/gocui/plugin.go
@@ -50,7 +50,7 @@ func action(a *widget.Action) {
n.AddText(widget.GetString(a.Value))
case widget.Move:
log.Log(NOW, "attempt to move() =", a.ActionType, a.WidgetType, a.ProgName)
- case widget.CloseToolkit:
+ case widget.ToolkitClose:
log.Log(NOW, "attempting to close the plugin and release stdout and stderr")
standardExit()
case widget.Enable:
diff --git a/gocui/view.go b/gocui/view.go
index b88763c..912cf21 100644
--- a/gocui/view.go
+++ b/gocui/view.go
@@ -3,7 +3,6 @@ package main
import (
"fmt"
"errors"
- "strconv"
"bufio"
"strings"
@@ -60,7 +59,7 @@ func (n *node) showView() {
if (w.cuiName == "") {
log.Log(ERROR, "showView() w.cuiName was not set for widget", w)
- w.cuiName = strconv.Itoa(n.WidgetId)
+ w.cuiName = string(n.WidgetId)
}
// if the gocui element doesn't exist, create it
diff --git a/gocui/widget.go b/gocui/widget.go
index fba66dd..e739993 100644
--- a/gocui/widget.go
+++ b/gocui/widget.go
@@ -1,8 +1,6 @@
package main
import (
- "strconv"
-
"go.wit.com/log"
"go.wit.com/gui/widget"
)
@@ -15,7 +13,7 @@ func initWidget(n *node) *guiWidget {
w.frame = true
// set the name used by gocui to the id
- w.cuiName = strconv.Itoa(n.WidgetId)
+ w.cuiName = string(n.WidgetId)
if n.WidgetType == widget.Root {
log.Log(INFO, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
diff --git a/nocui/action.go b/nocui/action.go
index 892bd54..cf258c1 100644
--- a/nocui/action.go
+++ b/nocui/action.go
@@ -1,152 +1,87 @@
package main
+/*
+ a simple function to handle widget actions
+
+ You can tie this into your toolkit here.
+*/
+
import (
"go.wit.com/log"
"go.wit.com/gui/widget"
+ // "go.wit.com/gui/toolkits/tree"
)
-func (n *node) show(b bool) {
-}
-
-func (n *node) enable(b bool) {
-}
-
-func (n *node) pad(at widget.ActionType) {
- switch n.WidgetType {
- case widget.Group:
- switch at {
- case widget.Margin:
- // SetMargined(true)
- case widget.Unmargin:
- // SetMargined(false)
- case widget.Pad:
- // SetMargined(true)
- case widget.Unpad:
- // SetMargined(false)
- }
- case widget.Tab:
- case widget.Window:
- case widget.Grid:
- case widget.Box:
- case widget.Textbox:
- log.Log(ERROR, "TODO: implement ActionType =", at)
- default:
- log.Log(ERROR, "TODO: implement pad() for", at)
- }
-}
-
-func (n *node) move(newParent *node) {
- p := n.parent
-
- switch p.WidgetType {
- case widget.Group:
- case widget.Tab:
- // tabSetMargined(tParent.uiTab, true)
- case widget.Window:
- // t.uiWindow.SetBorderless(false)
- case widget.Grid:
- // t.uiGrid.SetPadded(true)
- case widget.Box:
- log.Log(INFO, "TODO: move() where =", p.ParentId)
- log.Log(INFO, "TODO: move() for widget =", n.WidgetId)
- default:
- log.Log(ERROR, "TODO: need to implement move() for type =", n.WidgetType)
- log.Log(ERROR, "TODO: need to implement move() for where =", p.ParentId)
- log.Log(ERROR, "TODO: need to implement move() for widget =", n.WidgetId)
- }
-}
-
-func (n *node) Delete() {
- p := n.parent
- log.Log(NOW, "uiDelete()", n.WidgetId, "to", p.WidgetId)
-
- switch p.WidgetType {
- case widget.Group:
- // tParent.uiGroup.SetMargined(true)
- case widget.Tab:
- // tabSetMargined(tParent.uiTab, true)
- case widget.Window:
- // t.uiWindow.SetBorderless(false)
- case widget.Grid:
- // t.uiGrid.SetPadded(true)
- case widget.Box:
- log.Log(NOW, "tWidget.boxC =", p.progname)
- log.Log(NOW, "is there a tParent parent? =", p.parent)
- // this didn't work:
- // tWidget.uiControl.Disable()
- // sleep(.8)
- // tParent.uiBox.Append(tWidget.uiControl, stretchy)
- default:
- log.Log(ERROR, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
- log.Log(ERROR, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
- }
-}
-
-func doAction(a *widget.Action) {
+func doAction(a widget.Action) {
log.Log(INFO, "doAction() START a.ActionType =", a.ActionType)
log.Log(INFO, "doAction() START a.ProgName =", a.ProgName)
- if (a.ActionType == widget.InitToolkit) {
- // TODO: make sure to only do this once
- // go uiMain.Do(func() {
- // ui.Main(demoUI)
- // go catchActionChannel()
- // })
- // try doing this on toolkit load in init()
+ if (a.ActionType == widget.ToolkitInit) {
return
}
log.Log(INFO, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
switch a.WidgetType {
case widget.Root:
- me.rootNode = addNode(a)
- log.Log(INFO, "doAction() found rootNode")
+ me.treeRoot = me.myTree.AddNode(&a)
+ log.Log(INFO, "doAction() found treeRoot")
return
- case widget.Flag:
- // flag(&a)
+ }
+
+ switch a.ActionType {
+ case widget.Add:
+ me.myTree.AddNode(&a)
return
}
- n := me.rootNode.findWidgetId(a.WidgetId)
+ n := me.treeRoot.FindWidgetId(a.WidgetId)
+ if n == nil {
+ log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
+ log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
+ log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
+ log.Warn("Aaaaa!, return")
+ return
+ }
switch a.ActionType {
- case widget.Add:
- addNode(a)
case widget.Show:
- n.show(true)
+ n.State.Visable = true
case widget.Hide:
- n.show(false)
+ n.State.Visable = false
case widget.Enable:
- n.enable(true)
+ n.State.Visable = true
case widget.Disable:
- n.enable(false)
+ n.State.Visable = false
case widget.Get:
- // n.setText(a.S)
+ log.Warn("value =", n.State.Value)
case widget.GetText:
- switch a.WidgetType {
- case widget.Textbox:
- a.Value = n.value
- }
+ log.Warn("value =", n.String())
case widget.Set:
- // n.setText(a.S)
+ n.State.Value = a.State.Value
case widget.SetText:
- // n.setText(a.S)
+ log.Warn("GOT TO SetText()", a.WidgetId)
+ log.Warn("GOT TO SetText()", a.WidgetId)
+ log.Warn("GOT TO SetText()", a.WidgetId)
+ log.Warn("GOT TO SetText()", a.WidgetId)
+ if n == nil {
+ log.Warn("HOT DIGGITY. n == nil")
+ }
+ n.State.Value = a.State.Value
case widget.AddText:
- // n.setText(a.S)
+ n.State.Strings = append(a.State.Strings, widget.GetString(a.State.Value))
case widget.Margin:
- n.pad(widget.Unmargin)
+ n.State.Pad = true
case widget.Unmargin:
- n.pad(widget.Margin)
+ n.State.Pad = false
case widget.Pad:
- n.pad(widget.Pad)
+ n.State.Pad = true
case widget.Unpad:
- n.pad(widget.Unpad)
+ n.State.Pad = false
case widget.Delete:
- n.Delete()
+ log.Warn("doAction() TODO: Delete()")
+ // n.Delete()
case widget.Move:
- log.Log(INFO, "doAction() attempt to move() =", a.ActionType, a.WidgetType)
- newParent := me.rootNode.findWidgetId(a.ParentId)
- n.move(newParent)
+ log.Warn("doAction() TODO: Move()")
default:
log.Log(ERROR, "doAction() Unknown =", a.ActionType, a.WidgetType)
}
diff --git a/nocui/common.go b/nocui/common.go
deleted file mode 100644
index 7b79ca0..0000000
--- a/nocui/common.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package main
-
-/*
- These code should be common to all gui plugins
-
- There are some helper functions that are probably going to be
- the same everywhere. Mostly due to handling the binary tree structure
- and the channel communication
-
- For now, it's just a symlink to the 'master' version in
- ./toolkit/nocui/common.go
-*/
-
-import (
- "go.wit.com/log"
- "go.wit.com/gui/widget"
-)
-
-// this is the channel we send user events like
-// mouse clicks or keyboard events back to the program
-var callback chan widget.Action
-
-// this is the channel we get requests to make widgets
-var pluginChan chan widget.Action
-
-type node struct {
- parent *node
- children []*node
-
- WidgetId int // widget ID
- WidgetType widget.WidgetType
- ParentId int // parent ID
-
- state widget.State
-
- // a reference name for programming and debuggign. Must be unique
- progname string
-
- // the text used for button labesl, window titles, checkbox names, etc
- label string
-
- // horizontal means layout widgets like books on a bookshelf
- // vertical means layout widgets like books in a stack
- // direction widget.Orientation
- direction widget.Orientation
-
- // This is how the values are passed back and forth
- // values from things like checkboxes & dropdown's
- value any
-
- strings []string
-
- // This is used for things like a slider(0,100)
- X int
- Y int
-
- // This is for the grid size & widget position
- W int
- H int
- AtW int
- AtH int
-
- vals []string // dropdown menu items
-
- // horizontal bool `default:false`
-
- hasTabs bool // does the window have tabs?
- currentTab bool // the visible tab
-
- // the internal plugin toolkit structure
- // in the gtk plugin, it has gtk things like margin & border settings
- // in the text console one, it has text console things like colors for menus & buttons
- tk *guiWidget
-}
-
-// searches the binary tree for a WidgetId
-func (n *node) findWidgetId(id int) *node {
- if (n == nil) {
- return nil
- }
-
- if n.WidgetId == id {
- return n
- }
-
- for _, child := range n.children {
- newN := child.findWidgetId(id)
- if (newN != nil) {
- return newN
- }
- }
- return nil
-}
-
-func (n *node) doUserEvent() {
- if (callback == nil) {
- log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
- return
- }
- var a widget.Action
- a.WidgetId = n.WidgetId
- a.Value = n.value
- a.ActionType = widget.User
- log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
- callback <- a
- log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
- return
-}
-
-// 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.)
-//
-// this sets the channel to send user events back from the plugin
-func Callback(guiCallback chan widget.Action) {
- callback = guiCallback
-}
-
-func PluginChannel() chan widget.Action {
- return pluginChan
-}
-
-/*
-func convertString(val any) string {
- switch v := val.(type) {
- case bool:
- n.B = val.(bool)
- case string:
- n.label = val.(string)
- n.S = val.(string)
- case int:
- n.I = val.(int)
- default:
- log.Error(errors.New("Set() unknown type"), "v =", v)
- }
-}
-*/
-
-/*
-// this is in common.go, do not move it
-func getString(A any) string {
- if A == nil {
- log.Warn("getString() got nil")
- return ""
- }
- var k reflect.Kind
- k = reflect.TypeOf(A).Kind()
-
- switch k {
- case reflect.Int:
- var i int
- i = A.(int)
- return strconv.Itoa(i)
- case reflect.String:
- return A.(string)
- case reflect.Bool:
- if A.(bool) == true {
- return "true"
- } else {
- return "false"
- }
- default:
- log.Warn("getString uknown kind", k, "value =", A)
- return ""
- }
- return ""
-}
-*/
-
-// this is in common.go, do not move it
-func addNode(a *widget.Action) *node {
- n := new(node)
- n.WidgetType = a.WidgetType
- n.WidgetId = a.WidgetId
- n.ParentId = a.ParentId
-
- n.state = a.State
-
- // copy the data from the action message
- n.progname = a.ProgName
- n.value = a.Value
- n.direction = a.Direction
- n.strings = a.Strings
-
- // TODO: these need to be rethought
- n.X = a.X
- n.Y = a.Y
- n.W = a.W
- n.H = a.H
- n.AtW = a.AtW
- n.AtH = a.AtH
-
- // store the internal toolkit information
- n.tk = initWidget(n)
- // n.tk = new(guiWidget)
-
- if (a.WidgetType == widget.Root) {
- log.Log(INFO, "addNode() Root")
- return n
- }
-
- if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
- log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
- return me.rootNode.findWidgetId(a.WidgetId)
- }
-
- // add this new widget on the binary tree
- n.parent = me.rootNode.findWidgetId(a.ParentId)
- if n.parent != nil {
- n.parent.children = append(n.parent.children, n)
- //w := n.tk
- //w.parent = n.parent.tk
- //w.parent.children = append(w.parent.children, w)
- }
- return n
-}
diff --git a/nocui/event.go b/nocui/event.go
index 97f2aed..9bbafdb 100644
--- a/nocui/event.go
+++ b/nocui/event.go
@@ -1,11 +1,13 @@
package main
+/*
import (
"go.wit.com/log"
"go.wit.com/gui/widget"
+ "go.wit.com/gui/toolkits/tree"
)
-func (n *node) doWidgetClick() {
+func doWidgetClick(n *tree.Node) {
switch n.WidgetType {
case widget.Root:
// THIS IS THE BEGINING OF THE LAYOUT
@@ -17,32 +19,33 @@ func (n *node) doWidgetClick() {
// rootNode.dumpTree(true)
case widget.Window:
// setCurrentWindow(w)
- n.doUserEvent()
+ // n.doUserEvent()
case widget.Tab:
// setCurrentTab(w)
case widget.Group:
// n.placeWidgets()
// n.toggleTree()
case widget.Checkbox:
- if widget.GetBool(n.value) {
+ if n.Bool() {
// n.setCheckbox(false)
} else {
// n.setCheckbox(true)
}
- n.doUserEvent()
+ // n.doUserEvent()
case widget.Grid:
// rootNode.hideWidgets()
// n.placeGrid()
// n.showWidgets()
case widget.Box:
// n.showWidgetPlacement(logNow, "drawTree()")
- if widget.GetBool(n.value) {
- log.Log(NOW, "BOX IS HORIZONTAL", n.progname)
+ if n.Bool() {
+ log.Log(NOW, "BOX IS HORIZONTAL", n.GetProgName())
} else {
- log.Log(NOW, "BOX IS VERTICAL", n.progname)
+ log.Log(NOW, "BOX IS VERTICAL", n.GetProgName())
}
case widget.Button:
- n.doUserEvent()
+ // n.doUserEvent()
default:
}
}
+*/
diff --git a/nocui/go.mod b/nocui/go.mod
index ec42260..e802e10 100644
--- a/nocui/go.mod
+++ b/nocui/go.mod
@@ -1,10 +1,3 @@
module go.wit.com/gui/toolkits/nocui
go 1.21.4
-
-require (
- go.wit.com/gui/widget v1.1.3
- go.wit.com/log v0.5.4
-)
-
-require go.wit.com/dev/davecgh/spew v1.1.4 // indirect
diff --git a/nocui/go.sum b/nocui/go.sum
deleted file mode 100644
index 3af9a6c..0000000
--- a/nocui/go.sum
+++ /dev/null
@@ -1,10 +0,0 @@
-go.wit.com/dev/davecgh/spew v1.1.3 h1:hqnB5qsPgC2cLZaJXqQJspQ5n/Ugry9kyL3tLk0hVzQ=
-go.wit.com/dev/davecgh/spew v1.1.3/go.mod h1:sihvWmnQ/09FWplnEmozt90CCVqBtGuPXM811tgfhFA=
-go.wit.com/dev/davecgh/spew v1.1.4 h1:C9hj/rjlUpdK+E6aroyLjCbS5MFcyNUOuP1ICLWdNek=
-go.wit.com/dev/davecgh/spew v1.1.4/go.mod h1:sihvWmnQ/09FWplnEmozt90CCVqBtGuPXM811tgfhFA=
-go.wit.com/gui/widget v1.1.3 h1:GvLzGSOF9tfmoh6HNbFdN+NSlBo2qeS/Ba2TnQQ1A1U=
-go.wit.com/gui/widget v1.1.3/go.mod h1:A6/FaiFQtAHTjgo7c4FrokXe6bXX1Cowo35b2Lgi31E=
-go.wit.com/log v0.5.3 h1:/zHkniOPusPEuX1R401rMny9uwSO/nSU/QOMx6qoEnE=
-go.wit.com/log v0.5.3/go.mod h1:LzIzVxc2xJQxWQBtV9VbV605P4TOxmYDCl+BZF38yGE=
-go.wit.com/log v0.5.4 h1:vijLRPTUgChb8J5tx/7Uma/lGTUxeSXosFbheAmL914=
-go.wit.com/log v0.5.4/go.mod h1:BaJBfHFqcJSJLXGQ9RHi3XVhPgsStxSMZRlaRxW4kAo=
diff --git a/nocui/main.go b/nocui/main.go
index f6cfb3b..ebf3fae 100644
--- a/nocui/main.go
+++ b/nocui/main.go
@@ -1,55 +1,24 @@
package main
-import (
- "sync"
- "go.wit.com/log"
- "go.wit.com/gui/widget"
-)
-
-var muAction sync.Mutex
-
-func catchActionChannel() {
- log.Log(NOW, "catchActionChannel() START")
- for {
- log.Log(NOW, "catchActionChannel() for loop")
- select {
- case a := <-pluginChan:
- log.Log(NOW, "catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
- log.Log(NOW, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
- muAction.Lock()
- doAction(&a)
- muAction.Unlock()
- log.Log(NOW, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
- }
- }
-}
-
/*
-// 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.)
-//
-// this sets the channel to send user events back from the plugin
-func Callback(guiCallback chan widget.Action) {
- callback = guiCallback
-}
+ This is reference code for toolkit developers
-func PluginChannel() chan widget.Action {
- return pluginChan
-}
+ The 'nocui' is a bare minimum toolkit. It's all you need
+ to interact with the GUI
*/
-// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/toolkits/tree"
+)
+
func init() {
log.Log(INFO, "Init()")
- // andlabs = make(map[int]*andlabsT)
- pluginChan = make(chan widget.Action, 1)
+ me.myTree = tree.New()
+ me.myTree.PluginName = "nocui"
+ me.myTree.ActionFromChannel = doAction
- log.Log(NOW, "Init() start channel reciever")
- go catchActionChannel()
go simpleStdin()
- log.Log(NOW, "Init() END")
+ log.Log(INFO, "Init() END")
}
diff --git a/nocui/stdin.go b/nocui/stdin.go
index f7469c6..f003ee4 100644
--- a/nocui/stdin.go
+++ b/nocui/stdin.go
@@ -4,6 +4,7 @@ import (
"os"
"fmt"
"bufio"
+ "runtime/debug"
"strings"
"strconv"
@@ -12,6 +13,15 @@ import (
)
func simpleStdin() {
+ defer func() {
+ if r := recover(); r != nil {
+ log.Warn("nocui YAHOOOO Recovered in simpleStdin()", r)
+ log.Println("Recovered from panic:", r)
+ log.Println("Stack trace:")
+ debug.PrintStack()
+ me.myTree.DoToolkitPanic()
+ }
+ }()
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
s := scanner.Text()
@@ -19,63 +29,46 @@ func simpleStdin() {
switch s {
case "l":
log.Log(NOW, "list widgets")
- me.rootNode.listWidgets()
+ me.treeRoot.ListWidgets()
case "b":
log.Log(NOW, "show buttons")
- me.rootNode.showButtons()
+ me.treeRoot.ShowButtons()
+ case "g":
+ me.myTree.DoToolkitLoad("gocui")
+ case "a":
+ me.myTree.DoToolkitLoad("andlabs")
case "d":
- var a widget.Action
- a.ActionType = widget.EnableDebug
- callback <- a
+ me.myTree.DoEnableDebugger()
case "":
fmt.Println("")
fmt.Println("Enter:")
fmt.Println("'l': list all widgets")
fmt.Println("'b': for buttons")
+ fmt.Println("'g': load gocui plugin")
+ fmt.Println("'a': load andlabs plugin")
fmt.Println("'d': enable debugging")
default:
i, _ := strconv.Atoi(s)
log.Log(NOW, "got input:", i)
- n := me.rootNode.findWidgetId(i)
+ n := me.treeRoot.FindWidgetId(i)
if (n != nil) {
- n.dumpWidget("found node")
- n.doUserEvent()
+ n.DumpWidget("found node")
+ for i, s := range n.State.Strings {
+ log.Warn("n.State.Strings =", i, s)
+ }
+ switch n.WidgetType {
+ case widget.Root:
+ log.Warn("this is the root widget")
+ case widget.Dropdown:
+ log.Warn("print out dropdown values here")
+ case widget.Button:
+ me.myTree.DoUserEvent(n)
+ case widget.Checkbox:
+ me.myTree.DoUserEvent(n)
+ default:
+ log.Warn("you haven't defined an event for", n.WidgetType)
+ }
}
}
}
}
-
-func (n *node) showButtons() {
- if n.WidgetType == widget.Button {
- n.dumpWidget("Button:")
- }
-
- for _, child := range n.children {
- child.showButtons()
- }
-}
-
-func (n *node) dumpWidget(pad string) {
- log.Log(NOW, "node:", pad, n.WidgetId, ",", n.WidgetType, ",", n.progname)
-}
-
-var depth int = 0
-
-func (n *node) listWidgets() {
- if (n == nil) {
- return
- }
-
- var pad string
- for i := 0; i < depth; i++ {
- pad = pad + " "
- }
- n.dumpWidget(pad)
-
- for _, child := range n.children {
- depth += 1
- child.listWidgets()
- depth -= 1
- }
- return
-}
diff --git a/nocui/structs.go b/nocui/structs.go
index 888bcb5..c8a7cb4 100644
--- a/nocui/structs.go
+++ b/nocui/structs.go
@@ -1,17 +1,22 @@
package main
+import (
+ "go.wit.com/gui/toolkits/tree"
+)
+
// stores the raw toolkit internals
type guiWidget struct {
Width int
Height int
c int
- val map[int]string
+ val map[string]int
}
// It's probably a terrible idea to call this 'me'
var me config
type config struct {
- rootNode *node // the base of the binary tree. it should have id == 0
+ treeRoot *tree.Node // the base of the binary tree. it should have id == 0
+ myTree *tree.TreeInfo
}
diff --git a/nocui/tree.go b/nocui/tree.go
new file mode 100644
index 0000000..784e923
--- /dev/null
+++ b/nocui/tree.go
@@ -0,0 +1,24 @@
+package main
+
+/*
+ This is reference code for toolkit developers
+*/
+
+import (
+ "go.wit.com/gui/widget"
+)
+
+// 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.)
+//
+// this sets the channel to send user events back from the plugin
+func Callback(guiCallback chan widget.Action) {
+ me.myTree.Callback(guiCallback)
+}
+
+func PluginChannel() chan widget.Action {
+ return me.myTree.PluginChannel()
+}
diff --git a/nocui/widget.go b/nocui/widget.go
deleted file mode 100644
index 6e50705..0000000
--- a/nocui/widget.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package main
-
-import (
- "go.wit.com/log"
- "go.wit.com/gui/widget"
-)
-
-// this is specific to the nocui toolkit
-func initWidget(n *node) *guiWidget {
- var w *guiWidget
- w = new(guiWidget)
- // Set(w, "default")
-
- if n.WidgetType == widget.Root {
- log.Log(INFO, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
- n.WidgetId = 0
- me.rootNode = n
- return w
- }
-
- if (n.WidgetType == widget.Box) {
- if (n.direction == widget.Horizontal) {
- // n.horizontal = true
- } else {
- // n.horizontal = false
- }
- }
-
- return w
-}
diff --git a/tree/addNode.go b/tree/addNode.go
new file mode 100644
index 0000000..8c0a789
--- /dev/null
+++ b/tree/addNode.go
@@ -0,0 +1,47 @@
+package tree
+
+import (
+ "errors"
+
+ "go.wit.com/log"
+ "go.wit.com/gui/widget"
+)
+
+// this is in common.go, do not move it
+func (me *TreeInfo) AddNode(a *widget.Action) *Node {
+ n := new(Node)
+ n.WidgetType = a.WidgetType
+ n.WidgetId = a.WidgetId
+ n.ParentId = a.ParentId
+
+ n.State = a.State
+ n.Strings = make(map[string]int)
+
+ if (a.WidgetType == widget.Root) {
+ log.Info("AddNode() Root")
+ n.Parent = n
+ me.treeRoot = n
+ return n
+ }
+
+ if (me.treeRoot.FindWidgetId(a.WidgetId) != nil) {
+ log.Warn("AddNode() WidgetId already exists", a.WidgetId)
+ log.Warn("probably this is a Show() / Hide() issue")
+ log.Warn("TODO: figure out what to do here")
+ return me.treeRoot.FindWidgetId(a.WidgetId)
+ }
+
+ // add this new widget on the binary tree
+ p := me.treeRoot.FindWidgetId(a.ParentId)
+ n.Parent = p
+ if n.Parent == nil {
+ log.Error(errors.New("tree.AddNode() ERROR n.Parent == nil"), a.WidgetId, a.ParentId, a.ActionType)
+ log.Warn("AddNode() ERROR n.Parent == nil", a.WidgetId, a.ParentId, a.ActionType)
+ log.Warn("AddNode() ERROR n.Parent == nil", a.WidgetId, a.ParentId, a.WidgetType)
+ return n
+ }
+ log.Warn("AddNode() Adding to parent =", p.ParentId, p.WidgetType, p.GetProgName())
+ log.Warn("AddNode() Adding child =", n.ParentId, n.WidgetType, n.GetProgName())
+ p.children = append(p.children, n)
+ return n
+}
diff --git a/tree/common.go b/tree/common.go
new file mode 100644
index 0000000..24992de
--- /dev/null
+++ b/tree/common.go
@@ -0,0 +1,35 @@
+package tree
+
+import (
+ "go.wit.com/gui/widget"
+)
+
+func (n *Node) GetProgName() string {
+ return n.State.ProgName
+}
+
+func (n *Node) GetValue() any {
+ return n.State.Value
+}
+
+func (n *Node) Bool() bool {
+ return widget.GetBool(n.State.Value)
+}
+
+func (n *Node) String() string {
+ return widget.GetString(n.State.Value)
+}
+
+/* avoid this function name as confusing
+func (n *Node) GetText() string {
+ return widget.GetString(n.State.Value)
+}
+*/
+
+func (n *Node) SetValue(a any) {
+ n.State.Value = a
+}
+
+func (n *Node) GetLabel() string {
+ return n.State.Label
+}
diff --git a/tree/debug.go b/tree/debug.go
new file mode 100644
index 0000000..c79f35b
--- /dev/null
+++ b/tree/debug.go
@@ -0,0 +1,44 @@
+package tree
+
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/widget"
+)
+
+func (n *Node) ShowButtons() {
+ if n.WidgetType == widget.Button {
+ n.DumpWidget("Button:")
+ }
+
+ for _, child := range n.children {
+ child.ShowButtons()
+ }
+}
+
+func (n *Node) DumpWidget(pad string) {
+ log.Warn("node:", pad, n.WidgetId, ",", n.WidgetType, ",", n.GetProgName())
+}
+
+var depth int = 0
+
+func (n *Node) ListWidgets() {
+ if (n == nil) {
+ log.Warn("ERRRORRRR: n == nil in ListWidgets()")
+ log.Warn("ERRRORRRR: n == nil in ListWidgets()")
+ log.Warn("ERRRORRRR: n == nil in ListWidgets()")
+ return
+ }
+
+ var pad string
+ for i := 0; i < depth; i++ {
+ pad = pad + " "
+ }
+ n.DumpWidget(pad)
+
+ for _, child := range n.children {
+ depth += 1
+ child.ListWidgets()
+ depth -= 1
+ }
+ return
+}
diff --git a/tree/event.go b/tree/event.go
new file mode 100644
index 0000000..ee74138
--- /dev/null
+++ b/tree/event.go
@@ -0,0 +1,88 @@
+package tree
+
+/*
+ These code should be common to all gui plugins
+
+ There are some helper functions that are probably going to be
+ the same everywhere. Mostly due to handling the binary tree structure
+ and the channel communication
+
+ For now, it's just a symlink to the 'master' version in
+ ./toolkit/nocui/common.go
+*/
+
+import (
+ "go.wit.com/log"
+ "go.wit.com/gui/widget"
+)
+
+func (me *TreeInfo) DoEnableDebugger() {
+ if (me.callback == nil) {
+ log.Warn("DoUserEvent() toolkit panic() callback == nil")
+ return
+ }
+ var a widget.Action
+ a.ActionType = widget.EnableDebug
+ a.ProgName = me.PluginName
+ me.callback <- a
+ return
+}
+
+func (me *TreeInfo) DoToolkitLoad(s string) {
+ if (me.callback == nil) {
+ log.Warn("DoUserEvent() toolkit load callback == nil")
+ return
+ }
+ var a widget.Action
+ a.ActionType = widget.ToolkitLoad
+ a.ProgName = me.PluginName
+ a.Value = s
+ log.Warn("DoUserEvent() START: toolkit load", s)
+ me.callback <- a
+ log.Warn("DoUserEvent() END: toolkit load", s)
+ return
+}
+
+func (me *TreeInfo) DoToolkitPanic() {
+ if (me.callback == nil) {
+ log.Warn("DoUserEvent() toolkit panic() callback == nil")
+ return
+ }
+ var a widget.Action
+ a.ActionType = widget.ToolkitPanic
+ a.ProgName = me.PluginName
+ log.Info("DoUserEvent() START: toolkit panic()")
+ me.callback <- a
+ log.Info("DoUserEvent() END: toolkit panic()")
+ return
+}
+
+func (me *TreeInfo) DoWindowCloseEvent(n *Node) {
+ if (me.callback == nil) {
+ log.Warn("DoUserEvent() callback == nil", n.WidgetId)
+ return
+ }
+ var a widget.Action
+ a.WidgetId = n.WidgetId
+ a.ActionType = widget.CloseWindow
+ log.Info("DoUserEvent() START: user closed the window", n.GetProgName())
+ me.callback <- a
+ log.Info("DoUserEvent() END: user closed the window", n.GetProgName())
+ return
+}
+
+// Other goroutines must use this to access the GUI
+func (me *TreeInfo) DoUserEvent(n *Node) {
+ if (me.callback == nil) {
+ log.Warn("DoUserEvent() callback == nil", n.WidgetId)
+ return
+ }
+ var a widget.Action
+ a.WidgetId = n.WidgetId
+ a.Value = n.State.Value
+ a.ActionType = widget.User
+ log.Info("DoUserEvent() START: send a user event to the callback channel")
+ me.callback <- a
+ log.Info("DoUserEvent() END: sent a user event to the callback channel")
+ return
+}
diff --git a/tree/init.go b/tree/init.go
new file mode 100644
index 0000000..cdbd62a
--- /dev/null
+++ b/tree/init.go
@@ -0,0 +1,58 @@
+package tree
+
+import (
+ "sync"
+ "errors"
+
+ "go.wit.com/log"
+ "go.wit.com/gui/widget"
+)
+
+var muAction sync.Mutex
+
+func (me *TreeInfo) toolkit(a widget.Action) {
+ if me.ActionFromChannel == nil {
+ log.Error(errors.New("toolkit ActionFromChannel == nil"), a.WidgetId, a.ActionType, a.WidgetType)
+ return
+ }
+ me.ActionFromChannel(a)
+}
+
+func (me *TreeInfo) catchActionChannel() {
+ defer func() {
+ if r := recover(); r != nil {
+ log.Warn("nocui YAHOOOO Recovered in simpleStdin()", r)
+ me.DoToolkitPanic()
+ panic(-1)
+ }
+ }()
+ log.Info("catchActionChannel() START")
+ for {
+ log.Info("catchActionChannel() for loop")
+ select {
+ case a := <-me.pluginChan:
+ log.Info("catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
+ log.Warn("catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
+ if a.WidgetType == widget.Dropdown {
+ log.Warn("Found dropdown", a.WidgetId, a.ActionType, a.WidgetType)
+ for i, s := range a.State.Strings {
+ log.Warn("a.State.Strings =", i, s)
+ }
+ }
+ muAction.Lock()
+ me.toolkit(a)
+ muAction.Unlock()
+ log.Info("catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
+ }
+ }
+}
+
+func New() *TreeInfo {
+ me := new(TreeInfo)
+ me.pluginChan = make(chan widget.Action, 1)
+
+ log.Info("Init() start channel reciever")
+ go me.catchActionChannel()
+ log.Info("Init() END")
+ return me
+}
diff --git a/common/plugin.go b/tree/plugin.go
index bfc9a68..d7468e4 100644
--- a/common/plugin.go
+++ b/tree/plugin.go
@@ -1,4 +1,4 @@
-package main
+package tree
/*
These code should be common to all gui plugins
@@ -12,15 +12,11 @@ package main
*/
import (
- "reflect"
- "strconv"
-
- "go.wit.com/log"
"go.wit.com/gui/widget"
)
// searches the binary tree for a WidgetId
-func (n *node) findWidgetId(id int) *node {
+func (n *Node) FindWidgetId(id int) *Node {
if (n == nil) {
return nil
}
@@ -30,7 +26,7 @@ func (n *node) findWidgetId(id int) *node {
}
for _, child := range n.children {
- newN := child.findWidgetId(id)
+ newN := child.FindWidgetId(id)
if (newN != nil) {
return newN
}
@@ -38,21 +34,6 @@ func (n *node) findWidgetId(id int) *node {
return nil
}
-func (n *node) doUserEvent() {
- if (callback == nil) {
- log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
- return
- }
- var a widget.Action
- a.WidgetId = n.WidgetId
- a.Value = n.value
- a.ActionType = widget.User
- log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
- callback <- a
- log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
- return
-}
-
// Other goroutines must use this to access the GUI
//
// You can not acess / process the GUI thread directly from
@@ -60,10 +41,10 @@ func (n *node) doUserEvent() {
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
//
// this sets the channel to send user events back from the plugin
-func Callback(guiCallback chan widget.Action) {
- callback = guiCallback
+func (me *TreeInfo) Callback(guiCallback chan widget.Action) {
+ me.callback = guiCallback
}
-func PluginChannel() chan widget.Action {
- return pluginChan
+func (me *TreeInfo) PluginChannel() chan widget.Action {
+ return me.pluginChan
}
diff --git a/common/structs.go b/tree/structs.go
index 32eed8a..e998b6f 100644
--- a/common/structs.go
+++ b/tree/structs.go
@@ -1,4 +1,4 @@
-package main
+package tree
/*
These code should be common to all gui plugins
@@ -12,23 +12,29 @@ package main
*/
import (
- "reflect"
- "strconv"
-
- "go.wit.com/log"
+ // "go.wit.com/log"
"go.wit.com/gui/widget"
)
-// this is the channel we send user events like
-// mouse clicks or keyboard events back to the program
-var callback chan widget.Action
+// var me *TreeInfo
+
+type TreeInfo struct {
+ // this is the channel we send user events like
+ // mouse clicks or keyboard events back to the program
+ callback chan widget.Action
-// this is the channel we get requests to make widgets
-var pluginChan chan widget.Action
+ // this is the channel we get requests to make widgets
+ pluginChan chan widget.Action
+
+ treeRoot *Node
+ NodeI interface {}
+ ActionFromChannel func (widget.Action) ()
+ PluginName string
+}
type Node struct {
- parent *node
- children []*node
+ Parent *Node
+ children []*Node
WidgetId int // widget ID
WidgetType widget.WidgetType
@@ -36,6 +42,8 @@ type Node struct {
State widget.State
+ Strings map[string]int
+
// the internal plugin toolkit structure
// in the gtk plugin, it has gtk things like margin & border settings
// in the text console one, it has text console things like colors for menus & buttons