commit 66f87e34481df249b238d2b1490b6a0c1a3402e0 Author: Jeff Carr Date: Thu Jan 18 00:11:03 2024 -0600 just a "gui" from Signed-off-by: Jeff Carr diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..15c7487 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +all: plugin + ldd ../nocui.so + +plugin: + GO111MODULE="off" go build -v -x -buildmode=plugin -o ../nocui.so + +cleanbuild: + go build -v -x -buildmode=plugin -o ../nocui.so + +check-git-clean: + @git diff-index --quiet HEAD -- || (echo "Git repository is dirty, please commit your changes first"; exit 1) + +redomod: + rm -f go.* + GO111MODULE= go mod init + GO111MODULE= go mod tidy diff --git a/README.md b/README.md new file mode 100644 index 0000000..018b9ce --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# nogui + +Package gui implements a abstraction layer for Go visual elements. + +This is a sample plugin. It's a skeleton intended to be used when making a new toolkit plugin. diff --git a/action.go b/action.go new file mode 100644 index 0000000..ea1a6fa --- /dev/null +++ b/action.go @@ -0,0 +1,89 @@ +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/lib/widget" + // "go.wit.com/gui/toolkits/tree" +) + +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.ToolkitInit) { + return + } + + log.Log(INFO, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId) + switch a.WidgetType { + case widget.Root: + me.treeRoot = me.myTree.AddNode(&a) + log.Log(INFO, "doAction() found treeRoot") + return + } + + switch a.ActionType { + case widget.Add: + me.myTree.AddNode(&a) + return + } + + 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.Show: + n.State.Visable = true + case widget.Hide: + n.State.Visable = false + case widget.Enable: + n.State.Visable = true + case widget.Disable: + n.State.Visable = false + case widget.Get: + log.Warn("value =", n.State.Value) + case widget.GetText: + log.Warn("value =", n.String()) + case widget.Set: + n.State.Value = a.State.Value + case widget.SetText: + 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.State.Strings = append(a.State.Strings, widget.GetString(a.State.Value)) + case widget.Margin: + n.State.Pad = true + case widget.Unmargin: + n.State.Pad = false + case widget.Pad: + n.State.Pad = true + case widget.Unpad: + n.State.Pad = false + case widget.Delete: + log.Warn("doAction() TODO: Delete()") + // n.Delete() + case widget.Move: + log.Warn("doAction() TODO: Move()") + default: + log.Log(ERROR, "doAction() Unknown =", a.ActionType, a.WidgetType) + } + log.Log(INFO, "doAction() END =", a.ActionType, a.WidgetType) +} diff --git a/args.go b/args.go new file mode 100644 index 0000000..4b6b38e --- /dev/null +++ b/args.go @@ -0,0 +1,30 @@ +package main + +/* + this enables command line options from other packages like 'gui' and 'log' +*/ + +import ( + log "go.wit.com/log" +) + +var NOW *log.LogFlag +var INFO *log.LogFlag + +var SPEW *log.LogFlag +var WARN *log.LogFlag + +var ERROR *log.LogFlag + +func init() { + full := "toolkit/nocui" + short := "nocui" + + NOW = log.NewFlag( "NOW", true, full, short, "temp debugging stuff") + INFO = log.NewFlag("INFO", false, full, short, "normal debugging stuff") + + WARN = log.NewFlag("WARN", true, full, short, "bad things") + SPEW = log.NewFlag("SPEW", false, full, short, "spew stuff") + + ERROR = log.NewFlag("ERROR", false, full, short, "toolkit errors") +} diff --git a/event.go b/event.go new file mode 100644 index 0000000..9bbafdb --- /dev/null +++ b/event.go @@ -0,0 +1,51 @@ +package main + +/* +import ( + "go.wit.com/log" + "go.wit.com/gui/widget" + "go.wit.com/gui/toolkits/tree" +) + +func doWidgetClick(n *tree.Node) { + switch n.WidgetType { + case widget.Root: + // THIS IS THE BEGINING OF THE LAYOUT + // rootNode.nextW = 0 + // rootNode.nextH = 0 + // rootNode.redoTabs(true) + case widget.Flag: + // me.rootNode.redoColor(true) + // rootNode.dumpTree(true) + case widget.Window: + // setCurrentWindow(w) + // n.doUserEvent() + case widget.Tab: + // setCurrentTab(w) + case widget.Group: + // n.placeWidgets() + // n.toggleTree() + case widget.Checkbox: + if n.Bool() { + // n.setCheckbox(false) + } else { + // n.setCheckbox(true) + } + // n.doUserEvent() + case widget.Grid: + // rootNode.hideWidgets() + // n.placeGrid() + // n.showWidgets() + case widget.Box: + // n.showWidgetPlacement(logNow, "drawTree()") + if n.Bool() { + log.Log(NOW, "BOX IS HORIZONTAL", n.GetProgName()) + } else { + log.Log(NOW, "BOX IS VERTICAL", n.GetProgName()) + } + case widget.Button: + // n.doUserEvent() + default: + } +} +*/ diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..e802e10 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go.wit.com/gui/toolkits/nocui + +go 1.21.4 diff --git a/main.go b/main.go new file mode 100644 index 0000000..4b2b53b --- /dev/null +++ b/main.go @@ -0,0 +1,24 @@ +package main + +/* + This is reference code for toolkit developers + + The 'nocui' is a bare minimum toolkit. It's all you need + to interact with the GUI +*/ + +import ( + "go.wit.com/log" + "go.wit.com/toolkits/tree" +) + +func init() { + log.Log(INFO, "Init()") + + me.myTree = tree.New() + me.myTree.PluginName = "nocui" + me.myTree.ActionFromChannel = doAction + + go simpleStdin() + log.Log(INFO, "Init() END") +} diff --git a/stdin.go b/stdin.go new file mode 100644 index 0000000..9b9f794 --- /dev/null +++ b/stdin.go @@ -0,0 +1,74 @@ +package main + +import ( + "os" + "fmt" + "bufio" + "runtime/debug" + "strings" + "strconv" + + "go.wit.com/log" + "go.wit.com/lib/widget" +) + +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() + s = strings.TrimSuffix(s, "\n") + switch s { + case "l": + log.Log(NOW, "list widgets") + me.treeRoot.ListWidgets() + case "b": + log.Log(NOW, "show buttons") + me.treeRoot.ShowButtons() + case "g": + me.myTree.DoToolkitLoad("gocui") + case "a": + me.myTree.DoToolkitLoad("andlabs") + case "d": + 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.treeRoot.FindWidgetId(i) + if (n != nil) { + 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) + } + } + } + } +} diff --git a/structs.go b/structs.go new file mode 100644 index 0000000..8d01ef0 --- /dev/null +++ b/structs.go @@ -0,0 +1,22 @@ +package main + +import ( + "go.wit.com/toolkits/tree" +) + +// stores the raw toolkit internals +type guiWidget struct { + Width int + Height int + + c int + val map[string]int +} + +// It's probably a terrible idea to call this 'me' +var me config + +type config struct { + treeRoot *tree.Node // the base of the binary tree. it should have id == 0 + myTree *tree.TreeInfo +} diff --git a/tree.go b/tree.go new file mode 100644 index 0000000..6ba353e --- /dev/null +++ b/tree.go @@ -0,0 +1,24 @@ +package main + +/* + This is reference code for toolkit developers +*/ + +import ( + "go.wit.com/lib/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() +}