summaryrefslogtreecommitdiff
path: root/tree
diff options
context:
space:
mode:
Diffstat (limited to 'tree')
-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.go50
-rw-r--r--tree/structs.go51
7 files changed, 373 insertions, 0 deletions
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/tree/plugin.go b/tree/plugin.go
new file mode 100644
index 0000000..d7468e4
--- /dev/null
+++ b/tree/plugin.go
@@ -0,0 +1,50 @@
+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/gui/widget"
+)
+
+// 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
+}
+
+// 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 (me *TreeInfo) Callback(guiCallback chan widget.Action) {
+ me.callback = guiCallback
+}
+
+func (me *TreeInfo) PluginChannel() chan widget.Action {
+ return me.pluginChan
+}
diff --git a/tree/structs.go b/tree/structs.go
new file mode 100644
index 0000000..e998b6f
--- /dev/null
+++ b/tree/structs.go
@@ -0,0 +1,51 @@
+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"
+)
+
+// 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
+ pluginChan chan widget.Action
+
+ treeRoot *Node
+ NodeI interface {}
+ ActionFromChannel func (widget.Action) ()
+ PluginName string
+}
+
+type Node struct {
+ Parent *Node
+ children []*Node
+
+ WidgetId int // widget ID
+ WidgetType widget.WidgetType
+ ParentId int // parent ID
+
+ 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
+ TK any
+}