var value any

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-01-11 19:32:40 -06:00
parent 828a6af020
commit e2958fe561
17 changed files with 160 additions and 84 deletions

View File

@ -20,8 +20,8 @@ endif
redomod:
rm -f go.*
go mod init
go mod tidy
GO111MODULE= go mod init
GO111MODULE= go mod tidy
# should update every go dependancy (?)
update:

28
box.go
View File

@ -6,10 +6,36 @@ import (
func (parent *Node) NewBox(name string, b bool) *Node {
newNode := parent.newNode(name, widget.Box)
newNode.B = b
if ! newNode.hidden {
a := newAction(newNode, widget.Add)
if b {
a.Direction = widget.Horizontal
} else {
a.Direction = widget.Vertical
}
sendAction(a)
}
return newNode
}
func (parent *Node) NewHorizontalBox(name string) *Node {
newNode := parent.newNode(name, widget.Box)
if ! newNode.hidden {
a := newAction(newNode, widget.Add)
a.Direction = widget.Horizontal
sendAction(a)
}
return newNode
}
func (parent *Node) NewVerticalBox(name string) *Node {
newNode := parent.newNode(name, widget.Box)
if ! newNode.hidden {
a := newAction(newNode, widget.Add)
a.Direction = widget.Vertical
sendAction(a)
}
return newNode

View File

@ -5,6 +5,8 @@ import "go.wit.com/gui/widget"
func (parent *Node) NewButton(name string, custom func()) *Node {
newNode := parent.newNode(name, widget.Button)
newNode.Custom = custom
newNode.value = name
newNode.progname = name
if ! newNode.hidden {
a := newAction(newNode, widget.Add)

View File

@ -3,11 +3,13 @@ package gui
import "go.wit.com/gui/widget"
func (n *Node) Checked() bool {
return n.B
return widget.GetBool(n.value)
}
func (n *Node) NewCheckbox(name string) *Node {
newNode := n.newNode(name, widget.Checkbox)
newNode.value = name
newNode.progname = name
if ! newNode.hidden {
a := newAction(newNode, widget.Add)

View File

@ -45,7 +45,7 @@ func (n *Node) Disable() *Node {
func (n *Node) Add(str string) {
log.Log(GUI, "gui.Add() value =", str)
n.S = str
n.value = str
if ! n.hidden {
a := newAction(n, widget.Add)
@ -56,8 +56,7 @@ func (n *Node) Add(str string) {
func (n *Node) AddText(str string) {
log.Log(CHANGE, "AddText() value =", str)
n.Text = str
n.S = str
n.value = str
if ! n.hidden {
a := newAction(n, widget.AddText)
@ -72,9 +71,8 @@ func (n *Node) SetNext(w int, h int) {
}
func (n *Node) AppendText(str string) {
tmp := n.S + str
n.Text = tmp
n.S = tmp
tmp := widget.GetString(n.value) + str
n.value = tmp
if ! n.hidden {
a := newAction(n, widget.SetText)
@ -87,26 +85,31 @@ func (n *Node) AppendText(str string) {
// Value() ?
// Progname() Reference() ?
// should get the value of the node
// get a string from the widget
func (n *Node) GetText() string {
if n.value != nil {
return n.value.(string)
}
if (n.S != n.Text) {
log.Warn("GetText() is screwed up. TODO: fix this dumb crap. n.S =", n.S, "and n.Text =", n.Text)
}
if (n.S != "") {
return n.S
}
return n.Text
if ! n.Ready() { return "" }
return widget.GetString(n.value)
}
// should get the value of the node
// get a string from the widget
func (n *Node) GetInt() int {
if ! n.Ready() { return -1 }
return widget.GetInt(n.value)
}
// get a string from the widget
func (n *Node) GetBool() bool {
if ! n.Ready() { return false}
return widget.GetBool(n.value)
}
// should get the reference name used for programming and debugging
// myButton = myGroup.NewButton("hit ball", nil).SetName("HIT")
// myButton.GetName() should return "HIT"
// n = Find("HIT") should return myButton
func (n *Node) GetName() string {
return n.Name
if ! n.Ready() { return "" }
return n.progname
}
/*
@ -205,10 +208,17 @@ func (n *Node) Expand() *Node {
// 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 {

View File

@ -21,7 +21,7 @@ func (n *Node) Dump() {
b := true
Indent(b, "NODE DUMP START")
Indent(b, "id = ", n.id)
Indent(b, "Name = ", n.Name)
Indent(b, "progname = ", n.progname)
Indent(b, "(X,Y) = ", n.X, n.Y)
Indent(b, "Next (W,H) = ", n.NextW, n.NextH)
@ -57,7 +57,7 @@ func (n *Node) dumpWidget(b bool) string {
}
info = n.WidgetType.String()
d = strconv.Itoa(n.id) + " " + info + " " + n.Name
d = strconv.Itoa(n.id) + " " + info + " " + n.progname
var tabs string
for i := 0; i < listChildrenDepth; i++ {
@ -86,8 +86,8 @@ func (n *Node) ListChildren(dump bool) {
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.Name)
log.Log(NOW, "listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
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")
}

View File

@ -21,6 +21,8 @@ func (n *Node) SetDropdownName(name string) {
func (n *Node) NewDropdown(name string) *Node {
newNode := n.newNode(name, widget.Dropdown)
newNode.progname = name
newNode.value = name
if ! newNode.hidden {
a := newAction(newNode, widget.Add)
@ -32,6 +34,8 @@ func (n *Node) NewDropdown(name string) *Node {
func (n *Node) NewCombobox(name string) *Node {
newNode := n.newNode(name, widget.Combobox)
newNode.progname = name
newNode.value = name
if ! newNode.hidden {
a := newAction(newNode, widget.Add)

10
grid.go
View File

@ -23,6 +23,16 @@ import (
// -- (1,3) -- -- (3,3) --
// -----------------------------
type Grid struct {
Width int
Height int
}
type GridOffset struct {
X int
Y int
}
func (n *Node) NewGrid(name string, w int, h int) *Node {
newNode := n.newNode(name, widget.Grid)

View File

@ -10,6 +10,8 @@ import (
func (parent *Node) NewGroup(name string) *Node {
var newNode *Node
newNode = parent.newNode(name, widget.Group)
newNode.progname = name
newNode.value = name
if ! newNode.hidden {
a := newAction(newNode, widget.Add)

View File

@ -6,6 +6,8 @@ import (
func (parent *Node) NewLabel(text string) *Node {
newNode := parent.newNode(text, widget.Label)
newNode.value = text
newNode.progname = text
if ! newNode.hidden {
a := newAction(newNode, widget.Add)

38
main.go
View File

@ -58,9 +58,9 @@ func watchCallback() {
n := me.rootNode.FindId(a.WidgetId)
if (n == nil) {
log.Warn("watchCallback() UNKNOWN widget id =", a.WidgetId, a.Name)
log.Warn("watchCallback() UNKNOWN widget id =", a.WidgetId, a.ProgName)
} else {
log.Info("watchCallback() FOUND widget id =", n.id, n.Name)
log.Info("watchCallback() FOUND widget id =", n.id, n.progname)
n.doUserEvent(a)
}
// this maybe a good idea?
@ -71,7 +71,7 @@ func watchCallback() {
}
func (n *Node) doCustom() {
log.Info("doUserEvent() widget =", n.id, n.Name, n.WidgetType, n.B)
log.Info("doUserEvent() widget =", n.id, n.progname, n.WidgetType)
if (n.Custom == nil) {
log.Warn("Custom() = nil. SKIPPING")
return
@ -80,47 +80,49 @@ func (n *Node) doCustom() {
}
func (n *Node) doUserEvent(a widget.Action) {
log.Info("doUserEvent() node =", n.id, n.Name)
if a.A != nil {
log.Warn("doUserEvent() a.A != nil", n.id, n.Name, "n.value =", a.A)
n.value = a.A
n.doCustom()
log.Info("doUserEvent() node =", n.id, n.progname)
if a.Value == nil {
log.Warn("doUserEvent() a.A == nil", n.id, n.progname)
return
}
n.value = a.Value
n.doCustom()
return
/*
switch n.WidgetType {
case widget.Checkbox:
n.B = a.B
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.B)
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.value)
n.doCustom()
case widget.Button:
log.Info("doUserEvent() node =", n.id, n.Name, "button clicked")
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.Name, "set to:", n.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.Name, "set to:", n.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.Name, "set to:", n.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.Name, "set to:", n.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.Name, "set to:", n.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.Name, "window closed")
log.Info("doUserEvent() node =", n.id, n.progname, "window closed")
n.doCustom()
default:
log.Info("doUserEvent() type =", n.WidgetType)
}
*/
}
// There should only be one of these per application
@ -154,7 +156,7 @@ func (n *Node) Default() *Node {
// The window is destroyed but the application does not quit
func (n *Node) StandardClose() {
log.Log(GUI, "wit/gui Standard Window Close. name =", n.Name)
log.Log(GUI, "wit/gui Standard Window Close. name =", n.progname)
log.Log(GUI, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
}

View File

@ -31,8 +31,7 @@ func (n *Node) newNode(title string, t widget.WidgetType) *Node {
*/
func addNode(title string) *Node {
n := new(Node)
n.Name = title
n.Text = title
n.label = title
n.id = me.counter
log.Log(NODE, "addNode = widget setid =", n.id)
@ -46,12 +45,12 @@ func (n *Node) Parent() *Node {
func (n *Node) Delete(d *Node) {
for i, child := range n.children {
log.Log(NODE, "\t", i, child.id, child.Name)
log.Log(NODE, "\t", i, child.id, child.progname)
if (child.id == d.id) {
log.Log(NODE, "\t\t Deleting this")
n.children = append(n.children[:i], n.children[i+1:]...)
return
}
}
log.Warn("did not find node to delete", d.id, d.Name)
log.Warn("did not find node to delete", d.id, d.progname)
}

View File

@ -214,21 +214,18 @@ func initToolkit(name string, filename string) *aplug {
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. memcopy() only
// 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.Name = n.Name
a.Text = n.Text
a.WidgetId = n.id
a.B = n.B
a.I = n.I
a.S = n.S
a.ProgName = n.progname
a.Value = n.value
a.X = n.X
a.Y = n.Y

View File

@ -21,12 +21,12 @@ func (n *Node) redraw(p *aplug) {
}
func (n *Node) redo(plug *aplug) {
log.Info("redo()", plug.name, n.id, n.WidgetType, n.Name)
log.Info("redo()", plug.name, n.id, n.WidgetType, n.progname)
var a *widget.Action
a = new(widget.Action)
a.Name = n.Name
a.Text = n.Text
a.ProgName = n.progname
a.Value = n.value
a.ActionType = widget.Add
a.WidgetType = n.WidgetType
@ -40,11 +40,6 @@ func (n *Node) redo(plug *aplug) {
a.AtW = n.AtW
a.AtH = n.AtH
// used for values
a.I = n.I
a.S = n.S
a.B = n.B
if (n.parent == nil) {
a.ParentId = 0
} else {

View File

@ -3,8 +3,6 @@ package gui
// Common actions for widgets like 'Enable' or 'Hide'
import (
"errors"
"go.wit.com/log"
"go.wit.com/gui/widget"
)
@ -17,32 +15,52 @@ func (n *Node) SetText(text string) *Node {
if ! n.hidden {
a := newAction(n, widget.SetText)
a.A = n.value
a.Value = n.value
sendAction(a)
}
return n
}
func (n *Node) Set(val any) {
log.Log(CHANGE, "Set() value =", val)
n.value = val
/*
func convertString(val any) string {
switch v := val.(type) {
case bool:
n.B = val.(bool)
case string:
n.Text = val.(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)
}
}
*/
func (n *Node) Set(val any) {
log.Log(CHANGE, "Set() value =", val)
n.value = val
/*
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.A = val
a.Value = n.value
sendAction(a)
}
}

View File

@ -15,7 +15,7 @@ import (
// Native Windows and MacOS toolkits
//
// If that is the case, this code abstracts the concept of
// windows and makes each window a 'tabs' in a single window.
// windows and makes each window a 'tab' in a single window.
//
// Reminder from Goals: This is for simple GUI's.
// For example, a "Mouse Control Panel" not the GIMP or blender.
@ -23,6 +23,17 @@ import (
var me guiConfig
// Range(1, 10) includes the values 1 and 10
// almost all toolkits use integers so there doesn't
// seem to be a good idea to use 'type any' here as it
// just makes things more complicated for no good reason
type Range struct {
Low int
High int
}
type List []string
type guiConfig struct {
initOnce sync.Once
@ -56,13 +67,12 @@ type Node struct {
WidgetType widget.WidgetType
// for NewLabel("hello"), Text = 'hello'
Text string // what is visable to the user
// the current widget value.
value any
// for NewLabel("hello"), if Name = 'HELLO'
// this can programatically identify the widget
// The name must be unique
Name string // a name useful for debugging
progname string // a name useful for debugging
// used for Windows in toolkits measured in pixels
width int
@ -86,11 +96,6 @@ type Node struct {
AtW int
AtH int
// the current widget value.
I int
S string
B bool
value any
// this function is run when there are mouse or keyboard events
Custom func()

View File

@ -15,6 +15,8 @@ func (parent *Node) NewWindow(title string) *Node {
newNode.Custom = StandardExit
log.Info("NewWindow()", title)
newNode.progname = title
newNode.value = title
if ! newNode.hidden {
a := newAction(newNode, widget.Add)