just a "gui" from <STDIN>

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-01-18 00:11:03 -06:00
commit 66f87e3448
10 changed files with 338 additions and 0 deletions

16
Makefile Normal file
View File

@ -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

5
README.md Normal file
View File

@ -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.

89
action.go Normal file
View File

@ -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)
}

30
args.go Normal file
View File

@ -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")
}

51
event.go Normal file
View File

@ -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:
}
}
*/

3
go.mod Normal file
View File

@ -0,0 +1,3 @@
module go.wit.com/gui/toolkits/nocui
go 1.21.4

24
main.go Normal file
View File

@ -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")
}

74
stdin.go Normal file
View File

@ -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)
}
}
}
}
}

22
structs.go Normal file
View File

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

24
tree.go Normal file
View File

@ -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()
}