work on hiding widgets
When widgets are hidden, their state works exactly the same as normal, but updates are not sent to the toolkits Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
1e2fa2dce9
commit
732edc3faf
|
@ -0,0 +1,68 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is where the communication to the toolkit plugin happens.
|
||||||
|
|
||||||
|
We copy the current values from the widget node of the binary tree
|
||||||
|
and send an "action" to the toolkit over a channel.
|
||||||
|
|
||||||
|
TODO: use protobuf
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 2024/01/11 finally moving to type any. simplify to just 'value'
|
||||||
|
// 2023/05/09 pretty clean
|
||||||
|
// 2023/04/06 Queue() is also being used and channels are being used.
|
||||||
|
func sendAction(n *Node, atype widget.ActionType) {
|
||||||
|
if n == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if n.hidden {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var a widget.Action
|
||||||
|
a.ActionType = atype
|
||||||
|
|
||||||
|
// These should be "stable" at this point (2024/01/13)
|
||||||
|
a.WidgetId = n.id
|
||||||
|
a.ProgName = n.progname
|
||||||
|
a.Value = n.value
|
||||||
|
a.Direction = n.direction
|
||||||
|
a.Strings = n.strings
|
||||||
|
|
||||||
|
// These should be improved/deprecated based on the gui/widget docs
|
||||||
|
a.Expand = n.expand
|
||||||
|
|
||||||
|
a.X = n.X
|
||||||
|
a.Y = n.Y
|
||||||
|
|
||||||
|
a.AtW = n.AtW
|
||||||
|
a.AtH = n.AtH
|
||||||
|
|
||||||
|
if (n.parent != nil) {
|
||||||
|
a.ParentId = n.parent.id
|
||||||
|
}
|
||||||
|
a.WidgetType = n.WidgetType
|
||||||
|
sendActionToPlugin(&a)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sends the action/event to each toolkit via a golang plugin channel
|
||||||
|
func sendActionToPlugin(a *widget.Action) {
|
||||||
|
for _, aplug := range allPlugins {
|
||||||
|
log.Log(PLUG, "Action() aplug =", aplug.name, "Action type=", a.ActionType)
|
||||||
|
if (aplug.pluginChan == nil) {
|
||||||
|
log.Info("Action() retrieving the aplug.PluginChannel()", aplug.name)
|
||||||
|
aplug.pluginChan = aplug.PluginChannel()
|
||||||
|
log.Info("Action() retrieved", aplug.pluginChan)
|
||||||
|
}
|
||||||
|
log.Info("Action() SEND to pluginChan", aplug.name, a.ActionType, a.WidgetType, a.WidgetId, a.ProgName)
|
||||||
|
aplug.pluginChan <- *a
|
||||||
|
// added during debugging. might be a good idea in general for a tactile experience
|
||||||
|
log.Sleep(.02) // this delay makes it so SetText() works on initial widget creation
|
||||||
|
}
|
||||||
|
}
|
48
box.go
48
box.go
|
@ -4,39 +4,39 @@ import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewBox(name string, b bool) *Node {
|
func (parent *Node) NewBox(progname string, b bool) *Node {
|
||||||
newNode := parent.newNode(name, widget.Box)
|
newNode := parent.newNode(progname, widget.Box)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
if ! newNode.hidden {
|
if b {
|
||||||
a := newAction(newNode, widget.Add)
|
newNode.direction = widget.Horizontal
|
||||||
if b {
|
} else {
|
||||||
a.Direction = widget.Horizontal
|
newNode.direction = widget.Vertical
|
||||||
} else {
|
|
||||||
a.Direction = widget.Vertical
|
|
||||||
}
|
|
||||||
sendAction(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parent *Node) NewHorizontalBox(name string) *Node {
|
func (parent *Node) NewHorizontalBox(progname string) *Node {
|
||||||
newNode := parent.newNode(name, widget.Box)
|
newNode := parent.newNode(progname, widget.Box)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
if ! newNode.hidden {
|
newNode.direction = widget.Horizontal
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
a.Direction = widget.Horizontal
|
// inform the toolkits
|
||||||
sendAction(a)
|
sendAction(newNode, widget.Add)
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parent *Node) NewVerticalBox(name string) *Node {
|
func (parent *Node) NewVerticalBox(progname string) *Node {
|
||||||
newNode := parent.newNode(name, widget.Box)
|
newNode := parent.newNode(progname, widget.Box)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
if ! newNode.hidden {
|
newNode.direction = widget.Vertical
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
a.Direction = widget.Vertical
|
// inform the toolkits
|
||||||
sendAction(a)
|
sendAction(newNode, widget.Add)
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
25
button.go
25
button.go
|
@ -8,28 +8,7 @@ func (parent *Node) NewButton(name string, custom func()) *Node {
|
||||||
newNode.value = name
|
newNode.value = name
|
||||||
newNode.progname = name
|
newNode.progname = name
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
// find widget by number
|
|
||||||
func (n *Node) FindId(i int) (*Node) {
|
|
||||||
if (n == nil) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.id == i) {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
newN := child.FindId(i)
|
|
||||||
if (newN != nil) {
|
|
||||||
return newN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,9 +11,7 @@ func (n *Node) NewCheckbox(name string) *Node {
|
||||||
newNode.value = name
|
newNode.value = name
|
||||||
newNode.progname = name
|
newNode.progname = name
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
360
common.go
360
common.go
|
@ -11,79 +11,91 @@ import (
|
||||||
// functions for handling text related GUI elements
|
// functions for handling text related GUI elements
|
||||||
|
|
||||||
func (n *Node) Show() *Node {
|
func (n *Node) Show() *Node {
|
||||||
if ! n.hidden {
|
if ! n.Ready() { return n }
|
||||||
a := newAction(n, widget.Show)
|
if ! n.Hidden() { return n }
|
||||||
sendAction(a)
|
|
||||||
}
|
n.hidden = false
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Show)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Hide() *Node {
|
func (n *Node) Hide() *Node {
|
||||||
if ! n.hidden {
|
if ! n.Ready() { return n }
|
||||||
a := newAction(n, widget.Hide)
|
if n.Hidden() { return n }
|
||||||
sendAction(a)
|
|
||||||
}
|
n.hidden = true
|
||||||
|
n.changed = true
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Hide)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 {
|
func (n *Node) Enable() *Node {
|
||||||
if ! n.hidden {
|
if ! n.Ready() { return n }
|
||||||
a := newAction(n, widget.Enable)
|
// if n.enabled { return n }
|
||||||
sendAction(a)
|
|
||||||
}
|
n.enabled = true
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Enable)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disables a widget so the user can see it, but can not
|
||||||
|
// interact or change it.
|
||||||
func (n *Node) Disable() *Node {
|
func (n *Node) Disable() *Node {
|
||||||
if ! n.hidden {
|
if ! n.Ready() { return n }
|
||||||
a := newAction(n, widget.Disable)
|
// if ! n.enabled { return n }
|
||||||
sendAction(a)
|
|
||||||
}
|
n.enabled = false
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Disable)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Add(str string) {
|
|
||||||
log.Log(GUI, "gui.Add() value =", str)
|
|
||||||
|
|
||||||
n.value = str
|
// add a new text string to widgets that support
|
||||||
|
// multiple string values
|
||||||
if ! n.hidden {
|
// These must be unique. return false if the string already exists
|
||||||
a := newAction(n, widget.Add)
|
func (n *Node) AddText(str string) bool {
|
||||||
sendAction(a)
|
if ! n.Ready() { return false }
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) AddText(str string) {
|
|
||||||
log.Log(CHANGE, "AddText() value =", str)
|
log.Log(CHANGE, "AddText() value =", str)
|
||||||
|
|
||||||
n.value = str
|
n.value = str
|
||||||
|
// TODO: make sure these are unique
|
||||||
|
n.strings = append(n.strings, str)
|
||||||
|
|
||||||
if ! n.hidden {
|
// inform the toolkits
|
||||||
a := newAction(n, widget.AddText)
|
sendAction(n, widget.AddText)
|
||||||
sendAction(a)
|
return true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetNext(w int, h int) {
|
|
||||||
n.NextW = w
|
|
||||||
n.NextH = h
|
|
||||||
log.Info("SetNext() w,h =", n.NextW, n.NextH)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// appends text to the existing text
|
||||||
|
// TODO: this is an experiement
|
||||||
func (n *Node) AppendText(str string) {
|
func (n *Node) AppendText(str string) {
|
||||||
|
if ! n.Ready() { return }
|
||||||
tmp := widget.GetString(n.value) + str
|
tmp := widget.GetString(n.value) + str
|
||||||
n.value = tmp
|
n.value = tmp
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
if ! n.hidden {
|
// inform the toolkits
|
||||||
a := newAction(n, widget.SetText)
|
sendAction(n, widget.SetText)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// THESE TWO FUNCTIONS ARE TERRIBLY NAMED AND NEED TO BE FIXED
|
// THESE TWO FUNCTIONS ARE TERRIBLY NAMED AND NEED TO BE FIXED
|
||||||
// 5 seconds worth of ideas:
|
// 5 seconds worth of ideas:
|
||||||
// Value() ?
|
// Value() ?
|
||||||
// Progname() Reference() ?
|
// Progname() Reference() ?
|
||||||
|
// 2024/01/13 the names are starting to grow on me and make it clearer to code against
|
||||||
|
|
||||||
// get a string from the widget
|
// get a string from the widget
|
||||||
func (n *Node) GetText() string {
|
func (n *Node) GetText() string {
|
||||||
|
@ -104,14 +116,177 @@ func (n *Node) GetBool() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
// should get the reference name used for programming and debugging
|
// should get the reference name used for programming and debugging
|
||||||
// myButton = myGroup.NewButton("hit ball", nil).SetName("HIT")
|
func (n *Node) SetProgName(s string) {
|
||||||
// myButton.GetName() should return "HIT"
|
if ! n.Ready() { return }
|
||||||
// n = Find("HIT") should return myButton
|
|
||||||
func (n *Node) GetName() string {
|
if n.progname == s {
|
||||||
|
// don't do anything since nothing changed
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
n.changed = true
|
||||||
|
n.progname = s
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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
|
return n.progname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func commonCallback(n *Node) {
|
||||||
|
// TODO: make all of this common code to all the widgets
|
||||||
|
// This might be common everywhere finally (2023/03/01)
|
||||||
|
if (n.Custom == nil) {
|
||||||
|
log.Log(CHANGE, "Not Running n.Custom(n) == nil")
|
||||||
|
} else {
|
||||||
|
log.Log(CHANGE, "Running n.Custom(n)")
|
||||||
|
n.Custom()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (n *Node) Margin() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if n.margin { return n }
|
||||||
|
|
||||||
|
n.margin = true
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Margin)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Unmargin() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if ! n.margin { return n }
|
||||||
|
|
||||||
|
n.margin = false
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Unmargin)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Pad() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if n.pad == true { return n } // nothing changed
|
||||||
|
|
||||||
|
n.pad = true
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Pad)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Unpad() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if n.pad == false { return n } // nothing changed
|
||||||
|
|
||||||
|
n.pad = false
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Unpad)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Expand() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if n.expand == true { return n } // nothing changed
|
||||||
|
|
||||||
|
n.expand = true
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.SetExpand)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) SetExpand(b bool) *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
|
if n.expand == b { return n } // nothing changed
|
||||||
|
|
||||||
|
n.expand = b
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.SetExpand)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the widget currently viewable?
|
||||||
|
func (n *Node) Hidden() bool {
|
||||||
|
if ! n.Ready() { return false }
|
||||||
|
return n.hidden
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Ready() bool {
|
||||||
|
if n == nil {
|
||||||
|
log.Warn("Ready() got node == nil")
|
||||||
|
// TODO: figure out if you can identify the code trace
|
||||||
|
// to help find the root cause
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// DEPRECATE / REDO / SORT OUT THIS STUFF
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
// This should not really do anything. as per the docs, the "Standard()" way
|
||||||
|
// should be the default way
|
||||||
|
/*
|
||||||
|
func (n *Node) Standard() *Node {
|
||||||
|
log.Warn("Standard() not implemented yet")
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) SetMargin() *Node {
|
||||||
|
log.Warn("DoMargin() not implemented yet")
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (n *Node) Window(title string) *Node {
|
||||||
|
log.Warn("Window()", n)
|
||||||
|
return n.NewWindow(title)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (n *Node) Add(str string) {
|
||||||
|
log.Log(GUI, "gui.Add() value =", str)
|
||||||
|
|
||||||
|
n.value = str
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Add)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (n *Node) SetNext(w int, h int) {
|
||||||
|
n.NextW = w
|
||||||
|
n.NextH = h
|
||||||
|
log.Info("SetNext() w,h =", n.NextW, n.NextH)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// string handling examples that might be helpful for normalizeInt()
|
// string handling examples that might be helpful for normalizeInt()
|
||||||
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
||||||
|
@ -145,100 +320,3 @@ func normalizeInt(s string) string {
|
||||||
log.Log(GUI, "normalizeInt() s =", clean)
|
log.Log(GUI, "normalizeInt() s =", clean)
|
||||||
return clean
|
return clean
|
||||||
}
|
}
|
||||||
|
|
||||||
func commonCallback(n *Node) {
|
|
||||||
// TODO: make all of this common code to all the widgets
|
|
||||||
// This might be common everywhere finally (2023/03/01)
|
|
||||||
if (n.Custom == nil) {
|
|
||||||
log.Log(CHANGE, "Not Running n.Custom(n) == nil")
|
|
||||||
} else {
|
|
||||||
log.Log(CHANGE, "Running n.Custom(n)")
|
|
||||||
n.Custom()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Margin() *Node {
|
|
||||||
n.margin = true
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Margin)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Unmargin() *Node {
|
|
||||||
n.margin = false
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Unmargin)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Pad() *Node {
|
|
||||||
n.pad = true
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Pad)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Unpad() *Node {
|
|
||||||
n.pad = false
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Unpad)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Expand() *Node {
|
|
||||||
n.expand = true
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Pad)
|
|
||||||
a.Expand = true
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
// is this better?
|
|
||||||
// yes, this is better. it allows Internationalization very easily
|
|
||||||
// me.window = myGui.New2().Window("DNS and IPv6 Control Panel").Standard()
|
|
||||||
// myFunnyWindow = myGui.NewWindow("Hello").Standard().SetText("Hola")
|
|
||||||
|
|
||||||
/*
|
|
||||||
func (n *Node) Window(title string) *Node {
|
|
||||||
log.Warn("Window()", n)
|
|
||||||
return n.NewWindow(title)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (n *Node) ProgName() string {
|
|
||||||
if ! n.Ready() { return "" }
|
|
||||||
return n.progname
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Ready() bool {
|
|
||||||
if n == nil {
|
|
||||||
log.Warn("Ready() got node == nil")
|
|
||||||
// TODO: figure out if you can identify the code trace to help find the root cause
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// This should not really do anything. as per the docs, the "Standard()" way
|
|
||||||
// should be the default way
|
|
||||||
/*
|
|
||||||
func (n *Node) Standard() *Node {
|
|
||||||
log.Warn("Standard() not implemented yet")
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) SetMargin() *Node {
|
|
||||||
log.Warn("DoMargin() not implemented yet")
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
6
debug.go
6
debug.go
|
@ -38,10 +38,8 @@ func (n *Node) Dump() {
|
||||||
}
|
}
|
||||||
Indent(b, "NODE DUMP END")
|
Indent(b, "NODE DUMP END")
|
||||||
|
|
||||||
a := new(widget.Action)
|
n.changed = true
|
||||||
a.ActionType = widget.Dump
|
sendAction(n, widget.Dump)
|
||||||
a.WidgetId = n.id
|
|
||||||
sendAction(a)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Indent(b bool, a ...interface{}) {
|
func Indent(b bool, a ...interface{}) {
|
||||||
|
|
33
dropdown.go
33
dropdown.go
|
@ -6,41 +6,38 @@ package gui
|
||||||
// since it is the same. confusing names? maybe...
|
// since it is the same. confusing names? maybe...
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
// add a new entry to the dropdown name
|
// add a new entry to the dropdown name
|
||||||
func (n *Node) AddDropdownName(name string) {
|
func (n *Node) AddDropdownName(name string) {
|
||||||
|
if ! n.Ready() { return }
|
||||||
|
log.Warn("AddDropdownName() deprecated")
|
||||||
n.AddText(name)
|
n.AddText(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the dropdown menu to 'name'
|
// Set the dropdown menu to 'name'
|
||||||
func (n *Node) SetDropdownName(name string) {
|
func (n *Node) SetDropdownName(name string) {
|
||||||
|
if ! n.Ready() { return }
|
||||||
|
log.Warn("SetDropdownName() deprecated")
|
||||||
n.SetText(name)
|
n.SetText(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) NewDropdown(name string) *Node {
|
func (n *Node) NewDropdown(progname string) *Node {
|
||||||
newNode := n.newNode(name, widget.Dropdown)
|
newNode := n.newNode(progname, widget.Dropdown)
|
||||||
newNode.progname = name
|
newNode.progname = progname
|
||||||
newNode.value = name
|
|
||||||
|
|
||||||
if ! newNode.hidden {
|
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) NewCombobox(name string) *Node {
|
func (n *Node) NewCombobox(progname string) *Node {
|
||||||
newNode := n.newNode(name, widget.Combobox)
|
newNode := n.newNode(progname, widget.Combobox)
|
||||||
newNode.progname = name
|
newNode.progname = progname
|
||||||
newNode.value = name
|
|
||||||
|
|
||||||
if ! newNode.hidden {
|
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
15
grid.go
15
grid.go
|
@ -33,21 +33,20 @@ type GridOffset struct {
|
||||||
Y int
|
Y int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) NewGrid(name string, w int, h int) *Node {
|
func (n *Node) NewGrid(progname string, w int, h int) *Node {
|
||||||
newNode := n.newNode(name, widget.Grid)
|
newNode := n.newNode(progname, widget.Grid)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
newNode.W = w
|
newNode.W = w
|
||||||
newNode.H = h
|
newNode.H = h
|
||||||
newNode.NextW = 1
|
newNode.NextW = 1
|
||||||
newNode.NextH = 1
|
newNode.NextH = 1
|
||||||
|
|
||||||
if ! newNode.hidden {
|
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// by default, always pad grids
|
// by default, always pad grids
|
||||||
newNode.Pad()
|
newNode.pad = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
11
group.go
11
group.go
|
@ -13,14 +13,7 @@ func (parent *Node) NewGroup(name string) *Node {
|
||||||
newNode.progname = name
|
newNode.progname = name
|
||||||
newNode.value = name
|
newNode.value = name
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
// by default, always pad groups
|
|
||||||
newNode.Pad()
|
|
||||||
|
|
||||||
// newBox := newNode.NewBox("defaultGroupBox", false)
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
9
image.go
9
image.go
|
@ -1,6 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -8,9 +9,9 @@ func (parent *Node) NewImage(name string) *Node {
|
||||||
var newNode *Node
|
var newNode *Node
|
||||||
newNode = parent.newNode(name, widget.Image)
|
newNode = parent.newNode(name, widget.Image)
|
||||||
|
|
||||||
if ! newNode.hidden {
|
log.Warn("NewImage() not implemented. fix this")
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
sendAction(a)
|
// inform the toolkits
|
||||||
}
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
6
label.go
6
label.go
|
@ -9,9 +9,7 @@ func (parent *Node) NewLabel(text string) *Node {
|
||||||
newNode.value = text
|
newNode.value = text
|
||||||
newNode.progname = text
|
newNode.progname = text
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
38
main.go
38
main.go
|
@ -19,7 +19,7 @@ func init() {
|
||||||
log.Log(NOW, "init() has been run")
|
log.Log(NOW, "init() has been run")
|
||||||
|
|
||||||
me.counter = 0
|
me.counter = 0
|
||||||
me.prefix = "wit"
|
// me.prefix = "wit"
|
||||||
|
|
||||||
// Populates the top of the binary tree
|
// Populates the top of the binary tree
|
||||||
me.rootNode = addNode()
|
me.rootNode = addNode()
|
||||||
|
@ -38,30 +38,50 @@ func init() {
|
||||||
go watchCallback()
|
go watchCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// lookup the widget by the id sent from the toolkit
|
||||||
|
func (n *Node) findId(i int) (*Node) {
|
||||||
|
if (n == nil) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n.id == i) {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, child := range n.children {
|
||||||
|
newN := child.findId(i)
|
||||||
|
if (newN != nil) {
|
||||||
|
return newN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func watchCallback() {
|
func watchCallback() {
|
||||||
log.Info("watchCallback() START")
|
log.Info("guiChan() START")
|
||||||
for {
|
for {
|
||||||
log.Info("watchCallback() restarted select for toolkit user events")
|
log.Info("guiChan() restarted")
|
||||||
select {
|
select {
|
||||||
case a := <-me.guiChan:
|
case a := <-me.guiChan:
|
||||||
if (a.ActionType == widget.UserQuit) {
|
if (a.ActionType == widget.UserQuit) {
|
||||||
log.Info("doUserEvent() User sent Quit()")
|
log.Warn("guiChan() User sent Quit()")
|
||||||
me.rootNode.doCustom()
|
me.rootNode.doCustom()
|
||||||
log.Exit("wit/gui toolkit.UserQuit")
|
log.Exit("wit/gui toolkit.UserQuit")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (a.ActionType == widget.EnableDebug) {
|
if (a.ActionType == widget.EnableDebug) {
|
||||||
log.Warn("doUserEvent() Enable Debugging Window")
|
log.Warn("guiChan() Enable Debugging Window")
|
||||||
log.Warn("doUserEvent() TODO: not implemented")
|
log.Warn("guiChan() TODO: not implemented")
|
||||||
// DebugWindow()
|
// DebugWindow()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n := me.rootNode.FindId(a.WidgetId)
|
n := me.rootNode.findId(a.WidgetId)
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
log.Warn("watchCallback() UNKNOWN widget id =", a.WidgetId, a.ProgName)
|
log.Warn("guiChan() UNKNOWN widget id")
|
||||||
|
log.Warn("id =", a.WidgetId, a.ProgName)
|
||||||
} else {
|
} else {
|
||||||
log.Info("watchCallback() FOUND widget id =", n.id, n.progname)
|
log.Verbose("guiChan() FOUND widget id =", n.id, n.progname)
|
||||||
n.doUserEvent(a)
|
n.doUserEvent(a)
|
||||||
}
|
}
|
||||||
// this maybe a good idea?
|
// this maybe a good idea?
|
||||||
|
|
17
node.go
17
node.go
|
@ -7,14 +7,26 @@ import (
|
||||||
|
|
||||||
/*
|
/*
|
||||||
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
|
||||||
|
|
||||||
|
there isn't much to see here.
|
||||||
*/
|
*/
|
||||||
func (n *Node) newNode(title string, t widget.WidgetType) *Node {
|
func (n *Node) newNode(title string, t widget.WidgetType) *Node {
|
||||||
var newN *Node
|
var newN *Node
|
||||||
|
|
||||||
newN = addNode()
|
newN = addNode()
|
||||||
|
newN.progname = title
|
||||||
newN.value = title
|
newN.value = title
|
||||||
newN.WidgetType = t
|
newN.WidgetType = t
|
||||||
|
|
||||||
|
// set these defaults
|
||||||
|
newN.expand = true
|
||||||
|
newN.pad = true
|
||||||
|
newN.enabled = true
|
||||||
|
newN.changed = true
|
||||||
|
|
||||||
if n.WidgetType == widget.Grid {
|
if n.WidgetType == widget.Grid {
|
||||||
n.gridIncrement()
|
n.gridIncrement()
|
||||||
}
|
}
|
||||||
|
@ -28,7 +40,7 @@ func (n *Node) newNode(title string, t widget.WidgetType) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
raw create function for a new node struct
|
raw create function for a new node struct and increments the counter
|
||||||
*/
|
*/
|
||||||
func addNode() *Node {
|
func addNode() *Node {
|
||||||
n := new(Node)
|
n := new(Node)
|
||||||
|
@ -40,10 +52,13 @@ func addNode() *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Parent() *Node {
|
func (n *Node) Parent() *Node {
|
||||||
|
if ! n.Ready() { return n }
|
||||||
return n.parent
|
return n.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Delete(d *Node) {
|
func (n *Node) Delete(d *Node) {
|
||||||
|
if ! n.Ready() { return }
|
||||||
|
|
||||||
for i, child := range n.children {
|
for i, child := range n.children {
|
||||||
log.Log(NODE, "\t", i, child.id, child.progname)
|
log.Log(NODE, "\t", i, child.id, child.progname)
|
||||||
if (child.id == d.id) {
|
if (child.id == d.id) {
|
||||||
|
|
42
plugin.go
42
plugin.go
|
@ -214,48 +214,6 @@ func initToolkit(name string, filename string) *aplug {
|
||||||
return newPlug
|
return newPlug
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2024/01/11 finally moving to type any. simplify to just 'value'
|
|
||||||
// 2023/05/09 pretty clean
|
|
||||||
// 2023/04/06 Queue() is also being used and channels are being used.
|
|
||||||
func newAction(n *Node, atype widget.ActionType) *widget.Action {
|
|
||||||
var a widget.Action
|
|
||||||
a.ActionType = atype
|
|
||||||
if (n == nil) {
|
|
||||||
return &a
|
|
||||||
}
|
|
||||||
a.WidgetId = n.id
|
|
||||||
a.ProgName = n.progname
|
|
||||||
a.Value = n.value
|
|
||||||
|
|
||||||
a.X = n.X
|
|
||||||
a.Y = n.Y
|
|
||||||
|
|
||||||
a.AtW = n.AtW
|
|
||||||
a.AtH = n.AtH
|
|
||||||
|
|
||||||
if (n.parent != nil) {
|
|
||||||
a.ParentId = n.parent.id
|
|
||||||
}
|
|
||||||
a.WidgetType = n.WidgetType
|
|
||||||
return &a
|
|
||||||
}
|
|
||||||
|
|
||||||
// sends the action/event to each toolkit via a golang plugin channel
|
|
||||||
func sendAction(a *widget.Action) {
|
|
||||||
for _, aplug := range allPlugins {
|
|
||||||
log.Log(PLUG, "Action() aplug =", aplug.name, "Action type=", a.ActionType)
|
|
||||||
if (aplug.pluginChan == nil) {
|
|
||||||
log.Info("Action() retrieving the aplug.PluginChannel()", aplug.name)
|
|
||||||
aplug.pluginChan = aplug.PluginChannel()
|
|
||||||
log.Info("Action() retrieved", aplug.pluginChan)
|
|
||||||
}
|
|
||||||
log.Info("Action() SEND to pluginChan", aplug.name)
|
|
||||||
aplug.pluginChan <- *a
|
|
||||||
// added during debugging. might be a good idea in general for a tactile experience
|
|
||||||
log.Sleep(.02) // this delay makes it so SetText() works on initial widget creation
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) InitEmbed(resFS embed.FS) *Node {
|
func (n *Node) InitEmbed(resFS embed.FS) *Node {
|
||||||
me.resFS = resFS
|
me.resFS = resFS
|
||||||
return n
|
return n
|
||||||
|
|
69
setText.go
69
setText.go
|
@ -3,64 +3,55 @@ package gui
|
||||||
// Common actions for widgets like 'Enable' or 'Hide'
|
// Common actions for widgets like 'Enable' or 'Hide'
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *Node) SetText(text string) *Node {
|
func (n *Node) SetText(text string) *Node {
|
||||||
if ! n.Ready() { return n }
|
if ! n.Ready() { return n }
|
||||||
|
|
||||||
|
if n.GetText() == text {
|
||||||
|
// nothing changed
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
n.value = text
|
||||||
|
n.changed = true
|
||||||
log.Log(CHANGE, "SetText() value =", text)
|
log.Log(CHANGE, "SetText() value =", text)
|
||||||
|
|
||||||
n.value = text
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.SetText)
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.SetText)
|
|
||||||
a.Value = n.value
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
func (n *Node) Set(val any) {
|
||||||
func convertString(val any) string {
|
if ! n.Ready() { return }
|
||||||
|
|
||||||
switch v := val.(type) {
|
switch v := val.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
n.B = val.(bool)
|
if widget.GetBool(n.value) == val.(bool) {
|
||||||
|
// nothing changed
|
||||||
|
return
|
||||||
|
}
|
||||||
case string:
|
case string:
|
||||||
n.label = val.(string)
|
if widget.GetString(n.value) == val.(string) {
|
||||||
n.S = val.(string)
|
// nothing changed
|
||||||
|
return
|
||||||
|
}
|
||||||
case int:
|
case int:
|
||||||
n.I = val.(int)
|
if widget.GetInt(n.value) == val.(int) {
|
||||||
|
// nothing changed
|
||||||
|
return
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
log.Error(errors.New("Set() unknown type"), "v =", v)
|
log.Error(errors.New("Set() unknown type"), "v =", v)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
n.value = val
|
||||||
func (n *Node) Set(val any) {
|
n.changed = true
|
||||||
log.Log(CHANGE, "Set() value =", val)
|
log.Log(CHANGE, "Set() value =", val)
|
||||||
|
|
||||||
n.value = val
|
// inform the toolkits
|
||||||
/*
|
sendAction(n, widget.Set)
|
||||||
n.value = val
|
|
||||||
|
|
||||||
switch v := val.(type) {
|
|
||||||
case bool:
|
|
||||||
n.B = val.(bool)
|
|
||||||
case string:
|
|
||||||
n.label = val.(string)
|
|
||||||
n.S = val.(string)
|
|
||||||
case int:
|
|
||||||
n.I = val.(int)
|
|
||||||
default:
|
|
||||||
log.Error(errors.New("Set() unknown type"), "v =", v)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ! n.hidden {
|
|
||||||
a := newAction(n, widget.Set)
|
|
||||||
a.Value = n.value
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
15
slider.go
15
slider.go
|
@ -5,21 +5,18 @@ import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSlider(name string, x int, y int) *Node {
|
func (parent *Node) NewSlider(progname string, x int, y int) *Node {
|
||||||
newNode := parent.newNode(name, widget.Slider)
|
newNode := parent.newNode(progname, widget.Slider)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log.Log(GUI, "even newer clicker() name in NewSlider name =", name)
|
log.Log(GUI, "even newer clicker() name in NewSlider name =", progname)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.X = x
|
newNode.X = x
|
||||||
newNode.Y = y
|
newNode.Y = y
|
||||||
if ! newNode.hidden {
|
|
||||||
a := newAction(newNode, widget.Add)
|
|
||||||
a.X = x
|
|
||||||
a.Y = y
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(newNode, widget.Add)
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
13
spinner.go
13
spinner.go
|
@ -5,19 +5,18 @@ import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSpinner(name string, x int, y int) *Node {
|
func (parent *Node) NewSpinner(progname string, x int, y int) *Node {
|
||||||
newNode := parent.newNode(name, widget.Spinner)
|
newNode := parent.newNode(progname, widget.Spinner)
|
||||||
|
newNode.progname = progname
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log.Info("default NewSpinner() change", name)
|
log.Info("default NewSpinner() change", progname)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.X = x
|
newNode.X = x
|
||||||
newNode.Y = y
|
newNode.Y = y
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
71
structs.go
71
structs.go
|
@ -27,14 +27,15 @@ var me guiConfig
|
||||||
// almost all toolkits use integers so there doesn't
|
// almost all toolkits use integers so there doesn't
|
||||||
// seem to be a good idea to use 'type any' here as it
|
// seem to be a good idea to use 'type any' here as it
|
||||||
// just makes things more complicated for no good reason
|
// just makes things more complicated for no good reason
|
||||||
type Range struct {
|
type RangeMovedToWidget struct {
|
||||||
Low int
|
Low int
|
||||||
High int
|
High int
|
||||||
}
|
}
|
||||||
|
|
||||||
type List []string
|
// type List []string
|
||||||
|
|
||||||
type guiConfig struct {
|
type guiConfig struct {
|
||||||
|
// a toolkit requirement. never allow more than one per program
|
||||||
initOnce sync.Once
|
initOnce sync.Once
|
||||||
|
|
||||||
// This is the master node. The Binary Tree starts here
|
// This is the master node. The Binary Tree starts here
|
||||||
|
@ -52,28 +53,69 @@ type guiConfig struct {
|
||||||
resFS embed.FS
|
resFS embed.FS
|
||||||
|
|
||||||
// used to beautify logging to Stdout
|
// used to beautify logging to Stdout
|
||||||
depth int
|
// depth int
|
||||||
prefix string
|
// prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Node is a binary tree. This is how all GUI elements are stored
|
/*
|
||||||
// simply the name and the size of whatever GUI element exists
|
The Node is a binary tree. This is how all GUI elements are stored
|
||||||
|
simply the name and the size of whatever GUI element exists
|
||||||
|
|
||||||
|
value : most widgets need 1 value. this is it.
|
||||||
|
For a window -- the title. For a button -- the name
|
||||||
|
|
||||||
|
hidden : this means the widget is not displayed yet. In that
|
||||||
|
case, don't waste time trying to pass information to
|
||||||
|
the toolkits. This makes things efficient and fast if
|
||||||
|
the GUI does not have to display anything
|
||||||
|
|
||||||
|
Custom() : if the user does something like click on a button,
|
||||||
|
this function will be called. (this should probably
|
||||||
|
be renamed Callback()
|
||||||
|
|
||||||
|
progname : a short name to reference the widgets in the debugger
|
||||||
|
n.NewButton("click here to send it").SetProgName("SENT")
|
||||||
|
|
||||||
|
parent, children : the binary tree
|
||||||
|
|
||||||
|
pad, margin, expand : re-think these names and clarify
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
id int // should be unique
|
id int // should be unique
|
||||||
hidden bool // Sierpinski Carpet mode. It's there, but you can't see it.
|
hidden bool // don't update the toolkits when it's hidden
|
||||||
pad bool // the toolkit may use this. it's up to the toolkit
|
changed bool // do we need to inform the toolkit something changed?
|
||||||
margin bool // the toolkit may use this. it's up to the toolkit
|
enabled bool // if false, then the the user can't click on it
|
||||||
expand bool // the toolkit may use this. it's up to the toolkit
|
|
||||||
|
|
||||||
WidgetType widget.WidgetType
|
WidgetType widget.WidgetType
|
||||||
|
|
||||||
// the current widget value.
|
// most widgets need one value, this is current alue
|
||||||
value any
|
value any
|
||||||
|
|
||||||
// this can programatically identify the widget
|
// this can programatically identify the widget
|
||||||
// The name must be unique
|
// 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 []string
|
||||||
|
|
||||||
|
// how to arrange widgets
|
||||||
|
direction widget.Orientation
|
||||||
|
|
||||||
|
// this function is run when there are mouse or keyboard events
|
||||||
|
Custom func()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
// used for Windows in toolkits measured in pixels
|
// used for Windows in toolkits measured in pixels
|
||||||
width int
|
width int
|
||||||
height int
|
height int
|
||||||
|
@ -95,11 +137,4 @@ type Node struct {
|
||||||
// if this widget is in a grid, this is the position of a widget
|
// if this widget is in a grid, this is the position of a widget
|
||||||
AtW int
|
AtW int
|
||||||
AtH int
|
AtH int
|
||||||
|
|
||||||
|
|
||||||
// this function is run when there are mouse or keyboard events
|
|
||||||
Custom func()
|
|
||||||
|
|
||||||
parent *Node
|
|
||||||
children []*Node
|
|
||||||
}
|
}
|
||||||
|
|
16
textbox.go
16
textbox.go
|
@ -8,20 +8,22 @@ import (
|
||||||
|
|
||||||
func (parent *Node) NewTextbox(name string) *Node {
|
func (parent *Node) NewTextbox(name string) *Node {
|
||||||
newNode := parent.newNode(name, widget.Textbox)
|
newNode := parent.newNode(name, widget.Textbox)
|
||||||
|
newNode.value = name
|
||||||
|
newNode.progname = name
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log.Log(GUI, "NewTextbox changed =", name)
|
log.Log(GUI, "NewTextbox changed =", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (parent *Node) NewEntryLine(name string) *Node {
|
func (parent *Node) NewEntryLine(name string) *Node {
|
||||||
newNode := parent.newNode(name, widget.Textbox)
|
newNode := parent.newNode(name, widget.Textbox)
|
||||||
|
newNode.value = name
|
||||||
|
newNode.progname = name
|
||||||
|
|
||||||
newNode.X = 1
|
newNode.X = 1
|
||||||
|
|
||||||
|
@ -29,9 +31,7 @@ func (parent *Node) NewEntryLine(name string) *Node {
|
||||||
log.Log(GUI, "NewTextbox changed =", name)
|
log.Log(GUI, "NewTextbox changed =", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
43
window.go
43
window.go
|
@ -18,10 +18,8 @@ func (parent *Node) NewWindow(title string) *Node {
|
||||||
newNode.progname = title
|
newNode.progname = title
|
||||||
newNode.value = title
|
newNode.value = title
|
||||||
|
|
||||||
if ! newNode.hidden {
|
// inform the toolkits
|
||||||
a := newAction(newNode, widget.Add)
|
sendAction(newNode, widget.Add)
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,26 +38,51 @@ func (parent *Node) RawWindow(title string) *Node {
|
||||||
|
|
||||||
// TODO: should do this recursively
|
// TODO: should do this recursively
|
||||||
func (n *Node) UnDraw() *Node {
|
func (n *Node) UnDraw() *Node {
|
||||||
if ! n.hidden {
|
if ! n.Ready() { return n }
|
||||||
n.Hide()
|
|
||||||
}
|
|
||||||
n.hidden = true
|
n.hidden = true
|
||||||
|
n.changed = true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Delete)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: should do this recursively
|
// TODO: should do this recursively
|
||||||
func (n *Node) Draw() *Node {
|
func (n *Node) Draw() *Node {
|
||||||
n.hidden = false
|
if ! n.Ready() { return n }
|
||||||
|
|
||||||
a := newAction(n, widget.Add)
|
n.hidden = false
|
||||||
sendAction(a)
|
n.changed= true
|
||||||
|
|
||||||
|
// inform the toolkits
|
||||||
|
sendAction(n, widget.Add)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the toolkit supports a gui with pixels, it might honor this. no promises
|
// if the toolkit supports a gui with pixels, it might honor this. no promises
|
||||||
// consider this a 'recommendation' or developer 'preference' to the toolkit
|
// consider this a 'recommendation' or developer 'preference' to the toolkit
|
||||||
|
/*
|
||||||
func (n *Node) PixelSize(w, h int) *Node {
|
func (n *Node) PixelSize(w, h int) *Node {
|
||||||
n.width = w
|
n.width = w
|
||||||
n.height = w
|
n.height = w
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (n *Node) TestDraw() {
|
||||||
|
if (n == nil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable and
|
||||||
|
n.hidden = false
|
||||||
|
n.changed = true
|
||||||
|
log.Warn("TestDraw() sending widget.Add", n.id, n.WidgetType, n.progname)
|
||||||
|
sendAction(n, widget.Add)
|
||||||
|
|
||||||
|
for _, child := range n.children {
|
||||||
|
child.TestDraw()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue