initial commit

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-01-18 00:05:54 -06:00
commit 3ea3dd10db
11 changed files with 453 additions and 0 deletions

4
Makefile Normal file
View File

@ -0,0 +1,4 @@
redomod:
rm -f go.*
GO111MODULE= go mod init
GO111MODULE= go mod tidy

47
addNode.go Normal file
View File

@ -0,0 +1,47 @@
package tree
import (
"errors"
"go.wit.com/log"
"go.wit.com/lib/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
}

35
common.go Normal file
View File

@ -0,0 +1,35 @@
package tree
import (
"go.wit.com/lib/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
}

44
debug.go Normal file
View File

@ -0,0 +1,44 @@
package tree
import (
"go.wit.com/log"
"go.wit.com/lib/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
}

88
event.go Normal file
View File

@ -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/lib/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
}

10
go.mod Normal file
View File

@ -0,0 +1,10 @@
module go.wit.com/toolkits/tree
go 1.21.4
require (
go.wit.com/gui/widget v1.1.4
go.wit.com/log v0.5.5
)
require go.wit.com/dev/davecgh/spew v1.1.4 // indirect

6
go.sum Normal file
View File

@ -0,0 +1,6 @@
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.4 h1:dCztWNSuTSSP+/M8h8F3cT7vWtoKdCL3DUQql0qLKdk=
go.wit.com/gui/widget v1.1.4/go.mod h1:A6/FaiFQtAHTjgo7c4FrokXe6bXX1Cowo35b2Lgi31E=
go.wit.com/log v0.5.5 h1:bK3b94uVKgev4jB5wg06FnvCFBEapQICTSH2YW+CWr4=
go.wit.com/log v0.5.5/go.mod h1:BaJBfHFqcJSJLXGQ9RHi3XVhPgsStxSMZRlaRxW4kAo=

58
init.go Normal file
View File

@ -0,0 +1,58 @@
package tree
import (
"sync"
"errors"
"go.wit.com/log"
"go.wit.com/lib/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
}

60
json.go Normal file
View File

@ -0,0 +1,60 @@
package tree
import (
"fmt"
"go.wit.com/log"
"go.wit.com/lib/widget"
)
// makes a JSON version to pass to the toolkits ?
// probably this should be in gui/toolkits/tree
/*
{"widget": {
"debug": "on",
"window": {
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
},
"image": {
"src": "Images/Sun.png",
"name": "sun1",
"hOffset": 250,
"vOffset": 250,
"alignment": "center"
},
"text": {
"data": "Click Here",
"size": 36,
"style": "bold",
"name": "text1",
"hOffset": 250,
"vOffset": 100,
"alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
}
}}
*/
func (n *Node) Json() []string {
var all []string
switch n.WidgetType {
case widget.Checkbox:
case widget.Button:
case widget.Combobox:
case widget.Dropdown:
case widget.Textbox:
case widget.Spinner:
case widget.Slider:
case widget.Window:
tmp := fmt.Sprint("{ WidgetType :", n.WidgetType, "}")
all = append(all, tmp)
log.Warn(tmp)
return all
default:
log.Info("doUserEvent() type =", n.WidgetType)
}
return all
}

50
plugin.go Normal file
View File

@ -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/lib/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
}

51
structs.go Normal file
View File

@ -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/lib/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
}