diff options
| -rw-r--r-- | action.go | 12 | ||||
| -rw-r--r-- | addText.go | 32 | ||||
| -rw-r--r-- | args.go | 8 | ||||
| -rw-r--r-- | box.go | 2 | ||||
| -rw-r--r-- | button.go | 2 | ||||
| -rw-r--r-- | checkbox.go | 2 | ||||
| -rw-r--r-- | common.go | 121 | ||||
| -rw-r--r-- | debug.go | 33 | ||||
| -rw-r--r-- | doc.go | 28 | ||||
| -rw-r--r-- | dropdown.go | 2 | ||||
| -rw-r--r-- | grid.go | 12 | ||||
| -rw-r--r-- | group.go | 4 | ||||
| -rw-r--r-- | image.go | 2 | ||||
| -rw-r--r-- | label.go | 2 | ||||
| -rw-r--r-- | main.go | 100 | ||||
| -rw-r--r-- | node.go | 22 | ||||
| -rw-r--r-- | plugin.go | 60 | ||||
| -rw-r--r-- | redraw.go | 6 | ||||
| -rw-r--r-- | separator.go | 2 | ||||
| -rw-r--r-- | setText.go | 10 | ||||
| -rw-r--r-- | slider.go | 2 | ||||
| -rw-r--r-- | spinner.go | 2 | ||||
| -rw-r--r-- | structs.go | 54 | ||||
| -rw-r--r-- | textbox.go | 2 | ||||
| -rw-r--r-- | watchdog.go | 8 | ||||
| -rw-r--r-- | window.go | 14 |
26 files changed, 305 insertions, 239 deletions
@@ -12,8 +12,8 @@ package gui import ( "errors" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // 2024/01/11 finally moving to type any. simplify to just 'value' @@ -47,9 +47,9 @@ func sendAction(n *Node, atype widget.ActionType) { // set state a.State.ProgName = n.progname - a.State.Label = n.label - a.State.Value = n.value - a.State.Direction = n.direction + a.State.Label = n.label + a.State.Value = n.value + a.State.Direction = n.direction for s, _ := range n.strings { a.State.Strings = append(a.State.Strings, s) } @@ -68,7 +68,7 @@ func sendAction(n *Node, atype widget.ActionType) { a.State.GridOffset.X = n.AtW a.State.GridOffset.Y = n.AtH - if (n.parent != nil) { + if n.parent != nil { a.ParentId = n.parent.id } a.WidgetType = n.WidgetType @@ -79,7 +79,7 @@ func sendAction(n *Node, atype widget.ActionType) { func sendActionToPlugin(a *widget.Action) { for _, aplug := range allPlugins { log.Log(PLUG, "Action() aplug =", aplug.name, "Action type=", a.ActionType) - if (aplug.pluginChan == nil) { + if aplug.pluginChan == nil { log.Warn("Action() retrieving the aplug.PluginChannel()", aplug.name) aplug.pluginChan = aplug.PluginChannel() log.Warn("Action() retrieved", aplug.pluginChan) @@ -1,15 +1,17 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // tracks dropdown and combobox entries. Makes sure they are unique func (n *Node) addText(newS string) { var highest int for s, i := range n.strings { - if i > highest { highest = i } + if i > highest { + highest = i + } if s == newS { return } @@ -17,17 +19,17 @@ func (n *Node) addText(newS string) { n.strings[newS] = highest + 1 // TODO: use the int's for the order n.value = newS /* - // time.Sleep(time.Duration(1000 * time.Nanosecond)) // doesn't work - // maybe this stupid chipset is defective. TODO: try on different hardware - // tried with go 1.21.4 debian sid - mylock.Lock() - n.mu.Lock() - // time.Sleep(time.Duration(10 * time.Microsecond)) // doesn't work - time.Sleep(time.Duration(100 * time.Microsecond)) // does work - n.strings = append(n.strings, newS) - n.mu.Unlock() - mylock.Unlock() - log.Warn("addText() has strings:", n.strings) + // time.Sleep(time.Duration(1000 * time.Nanosecond)) // doesn't work + // maybe this stupid chipset is defective. TODO: try on different hardware + // tried with go 1.21.4 debian sid + mylock.Lock() + n.mu.Lock() + // time.Sleep(time.Duration(10 * time.Microsecond)) // doesn't work + time.Sleep(time.Duration(100 * time.Microsecond)) // does work + n.strings = append(n.strings, newS) + n.mu.Unlock() + mylock.Unlock() + log.Warn("addText() has strings:", n.strings) */ // inform the toolkits @@ -38,7 +40,9 @@ func (n *Node) addText(newS string) { // multiple string values // These must be unique. return false if the string already exists func (n *Node) AddText(str string) bool { - if ! n.Ready() { return false } + if !n.Ready() { + return false + } log.Warn("AddText() value =", str) log.Warn("AddText() value =", str) log.Warn("AddText() value =", str) @@ -1,8 +1,8 @@ package gui import ( - "go.wit.com/log" "go.wit.com/dev/alexflint/arg" + "go.wit.com/log" ) var INFO *log.LogFlag @@ -16,8 +16,8 @@ var argGui ArgsGui // This struct can be used with the go-arg package type ArgsGui struct { - GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"` - GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"` + GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"` + GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"` } // returns the toolkit @@ -31,7 +31,7 @@ func init() { full := "go.wit.com/gui/gui" short := "gui" - NOW = log.NewFlag("NOW", true, full, short, "temp debugging stuff") + NOW = log.NewFlag("NOW", true, full, short, "temp debugging stuff") INFO = log.NewFlag("INFO", false, full, short, "General Info") GUI = log.NewFlag("GUI", false, full, short, "basic GUI internals") NODE = log.NewFlag("NODE", false, full, short, "binary tree debugging") @@ -1,7 +1,7 @@ package gui import ( - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) func (parent *Node) NewBox(progname string, b bool) *Node { @@ -1,6 +1,6 @@ package gui -import "go.wit.com/gui/widget" +import "go.wit.com/lib/widget" func (parent *Node) NewButton(name string, custom func()) *Node { newNode := parent.newNode(name, widget.Button) diff --git a/checkbox.go b/checkbox.go index 012c30c..db0c9a3 100644 --- a/checkbox.go +++ b/checkbox.go @@ -1,6 +1,6 @@ package gui -import "go.wit.com/gui/widget" +import "go.wit.com/lib/widget" func (n *Node) Checked() bool { return widget.GetBool(n.value) @@ -3,16 +3,20 @@ package gui // Common actions for widgets like 'Enable' or 'Hide' import ( - "regexp" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" + "regexp" ) // functions for handling text related GUI elements func (n *Node) Show() *Node { - if ! n.Ready() { return n } - if ! n.Hidden() { return n } + if !n.Ready() { + return n + } + if !n.Hidden() { + return n + } n.hidden = false n.changed = true @@ -31,9 +35,12 @@ func (n *Node) Show() *Node { func (n *Node) Hide() *Node { return n - if ! n.Ready() { return n } - if n.Hidden() { return n } - + if !n.Ready() { + return n + } + if n.Hidden() { + return n + } if n.WidgetType == widget.Window { log.Warn("Hide on a window", n.progname) @@ -55,7 +62,9 @@ func (n *Node) Hide() *Node { // enables a widget so the user can see it and work/click/etc on it // by default, widgets are enabled when they are created func (n *Node) Enable() *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } // if n.enabled { return n } n.enabled = true @@ -69,7 +78,9 @@ func (n *Node) Enable() *Node { // disables a widget so the user can see it, but can not // interact or change it. func (n *Node) Disable() *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } // if ! n.enabled { return n } n.enabled = false @@ -81,25 +92,33 @@ func (n *Node) Disable() *Node { } func (n *Node) Bool() bool { - if ! n.Ready() { return false} + if !n.Ready() { + return false + } return widget.GetBool(n.value) } func (n *Node) Int() int { - if ! n.Ready() { return -1} + if !n.Ready() { + return -1 + } return widget.GetInt(n.value) } func (n *Node) String() string { - if ! n.Ready() { return ""} + if !n.Ready() { + return "" + } return widget.GetString(n.value) } func (n *Node) Strings() []string { - if ! n.Ready() { return nil} + if !n.Ready() { + return nil + } var tmp []string for s, _ := range n.strings { @@ -110,7 +129,9 @@ func (n *Node) Strings() []string { } func (n *Node) Destroy() { - if ! n.Ready() { return } + if !n.Ready() { + return + } // if ! n.enabled { return } n.enabled = false @@ -124,7 +145,9 @@ func (n *Node) Destroy() { // appends text to the existing text // TODO: this is an experiement func (n *Node) AppendText(str string) { - if ! n.Ready() { return } + if !n.Ready() { + return + } tmp := widget.GetString(n.value) + str n.value = tmp n.changed = true @@ -161,7 +184,9 @@ func (n *Node) GetBool() bool { // should get the reference name used for programming and debugging func (n *Node) SetProgName(s string) *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } if n.progname == s { // don't do anything since nothing changed @@ -174,13 +199,15 @@ func (n *Node) SetProgName(s string) *Node { } /* - TODO: ensure these are unique and make a way to look them up - myButton = myGroup.NewButton("hit ball", nil).SetName("HIT") - myButton.GetName() should return "HIT" - n = Find("HIT") should return myButton +TODO: ensure these are unique and make a way to look them up +myButton = myGroup.NewButton("hit ball", nil).SetName("HIT") +myButton.GetName() should return "HIT" +n = Find("HIT") should return myButton */ func (n *Node) GetProgName() string { - if ! n.Ready() { return "" } + if !n.Ready() { + return "" + } return n.progname } @@ -198,8 +225,12 @@ func commonCallback(n *Node) { */ func (n *Node) Margin() *Node { - if ! n.Ready() { return n } - if n.margin { return n } + if !n.Ready() { + return n + } + if n.margin { + return n + } n.margin = true n.changed = true @@ -211,8 +242,12 @@ func (n *Node) Margin() *Node { } func (n *Node) Unmargin() *Node { - if ! n.Ready() { return n } - if ! n.margin { return n } + if !n.Ready() { + return n + } + if !n.margin { + return n + } n.margin = false n.changed = true @@ -223,8 +258,12 @@ func (n *Node) Unmargin() *Node { } func (n *Node) Pad() *Node { - if ! n.Ready() { return n } - if n.pad == true { return n } // nothing changed + if !n.Ready() { + return n + } + if n.pad == true { + return n + } // nothing changed n.pad = true n.changed = true @@ -236,8 +275,12 @@ func (n *Node) Pad() *Node { } func (n *Node) Unpad() *Node { - if ! n.Ready() { return n } - if n.pad == false { return n } // nothing changed + if !n.Ready() { + return n + } + if n.pad == false { + return n + } // nothing changed n.pad = false n.changed = true @@ -248,8 +291,12 @@ func (n *Node) Unpad() *Node { } func (n *Node) Expand() *Node { - if ! n.Ready() { return n } - if n.expand == true { return n } // nothing changed + if !n.Ready() { + return n + } + if n.expand == true { + return n + } // nothing changed n.expand = true n.changed = true @@ -260,8 +307,12 @@ func (n *Node) Expand() *Node { } func (n *Node) SetExpand(b bool) *Node { - if ! n.Ready() { return n } - if n.expand == b { return n } // nothing changed + if !n.Ready() { + return n + } + if n.expand == b { + return n + } // nothing changed n.expand = b n.changed = true @@ -273,7 +324,9 @@ func (n *Node) SetExpand(b bool) *Node { // is the widget currently viewable? func (n *Node) Hidden() bool { - if ! n.Ready() { return false } + if !n.Ready() { + return false + } return n.hidden } @@ -8,8 +8,8 @@ import ( "errors" "strconv" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // for printing out the binary tree @@ -25,15 +25,15 @@ func (n *Node) Dump() { Indent(b, "(X,Y) = ", n.X, n.Y) Indent(b, "Next (W,H) = ", n.NextW, n.NextH) - if (n.parent == nil) { + if n.parent == nil { Indent(b, "parent = nil") } else { Indent(b, "parent.id =", n.parent.id) } - if (n.children != nil) { + if n.children != nil { Indent(b, "children = ", n.children) } - if (n.Custom != nil) { + if n.Custom != nil { Indent(b, "Custom = ", n.Custom) } Indent(b, "NODE DUMP END") @@ -49,13 +49,12 @@ func Indent(b bool, a ...interface{}) { func (n *Node) dumpWidget(b bool) string { var info, d string - if (n == nil) { + if n == nil { log.Error(errors.New("dumpWidget() node == nil")) return "" } info = n.WidgetType.String() - var tabs string for i := 0; i < listChildrenDepth; i++ { tabs = tabs + defaultPadding @@ -87,21 +86,21 @@ func (n *Node) Children() []*Node { // func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) { func (n *Node) ListChildren(dump bool) { - if (n == nil) { + if n == nil { return } n.dumpWidget(dump) if len(n.children) == 0 { - if (n.parent == nil) { + if n.parent == nil { return } - log.Log(NODE, "\t\t\tparent =",n.parent.id) - if (listChildrenParent != nil) { - log.Log(NODE, "\t\t\tlistChildrenParent =",listChildrenParent.id) - if (listChildrenParent.id != n.parent.id) { - log.Log(NOW, "parent =",n.parent.id, n.parent.progname) - log.Log(NOW, "listChildrenParent =",listChildrenParent.id, listChildrenParent.progname) + log.Log(NODE, "\t\t\tparent =", n.parent.id) + if listChildrenParent != nil { + log.Log(NODE, "\t\t\tlistChildrenParent =", listChildrenParent.id) + if listChildrenParent.id != n.parent.id { + log.Log(NOW, "parent =", n.parent.id, n.parent.progname) + log.Log(NOW, "listChildrenParent =", listChildrenParent.id, listChildrenParent.progname) log.Log(NOW, listChildrenParent.id, "!=", n.parent.id) log.Exit("parent.child does not match child.parent") } @@ -110,15 +109,15 @@ func (n *Node) ListChildren(dump bool) { return } for _, child := range n.children { - if (child.parent != nil) { - log.Log(NODE, "\t\t\tparent =",child.parent.id) + if child.parent != nil { + log.Log(NODE, "\t\t\tparent =", child.parent.id) } else { log.Log(GUI, "\t\t\tno parent") // memory corruption? non-threadsafe access? // can all binary tree changes to Node.parent & Node.child be forced into a singular goroutine? panic("something is wrong with the wit golang gui logic and the binary tree is broken. child has no parent") } - if (child.children == nil) { + if child.children == nil { log.Log(NODE, "\t\t", child.id, "has no children") } else { log.Log(NODE, "\t\t\tHas children:", child.children) @@ -1,22 +1,21 @@ /* - Package gui implements a abstraction layer for Go visual elements. Definitions: - * Toolkit: the underlying GUI library (MacOS gui, Windows gui, gtk, qt, etc) - * Node: A binary tree of all the underlying widgets + - Toolkit: the underlying GUI library (MacOS gui, Windows gui, gtk, qt, etc) + - Node: A binary tree of all the underlying widgets Principles: - * Make code using this package simple to use - * Hide complexity internally here - * Isolate the GUI toolkit - * Widget names should try to match [Wikipedia Graphical widget] - * When in doubt, search upward in the binary tree - * It's ok to guess. Try to do something sensible. + - Make code using this package simple to use + - Hide complexity internally here + - Isolate the GUI toolkit + - Widget names should try to match [Wikipedia Graphical widget] + - When in doubt, search upward in the binary tree + - It's ok to guess. Try to do something sensible. -Debian Build +# Debian Build This worked on debian sid (mate-desktop) on 2023/12/03 I didn't record the dependances needed (gtk-dev) @@ -61,21 +60,21 @@ consistant. External Toolkits - * andlabs - https://github.com/andlabs/ui - * gocui - https://github.com/awesome-gocui/gocui + - andlabs - https://github.com/andlabs/ui + - gocui - https://github.com/awesome-gocui/gocui The next step is to allow this to work against go-gtk and go-qt. TODO: Add Fyne, WASM, native macos & windows, android and hopefully also things like libSDL, faiface/pixel, slint -Bugs +# Bugs "The author's idea of friendly may differ to that of many other people." -- quote from the minimalistic window manager 'evilwm' -References +# References Useful links and other external things which might be useful @@ -86,6 +85,5 @@ external things which might be useful * [Federated git pull](https://github.com/forgefed/forgefed) Hopefully this will work for me with gitea * [Github mirror](https://github.com/wit-go/gui) This repo on mirror. Hopefully I won't have to use this. * [WIT GO projects](https://go.wit.com/) Attempt to model go.uber.org - */ package gui diff --git a/dropdown.go b/dropdown.go index f5882a9..4d61b1a 100644 --- a/dropdown.go +++ b/dropdown.go @@ -6,7 +6,7 @@ package gui // since it is the same. confusing names? maybe... import ( - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) /* @@ -1,8 +1,8 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // Grid numbering examples (H) or (W,H) @@ -24,7 +24,7 @@ import ( // ----------------------------- type Grid struct { - Width int + Width int Height int } @@ -53,7 +53,7 @@ func (n *Node) NewGrid(progname string, w int, h int) *Node { // true if the grid already have a child at W,H func (n *Node) gridCollision() bool { for _, child := range n.children { - if ((child.AtW == n.NextW) && (child.AtH == n.NextH)) { + if (child.AtW == n.NextW) && (child.AtH == n.NextH) { return true } } @@ -62,12 +62,12 @@ func (n *Node) gridCollision() bool { // keeps incrementing NextW & NextH until there is not a widget func (n *Node) gridIncrement() { - if ! n.gridCollision() { + if !n.gridCollision() { return } n.NextW += 1 - if (n.NextW > n.W) { + if n.NextW > n.W { n.NextW = 1 n.NextH += 1 } @@ -76,7 +76,7 @@ func (n *Node) gridIncrement() { } func (n *Node) At(w int, h int) *Node { - if (n == nil) { + if n == nil { return n } @@ -1,11 +1,11 @@ package gui import ( - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) // TODO: make a "Group" a "Grid" ? -// probably since right now group is just a +// probably since right now group is just a // pre-canned andlabs/ui gtk,macos,windows thing func (parent *Node) NewGroup(name string) *Node { var newNode *Node @@ -1,8 +1,8 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) func (parent *Node) NewImage(name string) *Node { @@ -1,7 +1,7 @@ package gui import ( - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) func (parent *Node) NewLabel(text string) *Node { @@ -3,8 +3,8 @@ package gui import ( "os" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // TODO: make a fake 'plugin' channel of communication to andlabs for mswindows @@ -39,18 +39,18 @@ func init() { } // lookup the widget by the id sent from the toolkit -func (n *Node) findId(i int) (*Node) { - if (n == nil) { +func (n *Node) findId(i int) *Node { + if n == nil { return nil } - if (n.id == i) { + if n.id == i { return n } for _, child := range n.children { newN := child.findId(i) - if (newN != nil) { + if newN != nil { return newN } } @@ -61,20 +61,20 @@ func watchCallback() { log.Info("guiChan() START") for { log.Info("guiChan() select restarted") - select { + select { case a := <-me.guiChan: - if (a.ActionType == widget.UserQuit) { + if a.ActionType == widget.UserQuit { log.Warn("guiChan() User sent Quit()") me.rootNode.doCustom() log.Exit("wit/gui toolkit.UserQuit") break } - if (a.ActionType == widget.CloseWindow) { + if a.ActionType == widget.CloseWindow { log.Warn("guiChan() Close Window") StandardExit() break } - if (a.ActionType == widget.ToolkitPanic) { + if a.ActionType == widget.ToolkitPanic { log.Warn("guiChan() Toolkit panic() in", a.ProgName) log.Warn("guiChan() unload toolkit plugin here", a.ProgName) me.rootNode.ListToolkits() @@ -95,12 +95,12 @@ func watchCallback() { me.rootNode.LoadToolkit("nocui") break } - if (a.ActionType == widget.ToolkitLoad) { + if a.ActionType == widget.ToolkitLoad { newPlug := widget.GetString(a.Value) log.Warn("Attempt to load a new toolkit", newPlug, "here") me.rootNode.LoadToolkit(newPlug) } - if (a.ActionType == widget.EnableDebug) { + if a.ActionType == widget.EnableDebug { log.Warn("guiChan() Enable Debugging Window") log.Warn("guiChan() TODO: not implemented") log.Warn("guiChan() Listing Toolkits:") @@ -120,7 +120,7 @@ func watchCallback() { } n := me.rootNode.findId(a.WidgetId) - if (n == nil) { + if n == nil { log.Warn("guiChan() UNKNOWN widget id") log.Warn("id =", a.WidgetId, a.ProgName) } else { @@ -136,7 +136,7 @@ func watchCallback() { func (n *Node) doCustom() { log.Info("doUserEvent() widget =", n.id, n.progname, n.WidgetType) - if (n.Custom == nil) { + if n.Custom == nil { log.Warn("Custom() = nil. SKIPPING") return } @@ -153,39 +153,39 @@ func (n *Node) doUserEvent(a widget.Action) { n.doCustom() return /* - switch n.WidgetType { - case widget.Checkbox: - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.value) - n.doCustom() - case widget.Button: - log.Info("doUserEvent() node =", n.id, n.progname, "button clicked") - n.doCustom() - case widget.Combobox: - n.S = a.S - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) - n.doCustom() - case widget.Dropdown: - n.S = a.S - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) - n.doCustom() - case widget.Textbox: - n.S = a.S - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) - n.doCustom() - case widget.Spinner: - n.I = a.I - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I) - n.doCustom() - case widget.Slider: - n.I = a.I - log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I) - n.doCustom() - case widget.Window: - log.Info("doUserEvent() node =", n.id, n.progname, "window closed") - n.doCustom() - default: - log.Info("doUserEvent() type =", n.WidgetType) - } + switch n.WidgetType { + case widget.Checkbox: + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.value) + n.doCustom() + case widget.Button: + log.Info("doUserEvent() node =", n.id, n.progname, "button clicked") + n.doCustom() + case widget.Combobox: + n.S = a.S + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) + n.doCustom() + case widget.Dropdown: + n.S = a.S + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) + n.doCustom() + case widget.Textbox: + n.S = a.S + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S) + n.doCustom() + case widget.Spinner: + n.I = a.I + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I) + n.doCustom() + case widget.Slider: + n.I = a.I + log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I) + n.doCustom() + case widget.Window: + log.Info("doUserEvent() node =", n.id, n.progname, "window closed") + n.doCustom() + default: + log.Info("doUserEvent() type =", n.WidgetType) + } */ } @@ -199,19 +199,19 @@ func New() *Node { // try to load andlabs, if that doesn't work, fall back to the console func (n *Node) Default() *Node { - if (argGui.GuiPlugin != "") { + if argGui.GuiPlugin != "" { log.Warn("New.Default() try toolkit =", argGui.GuiPlugin) return n.LoadToolkit(argGui.GuiPlugin) } // if DISPLAY isn't set, return since gtk can't load // TODO: figure out how to check what to do in macos and mswindows - if (os.Getenv("DISPLAY") == "") { - if (n.LoadToolkit("gocui") == nil) { + if os.Getenv("DISPLAY") == "" { + if n.LoadToolkit("gocui") == nil { log.Warn("New() failed to load gocui") } return n } - if (n.LoadToolkit("andlabs") != nil) { + if n.LoadToolkit("andlabs") != nil { return n } n.LoadToolkit("gocui") @@ -1,17 +1,17 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) /* - generic function to create a new node on the binary tree +generic function to create a new node on the binary tree - this is called each time you want a new widget - and it initializes basic default values +this is called each time you want a new widget +and it initializes basic default values - there isn't much to see here. +there isn't much to see here. */ func (n *Node) newNode(title string, t widget.WidgetType) *Node { var newN *Node @@ -42,7 +42,7 @@ func (n *Node) newNode(title string, t widget.WidgetType) *Node { } /* - raw create function for a new node struct and increments the counter +raw create function for a new node struct and increments the counter */ func addNode() *Node { n := new(Node) @@ -54,16 +54,20 @@ func addNode() *Node { } func (n *Node) Parent() *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } return n.parent } func (n *Node) Delete(d *Node) { - if ! n.Ready() { return } + if !n.Ready() { + return + } for i, child := range n.children { log.Log(NODE, "\t", i, child.id, child.progname) - if (child.id == d.id) { + if child.id == d.id { log.Log(NODE, "\t\t Deleting this") n.children = append(n.children[:i], n.children[i+1:]...) return @@ -6,21 +6,22 @@ package gui // It's a pleasure to be here with all of you import ( - "os" "embed" + "os" "plugin" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) var err error + type Symbol any type aplug struct { - name string + name string filename string - plug *plugin.Plugin + plug *plugin.Plugin // this tells the toolkit plugin how to send events // back here @@ -33,7 +34,7 @@ type aplug struct { // Callback func(chan widget.Action) - // This is how actions are sent to the toolkit. + // This is how actions are sent to the toolkit. // For example: // If a program is using GTK, when a program tries to make a new button // "Open GIMP", then it would pass an action via this channel into the toolkit @@ -42,7 +43,7 @@ type aplug struct { // each toolkit has it's own goroutine and each one is sent this // add button request // - pluginChan chan widget.Action + pluginChan chan widget.Action PluginChannel func() chan widget.Action } @@ -55,7 +56,7 @@ func initPlugin(name string) *aplug { for _, aplug := range allPlugins { log.Log(PLUG, "initPlugin() already loaded toolkit plugin =", aplug.name) - if (aplug.name == name) { + if aplug.name == name { log.Warn("initPlugin() SKIPPING", name, "as you can't load it twice") return nil } @@ -64,7 +65,7 @@ func initPlugin(name string) *aplug { return searchPaths(name) } -// newPlug.PluginChannel = getPluginChannel(newPlug, "PluginChannel") +// newPlug.PluginChannel = getPluginChannel(newPlug, "PluginChannel") func getPluginChannel(p *aplug, funcName string) func() chan widget.Action { var newfunc func() chan widget.Action var ok bool @@ -104,12 +105,13 @@ func sendCallback(p *aplug, funcName string) func(chan widget.Action) { } /* - TODO: clean this up. use command args? - TODO: use LD_LIBRARY_PATH ? - This searches in the following order for the plugin .so files: - ./toolkit/ - ~/go/src/go.wit.com/gui/toolkit/ - /usr/lib/go-gui/ +TODO: clean this up. use command args? +TODO: use LD_LIBRARY_PATH ? +This searches in the following order for the plugin .so files: + + ./toolkit/ + ~/go/src/go.wit.com/toolkits/ + /usr/lib/go-gui/ */ func searchPaths(name string) *aplug { var filename string @@ -119,14 +121,14 @@ func searchPaths(name string) *aplug { // first try to load the embedded plugin file filename = "resources/" + name + ".so" pfile, err = me.resFS.ReadFile(filename) - if (err == nil) { + if err == nil { filename = "/tmp/" + name + ".so" log.Error(err, "write out file here", name, filename, len(pfile)) f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600) f.Write(pfile) f.Close() p := initToolkit(name, filename) - if (p != nil) { + if p != nil { return p } } else { @@ -134,9 +136,9 @@ func searchPaths(name string) *aplug { } // attempt to write out the file from the internal resource - filename = "toolkits/" + name + ".so" + filename = "resources/" + name + ".so" p := initToolkit(name, filename) - if (p != nil) { + if p != nil { return p } @@ -146,21 +148,21 @@ func searchPaths(name string) *aplug { return nil } - filename = homeDir + "/go/src/go.wit.com/gui/toolkits/" + name + ".so" + filename = homeDir + "/go/src/go.wit.com/toolkits/" + name + ".so" p = initToolkit(name, filename) - if (p != nil) { + if p != nil { return p } filename = "/usr/lib/go-gui/latest/" + name + ".so" p = initToolkit(name, filename) - if (p != nil) { + if p != nil { return p } filename = "/usr/local/lib/gui/toolkits/" + name + ".so" p = initToolkit(name, filename) - if (p != nil) { + if p != nil { return p } return nil @@ -203,7 +205,7 @@ func initToolkit(name string, filename string) *aplug { // set the communication to the plugins newPlug.pluginChan = newPlug.PluginChannel() - if (newPlug.pluginChan == nil) { + if newPlug.pluginChan == nil { log.Warn("initToolkit() ERROR PluginChannel() returned nil for plugin:", newPlug.name, filename) return nil } @@ -221,14 +223,14 @@ func (n *Node) InitEmbed(resFS embed.FS) *Node { func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node { for _, aplug := range allPlugins { log.Info("LoadToolkitEmbed() already loaded toolkit plugin =", aplug.name) - if (aplug.name == name) { + if aplug.name == name { log.Warn("LoadToolkitEmbed() SKIPPING", name, "as you can't load it twice") return n } } - f, err := os.CreateTemp("", "sample." + name + ".so") - if (err != nil) { + f, err := os.CreateTemp("", "sample."+name+".so") + if err != nil { log.Error(err, "LoadToolkitEmbed() SKIPPING", name, "as you can't load it twice") return n } @@ -236,7 +238,7 @@ func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node { f.Write(b) p := initToolkit(name, f.Name()) - if (p == nil) { + if p == nil { log.Warn("LoadToolkitEmbed() embedded go file failed", name) } return n @@ -251,7 +253,7 @@ func (n *Node) ListToolkits() { func (n *Node) LoadToolkit(name string) *Node { log.Log(PLUG, "LoadToolkit() START for name =", name) plug := initPlugin(name) - if (plug == nil) { + if plug == nil { return n } @@ -271,7 +273,7 @@ func (n *Node) CloseToolkit(name string) bool { log.Log(PLUG, "CloseToolkit() for name =", name) for _, plug := range allPlugins { log.Log(PLUG, "CloseToolkit() found", plug.name) - if (plug.name == name) { + if plug.name == name { log.Log(PLUG, "CloseToolkit() sending close", name) var a widget.Action a.ActionType = widget.ToolkitClose @@ -1,15 +1,15 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // This recreates the whole GUI for a plugin // func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) { func (n *Node) redraw(p *aplug) { - if (n == nil) { + if n == nil { return } @@ -40,7 +40,7 @@ func (n *Node) redo(plug *aplug) { a.AtW = n.AtW a.AtH = n.AtH - if (n.parent == nil) { + if n.parent == nil { a.ParentId = 0 } else { a.ParentId = n.parent.id diff --git a/separator.go b/separator.go index 2765b24..8da91bc 100644 --- a/separator.go +++ b/separator.go @@ -1,7 +1,7 @@ package gui import ( - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) func (parent *Node) NewSeparator(progname string) *Node { @@ -5,12 +5,14 @@ package gui import ( "errors" + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) func (n *Node) SetText(text string) *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } if n.String() == text { // nothing changed @@ -26,7 +28,9 @@ func (n *Node) SetText(text string) *Node { } func (n *Node) Set(val any) { - if ! n.Ready() { return } + if !n.Ready() { + return + } switch v := val.(type) { case bool: @@ -1,8 +1,8 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) func (parent *Node) NewSlider(progname string, x int, y int) *Node { @@ -1,8 +1,8 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) func (parent *Node) NewSpinner(progname string, x int, y int) *Node { @@ -1,9 +1,9 @@ package gui import ( - "sync" "embed" - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" + "sync" ) // @@ -28,7 +28,7 @@ var me guiConfig // seem to be a good idea to use 'type any' here as it // just makes things more complicated for no good reason type RangeMovedToWidget struct { - Low int + Low int High int } @@ -45,19 +45,19 @@ type guiConfig struct { rootNode *Node // A node off of rootNode for passing debugging flags - flag *Node + flag *Node - counter int // used to make unique WidgetId's + counter int // used to make unique WidgetId's // sets the chan for the plugins to call back too guiChan chan widget.Action // option to pass in compiled plugins as embedded files - resFS embed.FS + resFS embed.FS // used to beautify logging to Stdout -// depth int -// prefix string + // depth int + // prefix string } /* @@ -86,23 +86,23 @@ type guiConfig struct { */ type Node struct { - id int // should be unique - hidden bool // don't update the toolkits when it's hidden + id int // should be unique + hidden bool // don't update the toolkits when it's hidden changed bool // do we need to inform the toolkit something changed? enabled bool // if false, then the the user can't click on it - mu sync.Mutex + mu sync.Mutex - WidgetType widget.WidgetType + WidgetType widget.WidgetType // most widgets need one value, this is current alue - value any + value any // label string // this can programatically identify the widget // The name must be unique - progname string // a name useful for debugging + progname string // a name useful for debugging // for widgets that a user select from a list of strings strings map[string]int @@ -113,35 +113,33 @@ type Node struct { // this function is run when there are mouse or keyboard events Custom func() - parent *Node + parent *Node children []*Node - // RETHINK EVERYTHING BELOW HERE - pad bool // the toolkit may use this. it's up to the toolkit - margin bool // the toolkit may use this. it's up to the toolkit - expand bool // the toolkit may use this. it's up to the toolkit - + pad bool // the toolkit may use this. it's up to the toolkit + margin bool // the toolkit may use this. it's up to the toolkit + expand bool // the toolkit may use this. it's up to the toolkit // used for Windows in toolkits measured in pixels width int height int // used for anything that needs a range (for example: a slider) - X int - Y int + X int + Y int // the grid widget max width and height // the max height can be implemented in the toolkit plugin // to restrict the number of rows to display - W int - H int + W int + H int // where the next widget should be put in this grid - NextW int - NextH int + NextW int + NextH int // if this widget is in a grid, this is the position of a widget - AtW int - AtH int + AtW int + AtH int } @@ -3,7 +3,7 @@ package gui import ( "go.wit.com/log" - "go.wit.com/gui/widget" + "go.wit.com/lib/widget" ) func (parent *Node) NewTextbox(name string) *Node { diff --git a/watchdog.go b/watchdog.go index a57005c..02e7a2f 100644 --- a/watchdog.go +++ b/watchdog.go @@ -9,11 +9,11 @@ import ( var watchtime time.Duration = 100 // in tenths of seconds /* - This program sits here. - If you exit here, the whole thing will os.Exit() - TODO: use Ticker +This program sits here. +If you exit here, the whole thing will os.Exit() +TODO: use Ticker - This goroutine can be used like a watchdog timer +This goroutine can be used like a watchdog timer */ func Watchdog() { var i = 1 @@ -1,8 +1,8 @@ package gui import ( + "go.wit.com/lib/widget" "go.wit.com/log" - "go.wit.com/gui/widget" ) // This routine creates a blank window with a Title and size (W x H) @@ -38,7 +38,9 @@ func (parent *Node) RawWindow(title string) *Node { // TODO: should do this recursively func (n *Node) UnDraw() *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } n.hidden = true n.changed = true @@ -50,10 +52,12 @@ func (n *Node) UnDraw() *Node { // TODO: should do this recursively func (n *Node) Draw() *Node { - if ! n.Ready() { return n } + if !n.Ready() { + return n + } n.hidden = false - n.changed= true + n.changed = true // inform the toolkits sendAction(n, widget.Add) @@ -71,7 +75,7 @@ func (n *Node) PixelSize(w, h int) *Node { */ func (n *Node) TestDraw() { - if (n == nil) { + if n == nil { return } |
