Squashed commit of the following:

boxes now exist and are tracked in the binary tree
    create for group and grid works
    gocui plugin no longer works. TODO: fix in next release
    converted everything from plugin to Action()
        can remove send()
        tab and window are now action()
        flags moved to action()
    ready for new release
    pad() margion() border() all work
    move worked!
    go.wit.com attept 578th try
    adds an early grid widget. won't work until chan
        andlabs/ui grid (X,Y) works right
        actually can put things in places in a grid
        Queue() means shit doesn't look right on grids
    lots of fucking around. why am I wasting time on image?
    wow. the crazy doAppend() thing is gone
    implement Action Show() and Hide()

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-03-23 12:35:12 -05:00
parent 18c131868c
commit fa356841bf
58 changed files with 1867 additions and 1391 deletions

View File

@ -145,7 +145,7 @@ var WARN bool
## Functions
### func [DebugWidgetWindow](/debugWidget.go#L56)
### func [DebugWidgetWindow](/debugWidget.go#L52)
`func DebugWidgetWindow(w *Node)`
@ -155,19 +155,15 @@ var WARN bool
Creates a window helpful for debugging this package
### func [Delete](/common.go#L90)
### func [Indent](/debug.go#L130)
`func Delete(c *Node)`
### func [Indent](/debug.go#L116)
`func Indent(a ...interface{})`
`func Indent(b bool, a ...interface{})`
### func [InitPlugins](/main.go#L56)
`func InitPlugins(names []string)`
### func [LoadToolkit](/plugin.go#L43)
### func [LoadToolkit](/plugin.go#L46)
`func LoadToolkit(name string) bool`
@ -190,15 +186,15 @@ other goroutines. This is due to the nature of how
Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
For example: gui.Queue(NewWindow())
### func [SetDebug](/debug.go#L26)
### func [SetDebug](/debug.go#L28)
`func SetDebug(s bool)`
### func [SetFlag](/debug.go#L42)
### func [SetFlag](/debug.go#L44)
`func SetFlag(s string, b bool)`
### func [ShowDebugValues](/debug.go#L75)
### func [ShowDebugValues](/debug.go#L86)
`func ShowDebugValues()`

View File

@ -4,6 +4,13 @@ import "git.wit.org/wit/gui/toolkit"
func (n *Node) NewButton(name string, custom func()) *Node {
newNode := n.New(name, toolkit.Button, custom)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

90
chan.go Normal file
View File

@ -0,0 +1,90 @@
package gui
// channel communication to the plugins
// https://github.com/sourcegraph/conc
// https://www.reddit.com/r/golang/comments/11x1oek/hello_gophers_show_me_your_concurrent_code/
import (
// "regexp"
// "git.wit.org/wit/gui/toolkit"
"sync"
"github.com/sourcegraph/conc"
"github.com/sourcegraph/conc/stream"
)
func makeConc() {
var wg conc.WaitGroup
defer wg.Wait()
startTheThing(&wg)
}
func startTheThing(wg *conc.WaitGroup) {
wg.Go(func() {
log(debugNow, "startTheThing()")
})
}
func mapStream(
in chan int,
out chan int,
f func(int) int,
) {
tasks := make(chan func())
taskResults := make(chan chan int)
// Worker goroutines
var workerWg sync.WaitGroup
for i := 0; i < 10; i++ {
workerWg.Add(1)
go func() {
defer workerWg.Done()
for task := range tasks {
task()
}
}()
}
// Ordered reader goroutines
var readerWg sync.WaitGroup
readerWg.Add(1)
go func() {
defer readerWg.Done()
for result := range taskResults {
item := <-result
out <- item
}
}()
// Feed the workers with tasks
for elem := range in {
resultCh := make(chan int, 1)
taskResults <- resultCh
tasks <- func() {
resultCh <- f(elem)
}
}
// We've exhausted input.
// Wait for everything to finish
close(tasks)
workerWg.Wait()
close(taskResults)
readerWg.Wait()
}
func mapStream2(
in chan int,
out chan int,
f func(int) int,
) {
s := stream.New().WithMaxGoroutines(10)
for elem := range in {
elem := elem
s.Go(func() stream.Callback {
res := f(elem)
return func() { out <- res }
})
}
s.Wait()
}

View File

@ -3,12 +3,18 @@ package gui
import "git.wit.org/wit/gui/toolkit"
func (n *Node) Checked() bool {
n.Dump()
return n.widget.B
}
func (n *Node) NewCheckbox(name string) *Node {
newNode := n.New(name, toolkit.Checkbox, nil)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a, newNode, n)
newaction(&a, newNode, n)
return newNode
}

View File

@ -20,21 +20,10 @@ var args struct {
}
func main() {
// this implements ./cmd --gui-debug --gui-toolkit, etc
arg.MustParse(&args)
// fmt.Println(args.Foo, args.Bar, args.User)
log.Println("Toolkit = ", args.Toolkit)
/*
f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}
defer f.Close()
log.SetOutput(f)
log.Println("This is a test log entry")
*/
// gui.InitPlugins([]string{"andlabs"})
gui.Main(initGUI)
}
@ -52,32 +41,40 @@ func initGUI() {
log.Println("myDefaultExit(w)")
myDefaultExit(w)
}
w.Dump()
addDemoTab(w, "A Simple Tab Demo")
addDemoTab(w, "A Second Tab")
if (args.GuiDebug) {
gui.DebugWindow()
gui.DebugWindow()
}
if (args.GuiVerbose) {
gui.SetDebug(true)
gui.SetDebug(true)
}
}
func addDemoTab(window *gui.Node, title string) {
var newNode, g, g2, tb *gui.Node
var newNode, g *gui.Node
newNode = window.NewTab(title)
log.Println("addDemoTab() newNode.Dump")
newNode.Dump()
log.Println("addDemoTab() newNode START")
// newNode.Dump(true)
g = newNode.NewGroup("group 1")
dd := g.NewDropdown("demoCombo2")
g1 := g.NewGrid("grid 1", 2, 2)
g1.NewLabel("less")
dd := g1.NewDropdown("more")
dd.AddDropdownName("more 1")
dd.AddDropdownName("more 2")
dd.AddDropdownName("more 3")
g2 = newNode.NewGroup("group 2")
tb = g2.NewTextbox("tb")
g.SetNext(3,1)
g1.NewLabel("label (3,1)")
g.SetNext(3,2)
g1.NewLabel("label (3,2)")
g2 := newNode.NewGroup("group 2")
tb := g2.NewTextbox("tb")
log.Println("tb =", tb.GetText())
tb.Custom = func() {
s := tb.GetText()

119
common.go
View File

@ -1,52 +1,112 @@
package gui
// Common actions for widgets like 'Enable' or 'Hide'
import (
"regexp"
// "errors"
// "git.wit.org/wit/gui/toolkit"
"git.wit.org/wit/gui/toolkit"
)
// functions for handling text related GUI elements
func (n *Node) Show() {
var a toolkit.Action
a.Type = toolkit.Show
newaction(&a, n, nil)
}
func (n *Node) Hide() {
var a toolkit.Action
a.Type = toolkit.Hide
newaction(&a, n, nil)
}
func (n *Node) Enable() {
var a toolkit.Action
a.Type = toolkit.Enable
newaction(&a, n, nil)
}
func (n *Node) Disable() {
var a toolkit.Action
a.Type = toolkit.Disable
newaction(&a, n, nil)
}
func (n *Node) Add(str string) {
log(debugGui, "gui.Add() value =", str)
n.widget.Action = "Add"
n.widget.S = str
send(n.parent, n)
var a toolkit.Action
a.Type = toolkit.Add
a.S = str
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
}
func (n *Node) SetText(str string) bool {
log(debugChange, "gui.SetText() value =", str)
n.widget.Action = "SetText"
n.widget.S = str
send(n.parent, n)
return true
func (n *Node) AddText(str string) {
log(debugChange, "AddText() value =", str)
var a toolkit.Action
a.Type = toolkit.AddText
a.S = str
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
}
func (n *Node) Set(a any) bool {
log(debugChange, "gui.Set() value =", a)
n.widget.Action = "Set"
switch v := a.(type) {
func (n *Node) SetText(str string) {
log(debugChange, "SetText() value =", str)
var a toolkit.Action
a.Type = toolkit.SetText
a.S = str
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
}
func (n *Node) SetNext(x int, y int) {
n.NextX = x
n.NextY = y
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
log(debugError, "SetNext() x,y =", n.NextX, n.NextY)
}
func (n *Node) Set(val any) {
log(debugChange, "Set() value =", val)
var a toolkit.Action
a.Type = toolkit.Set
switch v := val.(type) {
case bool:
n.widget.B = a.(bool)
a.B = val.(bool)
case string:
n.widget.S = a.(string)
a.S = val.(string)
case int:
n.widget.I = a.(int)
a.I = val.(int)
default:
log(debugError, "gui.Set() unknown type =", v, "a =", a)
log(debugError, "Set() unknown type =", v, "a =", a)
}
send(n.parent, n)
return true
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
}
func (n *Node) AppendText(str string) bool {
n.widget.Action = "Set"
func (n *Node) AppendText(str string) {
var a toolkit.Action
a.Type = toolkit.SetText
tmp := n.widget.S + str
log(debugChange, "gui.AppendText() value =", tmp)
n.widget.S = tmp
send(n.parent, n)
return true
log(debugChange, "AppendText() value =", tmp)
a.S = tmp
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
}
func (n *Node) GetText() string {
@ -87,11 +147,6 @@ func normalizeInt(s string) string {
return clean
}
func Delete(c *Node) {
c.widget.Action = "Delete"
send(c.parent, c)
}
func commonCallback(n *Node) {
// TODO: make all of this common code to all the widgets
// This might be common everywhere finally (2023/03/01)

25
debian/index.html vendored Normal file
View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>go.wit.com/gui</title>
<meta name="go-import" content="go.wit.com/gui git https://github.com/wit-go/gui">
<meta name="go-source" content="go.wit.com/gui https://github.com/wit-go/gui https://github.com/wit-go/gui/tree/master{/dir} https://github.com/wit-go/gui/blob/master{/dir}/{file}#L{line}">
<style>
* { font-family: sans-serif; }
body { margin-top: 0; }
.content { display: inline-block; }
code { display: block; font-family: monospace; font-size: 1em; background-color: #d5d5d5; padding: 1em; margin-bottom: 16px; }
ul { margin-top: 16px; margin-bottom: 16px; }
</style>
</head>
<body>
<div class="content">
<h2>go.wit.com/gui</h2>
<code>go get -v go.wit.com/gui</code>
<code>import "go.wit.com/gui"</code>
Home: <a href="https://godoc.org/go.wit.com/gui">https://godoc.org/go.wit.com/gui</a><br/>
Source: <a href="https://github.com/wit-go/gui">https://github.com/wit-go/gui</a><br/>
</div>
</body>
</html>

View File

@ -9,14 +9,16 @@ import (
)
// various debugging flags
var debugNow bool = true // useful for active development
var debugGui bool = false
var debugError bool = false
var debugError bool = true
var debugDump bool = false
var debugNode bool = false
var debugTabs bool = false
var debugFlags bool = false
var debugChange bool = false // shows user events like mouse and keyboard
var debugPlugin bool = false
var debugAction bool = false
// for printing out the binary tree
var listChildrenParent *Node
@ -64,12 +66,21 @@ func SetFlag (s string, b bool) {
}
// send the flag to the toolkit
n := Config.flag
log(debugChange, "Set() toolkit flag", s, "to", b)
n.widget.Action = "Set"
n.widget.S = s
n.widget.B = b
send(nil, n)
// n := Config.flag
// log(debugChange, "Set() toolkit flag", s, "to", b)
// n.widget.Action = "Set"
// n.widget.S = s
// n.widget.B = b
// send(nil, n) // set flag in the plugin
var a toolkit.Action
a.Type = toolkit.SetFlag
a.S = s
a.B = b
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, nil, nil)
}
func ShowDebugValues() {
@ -86,40 +97,47 @@ func ShowDebugValues() {
SetFlag("Show", true)
}
func (n *Node) Dump() {
if ! debugDump {
func (n *Node) Dump(b bool) {
// log("Dump() dump =", b)
if ! b {
return
}
Indent("NODE DUMP START")
Indent("id = ", n.id)
Indent("Name = ", n.Name)
Indent("Width = ", n.Width)
Indent("Height = ", n.Height)
Indent("Widget Name = ", n.widget.Name)
Indent("Widget Type = ", n.widget.Type)
Indent("Widget Id = ", n.widget.GetId())
Indent(b, "NODE DUMP START")
Indent(b, "id = ", n.id)
Indent(b, "Name = ", n.Name)
Indent(b, "Width = ", n.Width)
Indent(b, "Height = ", n.Height)
Indent(b, "(X,Y) = ", n.X, n.Y)
Indent(b, "Next (X,Y) = ", n.NextX, n.NextY)
Indent(b, "Widget Name = ", n.widget.Name)
Indent(b, "Widget Type = ", n.widget.Type)
Indent(b, "Widget Id = ", n.widget.GetId())
if (n.parent == nil) {
Indent("parent = nil")
Indent(b, "parent = nil")
} else {
Indent("parent.id =", n.parent.id)
Indent(b, "parent.id =", n.parent.id)
}
if (n.children != nil) {
Indent("children = ", n.children)
Indent(b, "children = ", n.children)
}
if (n.Custom != nil) {
Indent("Custom = ", n.Custom)
Indent(b, "Custom = ", n.Custom)
}
Indent("NODE DUMP END")
Indent(b, "NODE DUMP END")
}
func Indent(a ...interface{}) {
logindent(listChildrenDepth, defaultPadding, a...)
func Indent(b bool, a ...interface{}) {
logindent(b, listChildrenDepth, defaultPadding, a...)
}
func (n *Node) dumpWidget() string {
func (n *Node) dumpWidget(b bool) string {
var info, d string
if (n == nil) {
log(debugError, "dumpWidget() node == nil")
return ""
}
info = n.widget.Type.String()
info += ", " + n.widget.Name
@ -137,22 +155,18 @@ func (n *Node) dumpWidget() string {
tabs = tabs + defaultPadding
}
d = tabs + d
logindent(listChildrenDepth, defaultPadding, n.id, info)
logindent(b, listChildrenDepth, defaultPadding, n.id, info)
return d
}
func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
s := n.dumpWidget()
if (dropdown != nil) {
dropdown.AddDropdownName(s)
if (mapNodes != nil) {
mapNodes[s] = n
}
// func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
func (n *Node) ListChildren(dump bool) {
if (n == nil) {
return
}
if (dump == true) {
n.Dump()
}
n.dumpWidget(dump)
// n.Dump(dump)
if len(n.children) == 0 {
if (n.parent == nil) {
return
@ -161,7 +175,9 @@ func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node
if (listChildrenParent != nil) {
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
if (listChildrenParent.id != n.parent.id) {
// log("parent.child does not match child.parent")
log("parent =",n.parent.id, n.parent.Name)
log("listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
log(listChildrenParent.id, "!=", n.parent.id)
exit("parent.child does not match child.parent")
}
}
@ -177,9 +193,7 @@ func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node
// 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 (dump == true) {
child.Dump()
}
child.Dump(debugDump)
if (child.children == nil) {
log(debugNode, "\t\t", child.id, "has no children")
} else {
@ -187,7 +201,8 @@ func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node
}
listChildrenParent = n
listChildrenDepth += 1
child.ListChildren(dump, dropdown, mapNodes)
// child.ListChildren(dump, dropdown, mapNodes)
child.ListChildren(dump)
listChildrenDepth -= 1
}
return

View File

@ -33,50 +33,59 @@ func (n *Node) DebugFlags(makeWindow bool) {
})
g = w.NewGroup("List")
g = g.NewGrid("flags grid", 2, 2)
// generally useful debugging
cb1 := g.NewCheckbox("debug Gui (like verbose=1)")
cb1 := g.NewCheckbox("debug Gui")
g.NewLabel("like verbose=1")
cb1.Custom = func() {
debugGui = cb1.widget.B
log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B)
}
// errors. by default these always output somewhere
cbE := g.NewCheckbox("debug Error (bad things. default=true)")
cbE := g.NewCheckbox("debug Error")
g.NewLabel("(bad things. default=true)")
cbE.Custom = func() {
SetFlag("Error", cbE.widget.B)
}
// debugging that will show you things like mouse clicks, user inputing text, etc
// also set toolkit.DebugChange
cb2 := g.NewCheckbox("debug Change (keyboard and mouse events)")
cb2 := g.NewCheckbox("debug Change")
g.NewLabel("keyboard and mouse events")
cb2.Custom = func() {
SetFlag("Change", cb2.widget.B)
}
// supposed to tell if you are going to dump full variable output
cb3 := g.NewCheckbox("debug Dump (show lots of output)")
cb3 := g.NewCheckbox("debug Dump")
g.NewLabel("show lots of output")
cb3.Custom = func() {
SetFlag("Dump", cbE.widget.B)
}
cb4 := g.NewCheckbox("debug Tabs (tabs and windows)")
cb4 := g.NewCheckbox("debug Tabs")
g.NewLabel("tabs and windows")
cb4.Custom = func() {
SetFlag("Tabs", cb4.widget.B)
}
cb6 := g.NewCheckbox("debug Node (the binary tree)")
cb6 := g.NewCheckbox("debug Node")
g.NewLabel("the binary tree)")
cb6.Custom = func() {
SetFlag("Plugin", cb6.widget.B)
SetFlag("Node", cb6.widget.B)
}
// should show you when things go into or come back from the plugin
cb5 := g.NewCheckbox("debug Plugin (plugin interaction)")
cb5 := g.NewCheckbox("debug Plugin")
g.NewLabel("plugin interaction)")
cb5.Custom = func() {
SetFlag("Plugin", cb5.widget.B)
}
// turns on debugging inside the plugin toolkit
cb7 := g.NewCheckbox("debug Toolkit (the plugin internals)")
cb7 := g.NewCheckbox("debug Toolkit")
g.NewLabel("the plugin internals)")
cb7.Custom = func() {
// SetDebugToolkit(cb7.widget.B)
SetFlag("Toolkit", cb7.widget.B)

View File

@ -26,7 +26,6 @@ func (n *Node) DebugGoChannels(makeWindow bool) {
} else {
w = n.NewTab("Chan")
}
w.Dump()
g = w.NewGroup("Channel stuff")

View File

@ -24,7 +24,6 @@ func (n *Node) DebugGolangWindow(makeWindow bool) {
} else {
w = n.NewTab("GOLANG")
}
w.Dump()
g = w.NewGroup("Language Internals")

View File

@ -13,9 +13,18 @@ var bugWidget *Node
// the widget all these actions are run against
var activeWidget *Node
// for testing move, this is the node things are put on
var activeJunk *Node
// the label where the user can see which widget is active
var activeLabel *Node
var activeLabelType *Node
var activeLabelNewName *Node
var activeLabelNewType *Node
var activeLabelNewX *Node
var activeLabelNewY *Node
var activeLabelNewB *Node
// tmp junk
var debugGrid *Node
@ -37,19 +46,6 @@ func setActiveWidget(w *Node) {
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name
activeLabel.SetText(title)
activeLabelType.SetText("widget.Type = " + w.widget.Type.String())
// temporary stuff
if (w.widget.Type == toolkit.Window) {
debugWidgetBut1.widget.Action = "Enable"
send(debugWidgetBut1.parent, debugWidgetBut1)
debugWidgetBut2.widget.Action = "Enable"
send(debugWidgetBut2.parent, debugWidgetBut2)
} else {
debugWidgetBut1.widget.Action = "Disable"
send(debugWidgetBut1.parent, debugWidgetBut1)
debugWidgetBut2.widget.Action = "Disable"
send(debugWidgetBut2.parent, debugWidgetBut2)
}
return
}
@ -75,108 +71,113 @@ func DebugWidgetWindow(w *Node) {
g := bugWidget.NewGroup("widget:")
activeLabel = g.NewLabel("undef")
activeLabelType = g.NewLabel("undef")
g2 := g.NewGroup("widget:")
activeLabel = g2.NewLabel("undef")
g2 = g.NewGroup("type:")
activeLabelType = g2.NewLabel("undef")
g2 = g.NewGroup("New name:")
activeLabelNewName = g2.NewCombobox("newthing")
activeLabelNewName.AddText("penguin")
activeLabelNewName.AddText("snow")
activeLabelNewName.AddText("GO")
activeLabelNewName.AddText("debian")
activeLabelNewName.AddText("RiscV")
g2 = g.NewGroup("At X:")
activeLabelNewX = g2.NewSpinner("tmp spinner", -1, 100)
g2 = g.NewGroup("At Y:")
activeLabelNewY = g2.NewSpinner("tmp spinner", -1, 100)
g2 = g.NewGroup("bool B:")
activeLabelNewB = g2.NewCheckbox("tmp bool")
// common things that should work against each widget
g = bugWidget.NewGroup("common things")
g.NewButton("Disable()", func () {
activeWidget.widget.Action = "Disable"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Enable()", func () {
activeWidget.widget.Action = "Enable"
send(activeWidget.parent, activeWidget)
activeWidget.Enable()
})
g.NewButton("Disable()", func () {
activeWidget.Disable()
})
g.NewButton("Show()", func () {
activeWidget.widget.Action = "Show"
send(activeWidget.parent, activeWidget)
activeWidget.Show()
})
g.NewButton("Hide()", func () {
activeWidget.widget.Action = "Hide"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Delete()", func () {
Delete(activeWidget)
activeWidget.Hide()
})
g.NewButton("Dump()", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
activeWidget.Dump()
debugGui = g
debugDump = d
activeWidget.Dump(true)
var a toolkit.Action
a.Type = toolkit.Dump
newaction(&a, activeWidget, nil)
})
newG := bugWidget.NewGroup("add things")
newG.debugAddWidgetButtons()
g = bugWidget.NewGroup("add things")
g.debugAddWidgetButton()
g.NewLabel("experiments:")
g.debugAddWidgetButtons()
g = bugWidget.NewGroup("change things")
g.NewButton("SetMargin(true)", func () {
activeWidget.widget.Action = "SetMargin"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
g.NewButton("AddText()", func () {
var a toolkit.Action
a.Type = toolkit.AddText
a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
})
g.NewButton("SetMargin(false)", func () {
activeWidget.widget.Action = "SetMargin"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
g.NewButton("SetText()", func () {
var a toolkit.Action
a.Type = toolkit.SetText
a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
})
g.NewButton("Value()", func () {
log("activeWidget.B =", activeWidget.widget.B)
log("activeWidget.I =", activeWidget.widget.I)
log("activeWidget.S =", activeWidget.widget.S)
g.NewButton("Margin()", func () {
var a toolkit.Action
a.Type = toolkit.Margin
newaction(&a, activeWidget, nil)
})
g.NewButton("Set(true)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
g.NewButton("Unmargin()", func () {
var a toolkit.Action
a.Type = toolkit.Unmargin
newaction(&a, activeWidget, nil)
})
g.NewButton("Set(false)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
g.NewButton("Pad()", func () {
var a toolkit.Action
a.Type = toolkit.Pad
newaction(&a, activeWidget, nil)
})
g.NewButton("Set(20)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = true
activeWidget.widget.I = 20
activeWidget.widget.S = "20"
send(activeWidget.parent, activeWidget)
g.NewButton("Unpad()", func () {
var a toolkit.Action
a.Type = toolkit.Unpad
newaction(&a, activeWidget, nil)
})
g.NewButton("SetText('foo')", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.S = "foo"
send(activeWidget.parent, activeWidget)
g.NewButton("Move(junk)", func () {
var a toolkit.Action
a.Type = toolkit.Move
newaction(&a, activeWidget, activeJunk)
})
g.NewButton("Delete()", func () {
activeWidget.widget.Action = "Delete"
send(activeWidget.parent, activeWidget)
})
debugWidgetBut1 = g.NewButton("SetRaw(true)", func () {
activeWidget.widget.Action = "SetRaw"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
})
debugWidgetBut2 = g.NewButton("SetRaw(false)", func () {
activeWidget.widget.Action = "SetRaw"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
var a toolkit.Action
a.Type = toolkit.Delete
newaction(&a, activeWidget, activeJunk)
})
g = bugWidget.NewGroup("not working?")
g.NewButton("Add('foo')", func () {
activeWidget.widget.Action = "Add"
activeWidget.widget.S = "foo"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Add button to (1,1)", func () {
activeWidget.widget.Action = "AddGrid"
activeWidget.widget.B = false
send(activeWidget, debugGridLabel)
// debugGrid = gShoactiveWidget.NewGrid("tmp grid", 2, 3)
g.NewButton("Dump Widget Values()", func () {
log("activeWidget.B =", activeWidget.widget.B)
log("activeWidget.I =", activeWidget.widget.I)
log("activeWidget.S =", activeWidget.widget.S)
log("activeWidget.X =", activeWidget.widget.X)
log("activeWidget.Y =", activeWidget.widget.Y)
log("activeWidget.Width =", activeWidget.widget.Width)
log("activeWidget.Height =", activeWidget.widget.Height)
log("activeWidget.Margin =", activeWidget.widget.Margin)
log("activeWidget.Expand =", activeWidget.widget.Expand)
})
activeJunk = bugWidget.NewGroup("junk:")
activeJunk.NewLabel("test junk")
if (activeWidget == nil) {
setActiveWidget(Config.master)
@ -184,53 +185,20 @@ func DebugWidgetWindow(w *Node) {
}
func (n *Node) debugAddWidgetButtons() {
n.NewButton("Button", func () {
a := activeWidget.NewButton("myButton", nil)
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
})
n.NewButton("Checkbox", func () {
a := activeWidget.NewCheckbox("myCheckbox")
a.Custom = func () {
log("custom checkox func a=", a.widget.B, "id=", a.id)
}
})
n.NewButton("Label", func () {
activeWidget.NewLabel("mylabel")
})
n.NewButton("Textbox", func () {
a := activeWidget.NewTextbox("mytext")
a.Custom = func () {
log("custom TextBox() a =", a.widget.S, "id=", a.id)
}
})
n.NewButton("Slider", func () {
a := activeWidget.NewSlider("tmp slider", 10, 55)
a.Custom = func () {
log("custom slider() a =", a.widget.I, "id=", a.id)
}
})
n.NewButton("Spinner", func () {
a := activeWidget.NewSpinner("tmp spinner", 6, 32)
a.Custom = func () {
log("custom spinner() a =", a.widget.I, "id=", a.id)
}
})
n.NewButton("Dropdown", func () {
a := activeWidget.NewDropdown("tmp dropdown")
a.AddDropdownName("this is better than tcl/tk")
a.AddDropdownName("make something for tim")
a.AddDropdownName("for qflow")
a.Add("and for riscv")
a.AddText("this is better than tcl/tk")
a.AddText("make something for tim")
a.AddText("for qflow")
a.AddText("and for riscv")
a.Custom = func () {
log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id)
}
})
n.NewButton("Combobox", func () {
a := activeWidget.NewCombobox("tmp combobox")
a.Add("mirrors.wit.com")
a.Add("go.wit.org")
a.AddText("mirrors.wit.com")
a.AddText("go.wit.org")
a.Custom = func () {
log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id)
}
@ -245,31 +213,121 @@ func (n *Node) debugAddWidgetButtons() {
// SetDebug(true)
debugGrid = activeWidget.NewGrid("tmp grid", 2, 3)
debugGridLabel = debugGrid.NewLabel("mirrors.wit.com")
debugGrid.SetNext(0,1)
debugGrid.NewLabel("foo (0,1)")
debugGrid.SetNext(1,1)
debugGrid.NewLabel("foo (1,1)")
debugGrid.SetNext(2,1)
debugGrid.NewLabel("foo (2,1)")
// SetDebug(false)
DebugWidgetWindow(debugGrid)
})
n.NewButton("Image", func () {
activeWidget.NewImage("image")
})
n.NewButton("Tab", func () {
activeWidget.NewTab("myTab")
})
n.NewButton("Group", func () {
a := activeWidget.NewGroup("myGroup")
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
})
n.NewButton("Box(horizontal)", func () {
a := activeWidget.NewBox("hBox", true)
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
a.NewLabel("hBox")
a.NewLabel("hBox 2")
})
n.NewButton("Box(vertical)", func () {
a := activeWidget.NewBox("vBox", true)
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
a := activeWidget.NewBox("vBox", false)
a.NewLabel("vBox")
a.NewLabel("vBox 2")
})
}
func (n *Node) debugAddWidgetButton() {
activeLabelNewType = n.NewDropdown("tmp dropdown")
activeLabelNewType.AddText("Window")
activeLabelNewType.AddText("Tab")
activeLabelNewType.AddText("Frame")
activeLabelNewType.AddText("Grid")
activeLabelNewType.AddText("Group")
activeLabelNewType.AddText("Box")
activeLabelNewType.AddText("Button")
activeLabelNewType.AddText("Checkbox")
activeLabelNewType.AddText("Dropdown")
activeLabelNewType.AddText("Combobox")
activeLabelNewType.AddText("Label")
activeLabelNewType.AddText("Textbox")
activeLabelNewType.AddText("Slider")
activeLabelNewType.AddText("Spinner")
activeLabelNewType.AddText("Image")
activeLabelNewType.AddText("Area")
activeLabelNewType.AddText("Form")
activeLabelNewType.AddText("Font")
activeLabelNewType.AddText("Color")
activeLabelNewType.AddText("Dialog")
n.NewButton("Add", func () {
name := activeLabelNewName.widget.S
newX := activeLabelNewX.widget.I
newY := activeLabelNewY.widget.I
newB := activeLabelNewB.widget.B
if (newY == -1) {
name = name + " (" + strconv.Itoa(activeWidget.NextX) + "," + strconv.Itoa(activeWidget.NextY) + ")"
} else {
activeWidget.SetNext(newX, newY)
name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")"
}
log("New Name =", name)
log("New Type =", activeLabelNewType.widget.S)
log("New X =", newX)
log("New Y =", newY)
log("activeWidget.NextX =", activeWidget.NextX)
log("activeWidget.NextY =", activeWidget.NextY)
log(debugNow, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (X,Y) =", activeWidget.NextX, activeWidget.NextY)
activeWidget.Dump(true)
// activeWidget.widget.X = newX
// activeWidget.widget.Y = newY
switch activeLabelNewType.widget.S {
case "Grid":
activeWidget.NewGrid(name, newX, newY)
case "Group":
activeWidget.NewGroup(name)
case "Box":
activeWidget.NewBox(name, newB)
case "Button":
var n *Node
n = activeWidget.NewButton(name, func () {
log("got to button", name, n.id)
})
case "Checkbox":
a := activeWidget.NewCheckbox(name)
a.Custom = func () {
log("custom checkox func a=", a.widget.B, "id=", a.id)
}
case "Dropdown":
a := activeWidget.NewDropdown(name)
a.AddText(name + " yay")
a.AddText(name + " haha")
a.Custom = func () {
log("WTF a=", a.widget.B, "id=", a.id)
}
case "Combobox":
a := activeWidget.NewCombobox(name)
a.AddText(name + " foo")
a.AddText(name + " bar")
case "Label":
newNode := activeWidget.New(name, toolkit.Label, nil)
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, activeWidget)
// return newNode
// activeWidget.NewLabel(name)
case "Textbox":
activeWidget.NewTextbox(name)
case "Slider":
activeWidget.NewSlider(name, newX, newY)
case "Spinner":
activeWidget.NewSpinner(name, newX, newY)
default:
log(debugError, "make what type?")
}
})
}

View File

@ -1,7 +1,7 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
// "git.wit.org/wit/gui/toolkit"
)
// TODO: move all this shit into somewhere not global
@ -32,7 +32,6 @@ func (n *Node) DebugTab(title string) *Node {
// time.Sleep(1 * time.Second)
newN = n.NewTab(title)
newN.Dump()
//////////////////////// main debug things //////////////////////////////////
gog = newN.NewGroup("Debugging Windows:")
@ -77,23 +76,11 @@ func (n *Node) DebugTab(title string) *Node {
g2 := newN.NewGroup("node things")
g2.NewButton("Node.ListChildren(false)", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
activeWidget.ListChildren(false, nil, nil)
debugGui = g
debugDump = d
})
g2.NewButton("Node.ListChildren(true)", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
activeWidget.ListChildren(true, nil, nil)
debugGui = g
debugDump = d
if (activeWidget == nil) {
activeWidget = Config.master
}
activeWidget.ListChildren(true)
})
return newN
@ -111,14 +98,15 @@ func dropdownWindow(p *Node) {
log("The Window was set to", name)
}
log(debugGui, "dd =", dd)
if (activeWidget == nil) {
// the debug window doesn't exist yet so you can't display the change
// TODO: make a fake binary tree for this(?)
return
}
// var last = ""
for _, child := range Config.master.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
// skip the fake "Flag" node
if (child.widget.Type == toolkit.Flag) {
continue
}
dd.AddDropdownName(child.Name)
// last = child.Name
mapWindows[child.Name] = child
@ -141,5 +129,21 @@ func dropdownWindowWidgets(p *Node) {
}
log(debugGui, "dd =", dd)
activeWidget.ListChildren(true, dd, mapWindows)
// log("dumpWidget() ", b, listChildrenDepth, defaultPadding, n.id, info)
var addDropdowns func (*Node)
addDropdowns = func (n *Node) {
s := n.dumpWidget(true)
dd.AddDropdownName(s)
mapWindows[s] = n
for _, child := range n.children {
listChildrenDepth += 1
addDropdowns(child)
listChildrenDepth -= 1
}
}
// list everything in the binary tree
addDropdowns(Config.master)
}

View File

@ -11,7 +11,7 @@ import (
// add a new entry to the dropdown name
func (n *Node) AddDropdownName(name string) {
n.Add(name)
n.AddText(name)
}
// Set the dropdown menu to 'name'
@ -21,12 +21,26 @@ func (n *Node) SetDropdownName(name string) {
func (n *Node) NewDropdown(name string) *Node {
newNode := n.New(name, toolkit.Dropdown, nil)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}
func (n *Node) NewCombobox(name string) *Node {
newNode := n.New(name, toolkit.Combobox, nil)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

47
grid.go
View File

@ -4,34 +4,43 @@ import (
"git.wit.org/wit/gui/toolkit"
)
// Grid numbering examples (X) or (X,Y)
// ---------
// -- (1) --
// -- (2) --
// ---------
//
// -----------------------------
// -- (1,1) -- (1,2) -- (1,3) --
// -- (2,1) -- (2,2) -- (2,3) --
// -- (3,1) -- -- (2,3) --
// -----------------------------
func (n *Node) NewGrid(name string, x int, y int) *Node {
newNode := n.New(name, toolkit.Grid, func() {
log(debugChange, "click() NewGrid not defined =", name)
})
newNode.widget.X = x
newNode.widget.Y = y
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
a.X = x
a.Y = y
newNode.X = x
newNode.Y = y
newNode.NextX = 1
newNode.NextY = 1
newaction(&a, newNode, n)
return newNode
}
// a box is just a grid with a single set of widgets that are either horizontal or vertical
func (n *Node) NewBox(name string, horizontal bool) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Box, nil)
func (n *Node) NewBox(name string, b bool) *Node {
newNode := n.New(name, toolkit.Box, nil)
newNode.widget.X = 3
newNode.widget.Y = 1
newNode.widget.B = horizontal
var a toolkit.Action
a.Type = toolkit.Add
a.B = b
newaction(&a, newNode, n)
send(n, newNode)
return newNode
}
func (n *Node) AddGrid(a *Node, x int, y int) {
n.widget.X = x
n.widget.Y = y
a.widget.Action = "AddGrid"
send(n, a)
}

View File

@ -4,10 +4,17 @@ import (
"git.wit.org/wit/gui/toolkit"
)
// TODO: treat a "Group" like a "Grid"
// TODO: make a "Group" a "Grid" ?
// probably since right now group is just a
// pre-canned andlabs/ui gtk,macos,windows thing
func (n *Node) NewGroup(name string) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Group, nil)
send(n, newNode)
return newNode
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, n)
newBox := newNode.NewBox("group vBox", false)
return newBox
}

View File

@ -7,6 +7,13 @@ import (
func (n *Node) NewImage(name string) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Image, nil)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

3
int.go
View File

@ -12,6 +12,7 @@ package gui
because technically every interaction with the toolkit has to go through the Queue() goroutine.
Is it "has to go" or "should go"? Probably it makes sense to strictly inforce it. No "callback" functions. IPC only (go channels)
*/
/*
func (n *Node) Int() int {
return n.widget.I
}
@ -23,7 +24,7 @@ func (n *Node) Value() int {
func (n *Node) SetValue(i int) {
log(debugGui, "gui.SetValue() START")
n.Dump()
// FIXME: this needs to be redone
// n.toolkit.SetValue(i)
}
*/

View File

@ -5,10 +5,11 @@ import (
)
func (n *Node) NewLabel(text string) *Node {
newNode := n.New(text, toolkit.Label, func() {
log(debugChange, "TextBox changed", text)
})
newNode := n.New(text, toolkit.Label, nil)
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, n)
send(n, newNode)
return newNode
}

5
log.go
View File

@ -122,7 +122,8 @@ func loggo() {
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
}
func logindent(depth int, format string, a ...any) {
// b bool, print if true
func logindent(b bool, depth int, format string, a ...any) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
@ -133,6 +134,6 @@ func logindent(depth int, format string, a ...any) {
// array prepend(). Why isn't this a standard function. It should be:
// a.prepend(debugGui, newFormat)
a = append([]any{debugGui, newFormat}, a...)
a = append([]any{b, newFormat}, a...)
log(a...)
}

View File

@ -2,7 +2,7 @@ package gui
import (
// "embed"
"git.wit.org/wit/gui/toolkit"
// "git.wit.org/wit/gui/toolkit"
)
// Windows doesn't support plugins. How can I keep andlabs and only compile it on windows?
@ -34,7 +34,7 @@ func init() {
Config.master = addNode("guiBinaryTree")
// used to pass debugging flags to the toolkit plugins
Config.flag = Config.master.New("flag", toolkit.Flag, nil)
Config.flag = Config.master.New("flag", 0, nil)
}
func doGuiChan() {

View File

@ -10,13 +10,12 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
newN = addNode(title)
newN.widget.Type = t
newN.widget.Action = "New"
// newN.widget.Action = "New"
newN.Custom = custom
// TODO: This should not be defined for each widget. This has to be stupid
// or wait a second, is this where I send something to a channel?
newN.widget.Custom = func() {
log(debugChange, "Trying to find Window Close. widget.Action =", newN.widget.Action)
log(debugChange, "Trying to find Window Close. widget.Type =", newN.widget.Type)
if (newN.widget.Type == toolkit.Window) {
log(debugChange, "Need to delete newN here")
@ -64,9 +63,9 @@ func (n *Node) Append(child *Node) {
n.children = append(n.children, child)
if (debugNode) {
log(debugNode, "child node:")
child.Dump()
child.Dump(debugDump)
log(debugNode, "parent node:")
n.Dump()
n.Dump(debugDump)
}
}

115
plugin.go
View File

@ -35,6 +35,9 @@ type aplug struct {
// simplifies passing to the plugin
Send func(*toolkit.Widget, *toolkit.Widget)
// should replace Send()
Action func(*toolkit.Action)
}
var allPlugins []*aplug
@ -78,7 +81,12 @@ func LoadToolkit(name string) bool {
// Sends a widget (button, checkbox, etc) and it's parent widget
// This includes instructions like "Add", "Delete", "Disable", etc
newPlug.Send = loadFunc2(&newPlug, "Send")
// newPlug.Send = loadFunc2(&newPlug, "Send")
// This should replace Send()
// Sends instructions like "Add", "Delete", "Disable", etc
// Sends a widget (button, checkbox, etc) and it's parent widget
newPlug.Action = loadFuncA(&newPlug, "Action")
allPlugins = append(allPlugins, &newPlug)
@ -128,6 +136,27 @@ func loadFunc2(p *aplug, funcName string) func(*toolkit.Widget, *toolkit.Widget)
return newfunc
}
// does this fix loadFuncE problems?
// TODO: still need to move to channels here
func loadFuncA(p *aplug, funcName string) func(*toolkit.Action) {
var newfunc func(*toolkit.Action)
var ok bool
var test plugin.Symbol
test, err = p.plug.Lookup(funcName)
if err != nil {
log(debugGui, "DID NOT FIND: name =", test, "err =", err)
return nil
}
newfunc, ok = test.(func(*toolkit.Action))
if !ok {
log(debugGui, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
return nil
}
return newfunc
}
// This is probably dangerous and should never be done
// executing arbitrary functions will cause them to run inside the goroutine that
// the GUI toolkit itself is running in. TODO: move to channels here
@ -201,15 +230,97 @@ func loadfile(filename string) *plugin.Plugin {
return plug
}
/*
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
func send(p *Node, c *Node) {
for _, aplug := range allPlugins {
log(debugPlugin, "Send() aplug =", aplug.name, "type=", c.widget.Type, "action=", c.widget.Action, "name=", c.widget.Name)
if (aplug.Send == nil) {
log(debugPlugin, "\tSend() failed (aplug.Selete = nil) for", aplug.name)
log(debugPlugin, "Failed. Send() == nil for", aplug.name)
continue
}
aplug.Send(&c.parent.widget, &c.widget)
}
}
*/
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
/*
func action(a *toolkit.Action) {
for _, aplug := range allPlugins {
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.Type)
if (aplug.Action == nil) {
log(debugPlugin, "Failed Action() == nil for", aplug.name)
continue
}
aplug.Action(a)
}
}
*/
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
// THIS COPIES THE WIDGET STRUCT 2023/03/16 as it's not crashing. Queue() is also being used
// never mind that comment. no it doesn't
func newaction(a *toolkit.Action, n *Node, where *Node) {
if (n != nil) {
a.Widget = &n.widget
}
// action(&a, newNode, n)
// newaction(&a, newNode, n)
if (where != nil) {
log(debugGui, "Action() START on where X,Y, Next X,Y =", where.Name, where.X, where.Y, where.NextX, where.NextY)
a.Where = &where.widget
switch where.widget.Type {
case toolkit.Grid:
where.Dump(true)
log(debugGui, "Action() START on Grid (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
//
// fix values here if they are invalid. Index starts at 1
if (where.NextX < 1) {
where.NextX = 1
}
if (where.NextY < 1) {
where.NextY = 1
}
//
a.Where.X = where.NextX
a.Where.Y = where.NextY
log(debugGui, "Action() END on Grid (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
default:
}
}
for _, aplug := range allPlugins {
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.Type)
if (aplug.Action == nil) {
log(debugPlugin, "Failed Action() == nil for", aplug.name)
continue
}
aplug.Action(a)
}
// increment where to put the next widget in a grid or table
if (where != nil) {
switch where.widget.Type {
case toolkit.Grid:
log(debugNow, "Action() START size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
where.NextY += 1
if (where.NextY > where.Y) {
where.NextX += 1
where.NextY = 1
}
log(debugNow, "Action() END size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
where.Name = "jwc gridlaksdfjkl"
where.Width = 320
where.Height = 240
// where.NextX = 5
// where.NextY = 7
where.Dump(true)
default:
}
}
}

View File

@ -8,9 +8,15 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
newNode := n.New(name, toolkit.Slider, func() {
log(debugGui, "even newer clicker() name in NewSlider name =", name)
})
newNode.widget.X = x
newNode.widget.Y = y
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
a.X = x
a.Y = y
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

View File

@ -6,11 +6,17 @@ import (
func (n *Node) NewSpinner(name string, x int, y int) *Node {
newNode := n.New(name, toolkit.Spinner, func() {
log(debugGui, "even newer clicker() name in NewSpinner name =", name)
log(debugChange, "default NewSpinner() change", name)
})
newNode.widget.X = x
newNode.widget.Y = y
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
a.X = x
a.Y = y
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

View File

@ -59,11 +59,25 @@ type Node struct {
widget toolkit.Widget
// deprecate these and use toolkit.Widget
Name string
// used for Windows
Width int
Height int
// used for anything that needs a range
X int
Y int
// used for grids and tables
NextX int
NextY int
// used for values
I int
S string
B bool
// this function is run when there are mouse or keyboard events
Custom func()

5
tab.go
View File

@ -10,6 +10,9 @@ import (
func (n *Node) NewTab(text string) *Node {
newNode := n.New(text, toolkit.Tab, nil)
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, n)
return newNode
}

View File

@ -6,9 +6,15 @@ import (
func (n *Node) NewTextbox(name string) *Node {
newNode := n.New(name, toolkit.Textbox, func() {
log(debugGui, "wit/gui clicker()NewTextBox BUT IS EMPTY. FIXME name =", name)
log(debugGui, "NewTextbox changed =", name)
})
send(n, newNode)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
newaction(&a, newNode, n)
return newNode
}

253
toolkit/andlabs/action.go Normal file
View File

@ -0,0 +1,253 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
func show(w *toolkit.Widget) {
if (w == nil) {
log(debugError, "nil is probably already hidden")
return
}
log(debugError, "show()", w.Name)
t := mapToolkits[w]
if (t == nil) {
log(debugToolkit, "show() toolkit struct == nil. for", w.Name)
return
}
if (w.B) {
t.uiControl.Show()
} else {
t.uiControl.Hide()
}
}
func enable(w *toolkit.Widget) {
if (w == nil) {
log(debugError, "nil is probably already hidden")
return
}
log(debugError, "enable()", w.Name)
t := mapToolkits[w]
if (t == nil) {
log(debugToolkit, "enable() toolkit struct == nil. for", w.Name)
return
}
if (w.B) {
t.uiControl.Enable()
} else {
t.uiControl.Disable()
}
}
func pad(a *toolkit.Action) {
if (a.Widget == nil) {
log(debugError, "pad() ERROR: nil is probably already hidden")
return
}
log(debugError, "pad()", a.Widget.Name)
t := mapToolkits[a.Widget]
if (t == nil) {
log(debugToolkit, "pad() toolkit struct == nil. for", a.Widget.Name)
return
}
switch a.Widget.Type {
case toolkit.Group:
switch a.Type {
case toolkit.Margin:
t.uiGroup.SetMargined(true)
case toolkit.Unmargin:
t.uiGroup.SetMargined(false)
case toolkit.Pad:
t.uiGroup.SetMargined(true)
case toolkit.Unpad:
t.uiGroup.SetMargined(false)
}
case toolkit.Tab:
switch a.Type {
case toolkit.Margin:
tabSetMargined(t.uiTab, true)
case toolkit.Unmargin:
tabSetMargined(t.uiTab, false)
case toolkit.Pad:
tabSetMargined(t.uiTab, true)
case toolkit.Unpad:
tabSetMargined(t.uiTab, false)
}
case toolkit.Window:
switch a.Type {
case toolkit.Margin:
t.uiWindow.SetMargined(true)
case toolkit.Unmargin:
t.uiWindow.SetMargined(false)
case toolkit.Pad:
t.uiWindow.SetBorderless(false)
case toolkit.Unpad:
t.uiWindow.SetBorderless(true)
}
case toolkit.Grid:
switch a.Type {
case toolkit.Margin:
t.uiGrid.SetPadded(true)
case toolkit.Unmargin:
t.uiGrid.SetPadded(false)
case toolkit.Pad:
t.uiGrid.SetPadded(true)
case toolkit.Unpad:
t.uiGrid.SetPadded(false)
}
case toolkit.Box:
switch a.Type {
case toolkit.Margin:
t.uiBox.SetPadded(true)
case toolkit.Unmargin:
t.uiBox.SetPadded(false)
case toolkit.Pad:
t.uiBox.SetPadded(true)
case toolkit.Unpad:
t.uiBox.SetPadded(false)
}
case toolkit.Textbox:
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
default:
log(debugError, "TODO: implement pad() for", a.Type)
}
}
func move(a *toolkit.Action) {
if (a.Where == nil) {
log(debugError, "move() ERROR: can not move to nil")
return
}
if (a.Widget == nil) {
log(debugError, "move() ERROR: can not move nil")
return
}
log(debugNow, "move()", a.Widget.Name, "to", a.Where.Name)
tWidget := mapToolkits[a.Widget]
if (tWidget == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.Widget.Name)
return
}
tWhere := mapToolkits[a.Where]
if (tWhere == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.Where.Name)
return
}
switch a.Where.Type {
case toolkit.Group:
switch a.Type {
case toolkit.Margin:
tWhere.uiGroup.SetMargined(true)
}
case toolkit.Tab:
switch a.Type {
case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true)
}
case toolkit.Window:
switch a.Type {
case toolkit.Pad:
// t.uiWindow.SetBorderless(false)
}
case toolkit.Grid:
switch a.Type {
case toolkit.Pad:
// t.uiGrid.SetPadded(true)
}
case toolkit.Box:
log(debugNow, "TODO: move() for a =", a.Type)
log(debugNow, "TODO: move() where =", a.Where.Type)
log(debugNow, "TODO: move() for widget =", a.Widget.Type)
stretchy = true
tWhere.uiBox.Append(tWidget.uiControl, stretchy)
// log(debugNow, "is there a tWhere parent? =", tWhere.parent)
// tWhere.uiBox.Delete(0)
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
default:
log(debugError, "TODO: need to implement move() for a =", a.Type)
log(debugError, "TODO: need to implement move() for where =", a.Where.Type)
log(debugError, "TODO: need to implement move() for widget =", a.Widget.Type)
}
}
func uiDelete(a *toolkit.Action) {
if (a.Where == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete to nil")
return
}
if (a.Widget == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete nil")
return
}
log(debugNow, "uiDelete()", a.Widget.Name, "to", a.Where.Name)
tWidget := mapToolkits[a.Widget]
if (tWidget == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.Widget.Name)
return
}
tWhere := mapToolkits[a.Where]
if (tWhere == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.Where.Name)
return
}
switch a.Where.Type {
case toolkit.Group:
switch a.Type {
case toolkit.Margin:
tWhere.uiGroup.SetMargined(true)
}
case toolkit.Tab:
switch a.Type {
case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true)
}
case toolkit.Window:
switch a.Type {
case toolkit.Pad:
// t.uiWindow.SetBorderless(false)
}
case toolkit.Grid:
switch a.Type {
case toolkit.Pad:
// t.uiGrid.SetPadded(true)
}
case toolkit.Box:
log(debugNow, "tWidget.boxC =", tWhere.Name)
log(debugNow, "is there a tWhere parent? =", tWhere.parent)
if (tWidget.boxC < 1) {
log(debugNow, "Can not delete from Box. already empty. tWidget.boxC =", tWhere.boxC)
return
}
tWidget.uiBox.Delete(0)
tWidget.boxC -= 1
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
// tWhere.uiBox.Append(tWidget.uiControl, stretchy)
default:
log(debugError, "TODO: need to implement uiDelete() for a =", a.Type)
log(debugError, "TODO: need to implement uiDelete() for where =", a.Where.Type)
log(debugError, "TODO: need to implement uiDelete() for widget =", a.Widget.Type)
}
}

154
toolkit/andlabs/add.go Normal file
View File

@ -0,0 +1,154 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
"git.wit.org/wit/gui/toolkit"
)
func actionDump(b bool, a *toolkit.Action) {
log(b, "dump() Widget.Type =", a.Type)
log(b, "dump() Widget.S =", a.S)
log(b, "dump() Widget.I =", a.I)
log(b, "dump() Widget =", a.Widget)
log(b, "dump() Where =", a.Where)
}
func add(a *toolkit.Action) {
if (a.Widget == nil) {
log(debugError, "add() error. w.Widget == nil")
actionDump(debugError, a)
return
}
// for now, window gets handled without checking where == nil)
if (a.Widget.Type == toolkit.Window) {
doWindow(a)
return
}
t := mapToolkits[a.Where]
if (t == nil) {
// listMap(debugError) // memory corruption?
log(debugError, "add() Widget.Name =", a.Widget.Name, a.Widget.Type)
// log(debugError, "add() Where.Name =", a.Where.Name)
log(debugError, "ERROR add() ERROR a.Where map to t == nil.")
return
}
switch a.Widget.Type {
case toolkit.Window:
doWindow(a)
return
case toolkit.Tab:
doTab(a)
return
case toolkit.Label:
newLabel(a)
return
case toolkit.Button:
newButton(a)
return
case toolkit.Grid:
newGrid(a)
return
case toolkit.Checkbox:
newCheckbox(a)
return
case toolkit.Spinner:
newSpinner(a)
return
case toolkit.Slider:
newSlider(a)
return
case toolkit.Dropdown:
newDropdown(a)
return
case toolkit.Combobox:
newCombobox(a)
return
case toolkit.Textbox:
newTextbox(a)
return
case toolkit.Group:
newGroup(a)
return
case toolkit.Box:
newBox(a)
return
case toolkit.Image:
newImage(a)
return
default:
log(debugError, "add() error TODO: ", a.Widget.Type, a.Widget.Name)
}
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
// Grid numbering examples by (X,Y)
// ---------
// -- (1) --
// -- (2) --
// ---------
//
// -----------------------------
// -- (1,1) -- (1,2) -- (1,3) --
// -- (2,1) -- (2,2) -- (2,3) --
// -----------------------------
// internally for andlabs/ui
// (x&y flipped and start at zero)
// -----------------------------
// -- (0,0) -- (1,0) -- (1,0) --
// -- (0,1) -- (1,1) -- (1,1) --
// -----------------------------
func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
log(debugAction, "place() START", a.Widget.Type, a.Widget.Name)
if (newt.uiControl == nil) {
log(debugError, "place() ERROR uiControl == nil", a.Where.Type, a.Where.Name)
return false
}
switch a.Where.Type {
case toolkit.Grid:
log(debugGrid, "add() Grid try at Where X,Y =", a.Where.X, a.Where.Y)
newt.gridX = a.Where.X
newt.gridY = a.Where.Y
log(debugGrid, "add() Grid try at gridX,gridY", newt.gridX, newt.gridY)
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
t.uiGrid.Append(newt.uiControl,
newt.gridY - 1, newt.gridX - 1, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
return true
case toolkit.Group:
if (t.uiBox == nil) {
t.uiGroup.SetChild(newt.uiControl)
log(debugGrid, "add() hack Group to use this as the box?", a.Widget.Name, a.Widget.Type)
t.uiBox = newt.uiBox
} else {
t.uiBox.Append(newt.uiControl, stretchy)
}
return true
case toolkit.Tab:
t.uiBox.Append(newt.uiControl, stretchy)
t.boxC += 1
return true
case toolkit.Box:
t.uiBox.Append(newt.uiControl, stretchy)
t.boxC += 1
return true
case toolkit.Window:
t.uiWindow.SetChild(newt.uiControl)
return true
default:
log(debugError, "add() how?", a.Where.Type)
}
return false
}

View File

@ -1,103 +0,0 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// move all the append code here
func (t *andlabsT) doAppend(kind toolkit.WidgetType, newt *andlabsT, c *ui.Control) {
if (kind == toolkit.Grid) {
log(debugToolkit, "doAppend() attempt to append a ui.Control into a uiGrid")
// hack to add shit to a grid
button1 := ui.NewButton("a(0,2)")
newt.uiGrid.Append(button1,
0, 2, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
button2 := ui.NewButton("a(1,2)")
newt.uiGrid.Append(button2,
1, 2, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
if (t.uiBox != nil) {
log(debugToolkit, "doAppend() on uiGrid to a uiBox")
if (newt.Name == "output") {
t.uiBox.Append(newt.uiGrid, true)
} else {
t.uiBox.Append(newt.uiGrid, stretchy)
}
return
}
log(debugToolkit, "doAppend() on uiGrid failed")
return
}
if (kind == toolkit.Group) {
log(debugToolkit, "doAppend() attempt a uiGroup")
if (t.uiBox != nil) {
if (newt.Name == "output") {
t.uiBox.Append(newt.uiGroup, true)
} else {
t.uiBox.Append(newt.uiGroup, stretchy)
}
return
}
if (t.uiWindow != nil) {
log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that")
newt.Dump(debugToolkit)
t.uiBox = ui.NewHorizontalBox()
t.uiWindow.SetChild(t.uiBox)
log(debugToolkit, "tried to make a box", t.uiBox)
if (newt.Name == "output") {
log(debugToolkit, "tried to t.uiBox.Append(*c, true)")
if (t.uiBox == nil) {
log(debugToolkit, "tried to t.uiBox.Append(*c, true)")
}
t.uiBox.Append(newt.uiGroup, true)
} else {
log(debugToolkit, "tried to t.uiBox.Append(*c, stretchy)")
t.uiBox.Append(newt.uiGroup, stretchy)
}
return
}
log(debugError, "NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
if (kind == toolkit.Textbox) {
if (t.uiBox == nil) {
log(debugError, "NewTextbox() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
// TODO: temporary hack to make the output textbox 'fullscreen'
if (newt.Name == "output") {
t.uiBox.Append(*c, true)
} else {
t.uiBox.Append(*c, stretchy)
}
return
}
if (t.uiWindow != nil) {
log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that")
t.uiBox = ui.NewHorizontalBox()
t.uiWindow.SetChild(t.uiBox)
log(debugToolkit, "tried to make a box")
if (newt.Name == "output") {
t.uiBox.Append(*c, true)
} else {
t.uiBox.Append(*c, stretchy)
}
return
}
log(debugError, "NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}

View File

@ -1,54 +1,46 @@
package main
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
import (
"git.wit.org/wit/gui/toolkit"
// create a new box
func (t *andlabsT) getBox() *ui.Box {
return t.uiBox
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// make new Box here
func newBox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newBox()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "newBox() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap(debugToolkit)
}
newt := t.rawBox(w.Name, a.B)
newt.boxC = 0
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}
// create a new box
func (t *andlabsT) newBox() *andlabsT {
log(debugToolkit, "newBox() START create default")
t.Dump(debugToolkit)
if (t.uiGroup != nil) {
log(debugToolkit, "\tnewBox() is a Group")
var newTK andlabsT
// make new Box using andlabs/ui
func (t *andlabsT) rawBox(title string, b bool) *andlabsT {
var newt andlabsT
var box *ui.Box
newt.Name = title
vbox := ui.NewVerticalBox()
vbox.SetPadded(padded)
t.uiGroup.SetChild(vbox)
newTK.uiBox = vbox
log(debugToolkit, "rawBox() create", newt.Name)
return &newTK
if (b) {
box = ui.NewHorizontalBox()
} else {
box = ui.NewVerticalBox()
}
if (t.uiBox != nil) {
log(debugToolkit, "\tnewBox() is a Box")
var newTK andlabsT
box.SetPadded(padded)
vbox := ui.NewVerticalBox()
vbox.SetPadded(padded)
t.uiBox.Append(vbox, stretchy)
newTK.uiBox = vbox
newTK.Name = t.Name
newt.uiBox = box
newt.uiControl = box
return &newTK
}
if (t.uiWindow != nil) {
log(debugToolkit, "\tnewBox() is a Window")
var newT andlabsT
vbox := ui.NewVerticalBox()
vbox.SetPadded(padded)
t.uiWindow.SetChild(vbox)
newT.uiBox = vbox
newT.Name = t.Name
// panic("WTF")
return &newT
}
log(debugToolkit, "\tnewBox() FAILED. Couldn't figure out where to make a box")
t.Dump(debugToolkit)
return nil
return &newt
}

View File

@ -7,24 +7,23 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
func newButton(a *toolkit.Action) {
var t, newt *andlabsT
var b *ui.Button
w := a.Widget
log(debugToolkit, "newButton()", w.Name)
t = mapToolkits[parentW]
t = mapToolkits[a.Where]
if (t == nil) {
log(debugToolkit, "newButton() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newButton() toolkit struct == nil. name=", a.Where.Name, w.Name)
return
}
if t.broken() {
return
}
newt = new(andlabsT)
b = ui.NewButton(w.Name)
newt.uiButton = b
newt.uiControl = b
newt.tw = w
newt.parent = t
@ -32,66 +31,6 @@ func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
newt.commonChange(newt.tw)
})
log(debugToolkit, "newButton() about to append to Box parent t:", w.Name)
log(debugToolkit, "newButton() about to append to Box new t:", w.Name)
if (debugToolkit) {
ShowDebug ()
}
if (t.uiBox != nil) {
t.uiBox.Append(b, stretchy)
} else if (t.uiWindow != nil) {
t.uiWindow.SetChild(b)
} else {
log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
return
}
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doButton(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newButton(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Button() ct.broken", ct)
return
}
if (ct.uiButton == nil) {
log(debugError, "Button() uiButton == nil", ct)
return
}
log(debugToolkit, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiButton.Enable()
case "Disable":
ct.uiButton.Disable()
case "Show":
ct.uiButton.Show()
case "Hide":
ct.uiButton.Hide()
case "Set":
ct.uiButton.SetText(c.S)
default:
log(debugError, "Can't do", c.Action, "to a Button")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -11,14 +11,8 @@ func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
var newt andlabsT
newt.tw = w
if t.broken() {
return nil
}
newt.uiCheckbox = ui.NewCheckbox(w.Name)
newt.uiBox = t.uiBox
// t.doAppend(&newt, *newt.uiCheckbox)
t.uiBox.Append(newt.uiCheckbox, stretchy)
newt.uiControl = newt.uiCheckbox
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
newt.tw.B = newt.checked()
@ -30,14 +24,12 @@ func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
}
func (t *andlabsT) checked() bool {
if t.broken() {
return false
}
return t.uiCheckbox.Checked()
}
func newCheckbox(parentW *toolkit.Widget, w *toolkit.Widget) {
func newCheckbox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCheckbox()", w.Name)
t := mapToolkits[parentW]
@ -46,45 +38,6 @@ func newCheckbox(parentW *toolkit.Widget, w *toolkit.Widget) {
return
}
newt := t.newCheckbox(w)
mapWidgetsToolkits(w, newt)
}
func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newCheckbox(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "checkbox() ct.broken", ct)
return
}
if (ct.uiCheckbox == nil) {
log(true, "checkbox() uiCheckbox == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiCheckbox.Enable()
case "Disable":
ct.uiCheckbox.Disable()
case "Show":
ct.uiCheckbox.Show()
case "Hide":
ct.uiCheckbox.Hide()
case "SetText":
ct.uiCheckbox.SetText(c.S)
case "Set":
ct.uiCheckbox.SetChecked(c.B)
default:
log(debugError, "Can't do", c.Action, "to a checkbox")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -10,15 +10,10 @@ func (t *andlabsT) newCombobox(w *toolkit.Widget) *andlabsT {
var newt andlabsT
log(debugToolkit, "newCombobox() START", w.Name)
if t.broken() {
return nil
}
newt.tw = w
s := ui.NewEditableCombobox()
newt.uiEditableCombobox = s
newt.uiBox = t.uiBox
t.uiBox.Append(s, stretchy)
newt.uiControl = s
// initialize the index
newt.c = 0
@ -46,7 +41,9 @@ func (t *andlabsT) AddComboboxName(title string) {
t.c = t.c + 1
}
func newCombobox(parentW *toolkit.Widget, w *toolkit.Widget) {
func newCombobox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCombobox()", w.Name)
t := mapToolkits[parentW]
@ -56,45 +53,6 @@ func newCombobox(parentW *toolkit.Widget, w *toolkit.Widget) {
return
}
newt := t.newCombobox(w)
mapWidgetsToolkits(w, newt)
}
func doCombobox(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newCombobox(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Combobox() ct.broken", ct)
return
}
if (ct.uiEditableCombobox == nil) {
log(true, "Combobox() uiEditableCombobox == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Add":
ct.AddComboboxName(c.S)
case "Enable":
ct.uiEditableCombobox.Enable()
case "Disable":
ct.uiEditableCombobox.Disable()
case "Show":
ct.uiEditableCombobox.Show()
case "Hide":
ct.uiEditableCombobox.Hide()
case "Set":
ct.uiEditableCombobox.SetText(c.S)
default:
log(debugError, "Can't do", c.Action, "to a Combobox")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -2,11 +2,10 @@ package main
import (
"git.wit.org/wit/gui/toolkit"
// "github.com/davecgh/go-spew/spew"
)
func (t *andlabsT) commonChange(tw *toolkit.Widget) {
log(debugChange, "commonChange() START widget =", t.Name, t.Type)
log(debugChange, "commonChange() START widget =", t.tw.Name, t.tw.Type)
if (tw == nil) {
log(true, "commonChange() What the fuck. there is no widget t.tw == nil")
return
@ -19,44 +18,6 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget) {
log(debugChange, "commonChange() END Widget.Custom()", t.tw.Name, t.tw.Type)
}
// does some sanity checks on the internal structs of the binary tree
// TODO: probably this should not panic unless it's running in devel mode (?)
// TODO: redo this now that WidgetType is used and send() is used to package plugins
func (t *andlabsT) broken() bool {
/*
if (t.parent != nil) {
return false
}
if (t.uiBox == nil) {
if (t.uiWindow != nil) {
log(debugToolkit, "UiBox == nil. This is an empty window. Try to add a box")
t.newBox()
return false
}
log(true, "UiBox == nil. I can't add a widget without a place to put it")
// log(debugToolkit, "probably could just make a box here?")
// corruption or something horrible?
t.Dump(true)
panic("wit/gui toolkit/andlabs func broken() invalid goroutine access into this toolkit?")
panic("wit/gui toolkit/andlabs func broken() this probably should not cause the app to panic here (?)")
return true
}
if (t.uiWindow == nil) {
log(debugToolkit, "UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)")
t.Dump(debugToolkit)
return false
}
*/
return false
}
func broken(w *toolkit.Widget) bool {
if (w == nil) {
log(true, "widget == nil. I can't do anything widget")
return true
}
return false
}
func dump(p *toolkit.Widget, c *toolkit.Widget, b bool) {
log(b, "Parent:")
pt := mapToolkits[p]

View File

@ -14,7 +14,10 @@ var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugAction bool
var debugFlags bool
var debugGrid bool
var debugNow bool = true
var debugError bool = true
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
@ -37,8 +40,9 @@ func setDefaultBehavior(s bool) {
func ShowDebug () {
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
log(true, "debugPlugin =", debugPlugin)
log(true, "debugAction =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugNow =", debugNow)
log(true, "debugError =", debugError)
}
@ -87,7 +91,6 @@ func widgetDump(b bool, w *toolkit.Widget) {
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)

View File

@ -18,7 +18,7 @@ func destroy(p *toolkit.Widget, c *toolkit.Widget) {
return
}
switch ct.Type {
switch ct.tw.Type {
case toolkit.Button:
log(true, "Should delete Button here:", c.Name)
log(true, "Parent:")
@ -41,8 +41,8 @@ func destroy(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "Should delete Window here:", c.Name)
default:
log(true, "Don't know how to delete c =", c.Type, c.Name)
log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton)
log(true, "Don't know how to delete pt =", pt.tw.Type, pt.tw.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.tw.Type, ct.tw.Name, ct.uiButton)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")

View File

@ -10,15 +10,10 @@ func (t *andlabsT) newDropdown(w *toolkit.Widget) *andlabsT {
var newt andlabsT
log(debugToolkit, "gui.Toolbox.newDropdown() START", w.Name)
if t.broken() {
return nil
}
newt.tw = w
s := ui.NewCombobox()
newt.uiCombobox = s
newt.uiBox = t.uiBox
t.uiBox.Append(s, stretchy)
newt.uiControl = s
// initialize the index
newt.c = 0
@ -57,16 +52,16 @@ func (t *andlabsT) SetDropdown(i int) {
t.uiCombobox.SetSelected(i)
}
func AddDropdownName(w *toolkit.Widget, s string) {
log(debugToolkit, "gui.andlabs.AddDropdownName()", w.Name, "add:", s)
func AddDropdownName(a *toolkit.Action) {
log(debugToolkit, "gui.andlabs.AddDropdownName()", a.Widget.Name, "add:", a.S)
t := mapToolkits[w]
t := mapToolkits[a.Widget]
if (t == nil) {
log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", w.Name, s)
log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", a.Widget.Name, a.S)
listMap(debugToolkit)
return
}
t.AddDropdownName(s)
t.AddDropdownName(a.S)
}
func SetDropdownName(w *toolkit.Widget, s string) {
@ -82,7 +77,9 @@ func SetDropdownName(w *toolkit.Widget, s string) {
t.tw.S = s
}
func newDropdown(parentW *toolkit.Widget, w *toolkit.Widget) {
func newDropdown(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "gui.andlabs.newDropdown()", w.Name)
t := mapToolkits[parentW]
@ -92,68 +89,6 @@ func newDropdown(parentW *toolkit.Widget, w *toolkit.Widget) {
return
}
newt := t.newDropdown(w)
mapWidgetsToolkits(w, newt)
}
func doDropdown(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newDropdown(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Dropdown() ct.broken", ct)
return
}
if (ct.uiCombobox == nil) {
log(debugError, "Dropdown() uiCombobox == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Add":
ct.AddDropdownName(c.S)
// ct.uiCombobox.Enable()
case "Enable":
ct.uiCombobox.Enable()
case "Disable":
ct.uiCombobox.Disable()
case "Show":
ct.uiCombobox.Show()
case "Hide":
ct.uiCombobox.Hide()
case "Set":
ct.uiCombobox.SetSelected(1)
case "SetText":
var orig int
var i int = -1
var s string
orig = ct.uiCombobox.Selected()
log(debugError, "TODO: set a Dropdown by the name selected =", orig, ct.c, c.S)
// try to find the string
for i, s = range ct.val {
log(debugError, "i, s", i, s)
if (c.S == s) {
ct.uiCombobox.SetSelected(i)
return
}
}
// if i == -1, then there are not any things in the menu to select
if (i == -1) {
return
}
// if the string was never set, then set the dropdown to the last thing added to the menu
if (orig == -1) {
ct.uiCombobox.SetSelected(i)
}
default:
log(debugError, "Can't do", c.Action, "to a Dropdown")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -12,80 +12,21 @@ import (
// -- (1,1) -- (2,1) -- (3,1) --
// -- (1,2) -- (2,1) -- (3,1) --
// -----------------------------
func newGrid(parentW *toolkit.Widget, w *toolkit.Widget) {
func newGrid(a *toolkit.Action) {
var newt *andlabsT
log(debugToolkit, "NewGrid()", w.Name)
log(debugToolkit, "newGrid()", a.Widget.Name, "to", a.Where.Type)
t := mapToolkits[parentW]
if (t == nil) {
listMap(debugError)
log(debugError, "ERROR newGrid() listMap()")
log(debugError, "ERROR FFFFFFFFFFFF listMap()")
log(debugError, "ERROR FFFFFFFFFFFF listMap()")
return
}
log(debugToolkit, "NewGrid()", w.Name)
if t.broken() {
return
}
t := mapToolkits[a.Where]
newt = new(andlabsT)
c := ui.NewGrid()
newt.uiGrid = c
newt.uiBox = t.uiBox
newt.tw = w
t.doAppend(toolkit.Grid, newt, nil)
mapWidgetsToolkits(w, newt)
}
newt.uiControl = c
newt.tw = a.Widget
newt.gridX = 0
newt.gridY = 0
func doGrid(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newGrid(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Grid() ct.broken", ct)
return
}
if (ct.uiGrid == nil) {
log(debugError, "Grid() uiGrid == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiGrid.Enable()
case "Disable":
ct.uiGrid.Disable()
case "Show":
ct.uiGrid.Show()
case "Hide":
log(debugError, "trying Hide on grid")
ct.uiGrid.Hide()
case "SetMargin":
log(debugError, "trying SetMargin on grid")
ct.uiGrid.SetPadded(c.B)
case "Set":
log(debugError, "Can I use 'Set' to place a *Node in a Grid?")
/*
case "AddGrid":
log(true, "how do I add a thing to a grid?")
dump(p, c, true)
newt.uiGrid.Append(button1,
0, 2, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
*/
default:
log(debugError, "Can't do", c.Action, "to a Grid")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -7,7 +7,9 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
func newGroup(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "NewGroup()", w.Name)
t := mapToolkits[parentW]
@ -16,7 +18,8 @@ func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
listMap(debugToolkit)
}
newt := t.rawGroup(w.Name)
mapWidgetsToolkits(w, newt)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}
// make new Group here
@ -29,69 +32,15 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
g := ui.NewGroup(newt.Name)
g.SetMargined(margin)
newt.uiGroup = g
newt.uiControl = g
t.doAppend(toolkit.Group, &newt, nil)
// hbox := ui.NewVerticalBox()
// hbox.SetPadded(padded)
// g.SetChild(hbox)
hbox := ui.NewVerticalBox()
hbox.SetPadded(padded)
g.SetChild(hbox)
newt.uiBox = hbox
newt.uiWindow = t.uiWindow
newt.uiTab = t.uiTab
// newt.uiBox = hbox
// newt.uiWindow = t.uiWindow
// newt.uiTab = t.uiTab
return &newt
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doGroup(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newGroup(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Group() ct.broken", ct)
return
}
if (ct.uiGroup == nil) {
log(debugError, "Label() uiGroup == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiGroup.Enable()
case "Disable":
ct.uiGroup.Disable()
case "Show":
ct.uiGroup.Show()
case "Hide":
ct.uiGroup.Hide()
case "Get":
c.S = ct.uiGroup.Title()
case "Set":
ct.uiGroup.SetTitle(c.S)
case "SetText":
ct.uiGroup.SetTitle(c.S)
case "SetMargin":
ct.uiGroup.SetMargined(c.B)
case "Destroy":
ct.uiGroup.Destroy()
default:
log(debugError, "Can't do", c.Action, "to a Group")
}
}

68
toolkit/andlabs/image.go Normal file
View File

@ -0,0 +1,68 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// make new Image here
func newImage(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newImage()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "newImage() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap(debugToolkit)
}
newt := t.rawImage(w.Name)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}
// make new Image using andlabs/ui
func (t *andlabsT) rawImage(title string) *andlabsT {
var newt andlabsT
var img *ui.Image
newt.Name = title
log(debugToolkit, "rawImage() create", newt.Name)
img = ui.NewImage(16, 16)
newt.uiImage = img
// newt.uiControl = img
return &newt
}
/*
if (w.Name == "image") {
log(true, "NewTextbox() trying to add a new image")
i := ui.NewImage(16, 16)
img, _, err := image.Decode(bytes.NewReader(rawImage))
if err != nil {
panic(err)
}
nr, ok := img.(*image.RGBA)
if !ok {
i2 := image.NewRGBA(img.Bounds())
draw.Draw(i2, i2.Bounds(), img, img.Bounds().Min, draw.Src)
nr = i2
}
i.Append(nr)
t.uiBox.Append(i, true)
var img *ui.Image
var icon []byte
var imgA image.Image
icon, _ = res.ReadFile("resources/ping6.working.png")
// imgA, _, err := image.Decode(bytes.NewReader(b))
imgA, _, _ = image.Decode(icon)
img.Append(imgA)
img.Append(icon)
}
*/

View File

@ -7,11 +7,12 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
func newLabel(a *toolkit.Action) {
var newt *andlabsT
w := a.Widget
log(debugToolkit, "NewLabel()", w.Name)
t := mapToolkits[parentW]
t := mapToolkits[a.Where]
if (t == nil) {
listMap(debugError)
log(debugError, "ERROR newLabel() listMap()")
@ -21,68 +22,13 @@ func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
}
log(debugToolkit, "NewLabel()", w.Name)
if t.broken() {
return
}
newt = new(andlabsT)
c := ui.NewLabel(w.Name)
newt.uiLabel = c
newt.uiControl = c
newt.uiBox = t.uiBox
newt.tw = w
if (defaultBehavior) {
t.uiBox.Append(c, stretchy)
}
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doLabel(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newLabel(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Label() ct.broken", ct)
return
}
if (ct.uiLabel == nil) {
log(debugError, "Label() uiLabel == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiLabel.Enable()
case "Disable":
ct.uiLabel.Disable()
case "Show":
ct.uiLabel.Show()
case "Hide":
ct.uiLabel.Hide()
case "SetText":
ct.uiLabel.SetText(c.S)
case "Set":
ct.uiLabel.SetText(c.S)
default:
log(debugError, "Can't do", c.Action, "to a Label")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -19,73 +19,224 @@ import "git.wit.org/wit/gui/toolkit"
// TODO: make sure you can't escape this goroutine
//
func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) {
log(debugPlugin, "Send() parent = nil")
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
log(debugPlugin, "Send() goodbye. not used anymore")
}
/*
if (c.Action == "SetMargin") {
log(debugError, "need to implement SetMargin here")
setMargin(c, c.B)
func Action(a *toolkit.Action) {
if (a == nil) {
log(debugPlugin, "Action = nil")
return
}
*/
f := func() {
rawAction(a)
}
switch c.Type {
case toolkit.Window:
doWindow(c)
case toolkit.Tab:
doTab(p, c)
case toolkit.Group:
doGroup(p, c)
case toolkit.Button:
doButton(p, c)
case toolkit.Checkbox:
doCheckbox(p, c)
case toolkit.Label:
doLabel(p, c)
case toolkit.Textbox:
doTextbox(p, c)
case toolkit.Slider:
doSlider(p, c)
case toolkit.Spinner:
doSpinner(p, c)
case toolkit.Dropdown:
doDropdown(p, c)
case toolkit.Combobox:
doCombobox(p, c)
case toolkit.Grid:
doGrid(p, c)
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch c.S {
case "Toolkit":
debugToolkit = c.B
case "Change":
debugChange = c.B
case "Plugin":
debugPlugin = c.B
case "Flags":
debugFlags = c.B
case "Error":
debugError = c.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", c.S)
// f()
Queue(f)
}
func rawAction(a *toolkit.Action) {
log(debugAction, "Action() START a.Type =", a.Type)
log(debugAction, "Action() START a.S =", a.S)
log(debugAction, "Action() START a.Widget =", a.Widget)
switch a.Type {
case toolkit.Add:
add(a)
case toolkit.Show:
a.Widget.B = true
show(a.Widget)
case toolkit.Hide:
a.Widget.B = false
show(a.Widget)
case toolkit.Enable:
a.Widget.B = true
enable(a.Widget)
case toolkit.Disable:
a.Widget.B = false
enable(a.Widget)
case toolkit.Get:
setText(a)
case toolkit.GetText:
switch a.Widget.Type {
case toolkit.Textbox:
t := mapToolkits[a.Widget]
a.S = t.s
}
case toolkit.Set:
setText(a)
case toolkit.SetFlag:
flag(a)
case toolkit.SetText:
setText(a)
case toolkit.AddText:
setText(a)
case toolkit.Margin:
pad(a)
case toolkit.Unmargin:
pad(a)
case toolkit.Pad:
pad(a)
case toolkit.Unpad:
pad(a)
case toolkit.Delete:
uiDelete(a)
case toolkit.Flag:
flag(a)
case toolkit.Move:
log(debugNow, "attempt to move() =", a.Type, a.Widget)
move(a)
default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet")
log(debugError, "Action() Unknown =", a.Type, a.Widget)
}
log(debugAction, "Action() END =", a.Type, a.Widget)
}
func flag(a *toolkit.Action) {
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch a.S {
case "Toolkit":
debugToolkit = a.B
case "Change":
debugChange = a.B
case "Plugin":
debugPlugin = a.B
case "Flags":
debugFlags = a.B
case "Error":
debugError = a.B
case "Now":
debugNow = a.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", a.S)
}
}
func setText(a *toolkit.Action) {
w := a.Widget
if (w == nil) {
log(debugError, "setText error. w.Widget == nil")
actionDump(debugError, a)
return
}
t := mapToolkits[w]
log(debugChange, "setText() Attempt on", w.Type, "with", a.S)
switch w.Type {
case toolkit.Window:
t.uiWindow.SetTitle(a.S)
case toolkit.Tab:
case toolkit.Group:
t.uiGroup.SetTitle(a.S)
case toolkit.Checkbox:
switch a.Type {
case toolkit.SetText:
t.uiCheckbox.SetText(a.S)
case toolkit.Get:
w.B = t.uiCheckbox.Checked()
case toolkit.Set:
t.uiCheckbox.SetChecked(a.B)
w.B = a.B
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
case toolkit.Textbox:
switch a.Type {
case toolkit.Set:
t.uiMultilineEntry.SetText(a.S)
case toolkit.SetText:
t.uiMultilineEntry.SetText(a.S)
case toolkit.Get:
w.S = t.s
case toolkit.GetText:
w.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
case toolkit.Label:
t.uiLabel.SetText(a.S)
case toolkit.Button:
t.uiButton.SetText(a.S)
case toolkit.Slider:
switch a.Type {
case toolkit.Get:
w.I = t.uiSlider.Value()
case toolkit.Set:
t.uiSlider.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
case toolkit.Spinner:
switch a.Type {
case toolkit.Get:
w.I = t.uiSpinbox.Value()
case toolkit.Set:
t.uiSpinbox.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
case toolkit.Dropdown:
switch a.Type {
case toolkit.AddText:
AddDropdownName(a)
case toolkit.Set:
var orig int
var i int = -1
var s string
orig = t.uiCombobox.Selected()
log(debugChange, "try to set the Dropdown to", a.S, "from", orig)
// try to find the string
for i, s = range t.val {
log(debugChange, "i, s", i, s)
if (a.S == s) {
t.uiCombobox.SetSelected(i)
log(debugChange, "setText() Dropdown worked.", w.S)
return
}
}
log(debugError, "setText() Dropdown did not find:", a.S)
// if i == -1, then there are not any things in the menu to select
if (i == -1) {
return
}
// if the string was never set, then set the dropdown to the last thing added to the menu
if (orig == -1) {
t.uiCombobox.SetSelected(i)
}
case toolkit.Get:
w.S = t.s
case toolkit.GetText:
w.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
case toolkit.Combobox:
switch a.Type {
case toolkit.AddText:
t.AddComboboxName(a.S)
case toolkit.Set:
t.uiEditableCombobox.SetText(a.S)
t.s = a.S
case toolkit.SetText:
t.uiEditableCombobox.SetText(a.S)
t.s = a.S
case toolkit.Get:
w.S = t.s
case toolkit.GetText:
w.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
}
default:
log(debugError, "plugin Send() Don't know how to setText on", w.Type, "yet", a.Type)
}
}

View File

@ -0,0 +1,72 @@
// myplugin/myplugin.go
package main
/*
from chatgpt:
// put this in widget.go
import (
"fmt"
// "toolkit"
)
type Plugin interface {
Process(input chan string, output chan string)
}
// put this in wit/gui/toolkit/*
type myPlugin struct{}
var Plugin myPlugin
func (p *myPlugin) Process(input chan string, output chan string) {
go func() {
for msg := range input {
// Your processing logic goes here
result := fmt.Sprintf("Processed: %s", msg)
output <- result
}
}()
}
// main.go put this in wit/gui
package main
import (
"fmt"
"plugin"
"pluginapi"
)
func main() {
plug, err := plugin.Open("myplugin.so")
if err != nil {
panic(err)
}
symPlugin, err := plug.Lookup("Plugin")
if err != nil {
panic(err)
}
p, ok := symPlugin.(pluginapi.Plugin)
if !ok {
panic("Invalid plugin type")
}
input := make(chan string)
output := make(chan string)
p.Process(input, output)
input <- "Hello, World!"
close(input)
for result := range output {
fmt.Println(result)
}
}
*/
// func main() {}

View File

@ -12,18 +12,10 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
log(debugToolkit, w.Name, w.Type, w.X, w.Y)
var newt andlabsT
if (t.uiBox == nil) {
log(debugToolkit, "node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugToolkit, "probably could just make a box here?")
exit("internal golang wit/gui/toolkit error")
return nil
}
s := ui.NewSlider(w.X, w.Y)
newt.uiSlider = s
newt.uiBox = t.uiBox
newt.uiControl = s
newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(spin *ui.Slider) {
newt.tw.I = newt.uiSlider.Value()
@ -33,8 +25,10 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
return &newt
}
func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
func newSlider(a *toolkit.Action) {
var newt *andlabsT
w := a.Widget
parentW := a.Where
log(debugToolkit, "newSlider()", w.Name)
t := mapToolkits[parentW]
@ -42,53 +36,9 @@ func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugError, "newSlider() ERROR toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
w.X = a.X
w.Y = a.Y
newt = t.newSlider(w)
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doSlider(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newSlider(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Slider() ct.broken", ct)
return
}
if (ct.uiSlider == nil) {
log(debugError, "Label() uiSlider == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiSlider.Enable()
case "Disable":
ct.uiSlider.Disable()
case "Show":
ct.uiSlider.Show()
case "Hide":
ct.uiSlider.Hide()
case "Set":
ct.uiSlider.SetValue(c.I)
case "Get":
c.I = ct.uiSlider.Value()
default:
log(debugError, "Can't do", c.Action, "to a Slider")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -12,16 +12,10 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
log(debugToolkit, "newSpinner()", w.X, w.Y)
var newt andlabsT
if (t.uiBox == nil) {
log(debugToolkit, "newSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it")
return nil
}
s := ui.NewSpinbox(w.X, w.Y)
newt.uiSpinbox = s
newt.uiBox = t.uiBox
newt.uiControl = s
newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(s *ui.Spinbox) {
newt.tw.I = newt.uiSpinbox.Value()
@ -31,61 +25,19 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
return &newt
}
func newSpinner(parentW *toolkit.Widget, w *toolkit.Widget) {
func newSpinner(a *toolkit.Action) {
var newt *andlabsT
w := a.Widget
parentW := a.Where
t := mapToolkits[parentW]
if (t == nil) {
log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
w.X = a.X
w.Y = a.Y
newt = t.newSpinner(w)
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doSpinner(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newSpinner(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Spinner() ct.broken", ct)
return
}
if (ct.uiSpinbox == nil) {
log(debugError, "Label() uiSpinbox == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiSpinbox.Enable()
case "Disable":
ct.uiSpinbox.Disable()
case "Show":
ct.uiSpinbox.Show()
case "Hide":
ct.uiSpinbox.Hide()
case "Set":
ct.uiSpinbox.SetValue(c.I)
case "Get":
c.I = ct.uiSpinbox.Value()
default:
log(debugError, "Can't do", c.Action, "to a Spinbox")
}
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -10,15 +10,16 @@ type andlabsT struct {
id string
Name string
Type toolkit.WidgetType
// Type toolkit.WidgetType
Width int
Height int
tw *toolkit.Widget
parent *andlabsT
uiControl ui.Control
uiBox *ui.Box
uiButton *ui.Button
uiControl *ui.Control
uiCombobox *ui.Combobox
uiCheckbox *ui.Checkbox
uiEntry *ui.Entry
@ -31,11 +32,21 @@ type andlabsT struct {
uiMultilineEntry *ui.MultilineEntry
uiEditableCombobox *ui.EditableCombobox
uiGrid *ui.Grid
uiImage *ui.Image
gridX int
gridY int
// used as a counter to work around limitations of widgets like combobox
// this is probably fucked up and in many ways wrong because of unsafe goroutine threading
// but it's working for now due to the need for need for a correct interaction layer betten toolkits
c int
i int
b bool
s string
val map[int]string
// andlabs/ui only accesses widget id numbers
boxC int // how many things on in a box
boxW map[int]int // find a widget in a box
text string
}

View File

@ -54,11 +54,11 @@ func (t *andlabsT) newTab(name string) *andlabsT {
// This sets _all_ the tabs to Margin = true
//
// TODO: do proper tab tracking (will be complicated). low priority
func tabSetMargined(tab *ui.Tab) {
func tabSetMargined(tab *ui.Tab, b bool) {
c := tab.NumPages()
for i := 0; i < c; i++ {
log(debugToolkit, "SetMargined", i, margin)
tab.SetMargined(i, margin)
log(debugToolkit, "SetMargined", i, b)
tab.SetMargined(i, b)
}
}
@ -80,11 +80,12 @@ func rawTab(w *ui.Window, name string) *andlabsT {
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
hbox.SetPadded(padded)
tab.Append(name, hbox)
tabSetMargined(tab) // TODO: run this in the right place(?)
tabSetMargined(tab, margin) // TODO: run this in the right place(?)
w.SetChild(tab)
newt.uiWindow = w
newt.uiTab = tab
newt.uiControl = tab
newt.uiBox = hbox
return &newt
}
@ -118,7 +119,9 @@ func (t *andlabsT) appendTab(name string) *andlabsT {
return &newT
}
func newTab(parentW *toolkit.Widget, w *toolkit.Widget) {
func newTab(a *toolkit.Action) {
parentW := a.Where
w := a.Widget
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
@ -128,55 +131,9 @@ func newTab(parentW *toolkit.Widget, w *toolkit.Widget) {
return
}
newt = t.newTab(w.Name)
mapWidgetsToolkits(w, newt)
mapWidgetsToolkits(a, newt)
}
func doTab(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newTab(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Tab() ct.broken", ct)
return
}
if (ct.uiTab == nil) {
log(debugError, "Tab() uiTab == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiTab.Enable()
case "Disable":
ct.uiTab.Disable()
case "Show":
ct.uiTab.Show()
case "Hide":
ct.uiTab.Hide()
case "Get":
c.I = ct.uiTab.NumPages()
case "Add":
log(true, "how do I add a tab here in doTab()?")
dump(p, c, true)
case "SetMargin":
i := ct.uiTab.NumPages()
log(true, "tab.NumPages() =", i)
for i > 0 {
i -= 1
log(true, "uiTab.SetMargined(true) for i =", i)
ct.uiTab.SetMargined(i, c.B)
}
default:
log(debugError, "Can't do", c.Action, "to a Tab")
}
func doTab(a *toolkit.Action) {
newTab(a)
}

View File

@ -7,142 +7,38 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func newTextbox(parentW *toolkit.Widget, w *toolkit.Widget) {
log(debugToolkit, "NewTexbox()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
listMap(debugError)
log(debugError, "newTextbox() listMap()")
log(debugError, "FFFFFFFFFFFF listMap()")
log(debugError, "FFFFFFFFFFFF listMap()")
}
// t.NewTextbox(w)
// func (t *andlabsT) NewTextbox(w *toolkit.Widget) *andlabsT {
var newt *andlabsT
newt = new(andlabsT)
log(debugToolkit, "gui.Toolkit.NewTextbox()", w.Name)
if t.broken() {
return
}
// func newTextbox(a *toolkit.Action) {
func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
var newt andlabsT
c := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = c
newt.uiControl = c
newt.uiBox = t.uiBox
newt.Name = w.Name
newt.tw = w
if (defaultBehavior) {
t.uiBox.Append(c, true)
} else {
t.uiBox.Append(c, stretchy)
}
/*
// don't bother with "images" on andlabs/ui
"image"
"bytes"
_ "image/png"
"image/draw"
if (w.Name == "image") {
log(true, "NewTextbox() trying to add a new image")
i := ui.NewImage(16, 16)
img, _, err := image.Decode(bytes.NewReader(rawImage))
if err != nil {
panic(err)
}
nr, ok := img.(*image.RGBA)
if !ok {
i2 := image.NewRGBA(img.Bounds())
draw.Draw(i2, i2.Bounds(), img, img.Bounds().Min, draw.Src)
nr = i2
}
i.Append(nr)
t.uiBox.Append(i, true)
var img *ui.Image
var icon []byte
var imgA image.Image
icon, _ = res.ReadFile("resources/ping6.working.png")
// imgA, _, err := image.Decode(bytes.NewReader(b))
imgA, _, _ = image.Decode(icon)
img.Append(imgA)
img.Append(icon)
}
*/
c.OnChanged(func(spin *ui.MultilineEntry) {
w.S = newt.uiMultilineEntry.Text()
t.s = spin.Text()
// this is still dangerous
// newt.commonChange(newt.tw)
log(debugChange, "Not yet safe to trigger on change for ui.MultilineEntry")
})
mapWidgetsToolkits(w, newt)
return &newt
}
func newTextbox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCombobox()", w.Name)
func doTextbox(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap(debugToolkit)
return
}
if (c.Action == "New") {
newTextbox(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Textbox() ct.broken", ct)
return
}
if (ct.uiMultilineEntry == nil) {
log(debugError, "Textbox() uiMultilineEntry == nil", ct)
return
}
// the dns control panel isn't crashing anymore (?)
Queue(ct.doSimpleAction)
}
func (t *andlabsT) doSimpleAction() {
if (t.tw == nil) {
log(true, "doSimpleAction() got an empty widget")
log(true, "THIS SHOULD NEVER HAPPEN")
panic("crap. panic. widget == nil")
}
log(debugChange, "Going to attempt:", t.tw.Action)
switch t.tw.Action {
case "Enable":
if (t.uiEntry != nil) {
t.uiEntry.Enable()
} else if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.Enable()
} else {
log(debugError, "don't know what to enable", t.Name)
}
case "Disable":
if (t.uiEntry != nil) {
t.uiEntry.Disable()
} else if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.Disable()
} else {
log(debugError, "don't know what to disable", t.Name)
}
case "Show":
t.uiMultilineEntry.Show()
case "Hide":
t.uiMultilineEntry.Hide()
case "SetText":
t.uiMultilineEntry.SetText(t.tw.S)
case "Set":
t.uiMultilineEntry.SetText(t.tw.S)
default:
log(debugError, "Can't do", t.tw.Action, "to a Textbox")
}
newt := t.newTextbox(w)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -9,10 +9,11 @@ import (
var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT
// This lists out the know mappings
// This lists out the known mappings
// deprecate and use instead the GUI interface
func listMap(b bool) {
log(b, "listMap() HERE")
log(b, "listMap() HERE")
log(b, "listMap() disabled HERE. output too big")
return
for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name)
}
@ -25,7 +26,8 @@ func listMap(b bool) {
log(b, "listMap() HERE FIXME. output too big")
}
func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
func mapWidgetsToolkits(a *toolkit.Action, t *andlabsT) {
w := a.Widget
if ((mapToolkits[w] == nil) && (mapWidgets[t] == nil)) {
log(debugToolkit, "map a new widget", w, t)
mapToolkits[w] = t
@ -63,5 +65,5 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
widgetDump(debugError, wt)
}
}
log(debugToolkit, "map of widget worked", w.Type, ",", w.Name, ",", w.Action)
log(debugToolkit, "map of widget worked", w.Type, ",", w.Name)
}

View File

@ -15,7 +15,8 @@ func (t *andlabsT) ErrorWindow(msg1 string, msg2 string) {
ui.MsgBoxError(t.uiWindow, msg1, msg2)
}
func newWindow(w *toolkit.Widget) {
func newWindow(a *toolkit.Action) {
w := a.Widget
var newt *andlabsT
log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
@ -37,10 +38,11 @@ func newWindow(w *toolkit.Widget) {
})
win.Show()
newt.uiWindow = win
newt.uiControl = win
// newt.UiWindowBad = win // deprecate this as soon as possible
newt.Name = w.Name
mapWidgetsToolkits(w, newt)
mapWidgetsToolkits(a, newt)
return
}
@ -54,46 +56,6 @@ func (t *andlabsT) SetWindowTitle(title string) {
}
}
func doWindow(c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newWindow(c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if (ct.uiWindow == nil) {
log(debugError, "Window() uiWindow == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Show":
ct.uiWindow.Show()
case "Hide":
ct.uiWindow.Hide()
case "Enable":
ct.uiWindow.Enable()
case "Disable":
ct.uiWindow.Disable()
case "Get":
c.S = ct.uiWindow.Title()
case "Set":
ct.uiWindow.SetTitle(c.S)
case "SetText":
ct.uiWindow.SetTitle(c.S)
case "SetMargin":
ct.uiWindow.SetMargined(c.B)
case "SetBorder":
ct.uiWindow.SetBorderless(c.B)
case "Delete":
ct.uiWindow.Destroy()
default:
log(debugError, "Can't do", c.Action, "to a Window")
}
func doWindow(a *toolkit.Action) {
newWindow(a)
}

View File

@ -89,7 +89,6 @@ func widgetDump(b bool, w *toolkit.Widget) {
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)

View File

@ -44,7 +44,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
log(debugPlugin, "Send() child =", c.Name, ",", c.Type)
/*
if (c.Action == "SetMargin") {
@ -81,6 +81,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
case toolkit.Grid:
// doGrid(p, c)
*/
/*
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
@ -105,6 +106,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
default:
log(debugError, "Can't set unknown flag", c.S)
}
*/
default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)

View File

@ -89,7 +89,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
// log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)

View File

@ -44,7 +44,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
log(debugPlugin, "Send() child =", c.Name, ",", c.Type)
/*
if (c.Action == "SetMargin") {
@ -83,6 +83,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
case toolkit.Grid:
// doGrid(p, c)
*/
/*
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
@ -107,6 +108,7 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
default:
log(debugError, "Can't set unknown flag", c.S)
}
*/
default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)

View File

@ -1,18 +1,24 @@
package toolkit
type WidgetType int
type ActionType int
// passes information between the toolkit library (plugin)
//
// All Toolkit interactions should be done via a channel or Queue()
// TODO: FIND THIS NOTE AND FIGURE OUT HOW TO IMPLEMENT IT
// TODO: FIGURE OUT HOW TO IMPLEMENT THIS
//
// This is the only thing that is passed between the toolkit plugin
//
// what names should be used? This is not part of [[Graphical Widget]]
// Event() seems like a good name.
// Event() seems like a good name.
// Event is used too much: web dev, cloud, etc
// I'm using "Action". Maybe it should really be
// "Interaction" as per wikipedia [[User interface]]
// Could a protobuf be used here? (Can functions be passed?)
type Widget struct {
Name string
Action string // "New", "Delete", "Set", aka something to do
// Action string // "New", "Delete", "Set", aka something to do
Type WidgetType
// This function is how you interact with the toolkit
@ -20,6 +26,7 @@ type Widget struct {
// Hopefully this will be the barrier between the goroutines
// TODO: move this interaction to channels
Custom func()
Callback func()
// re-adding an id to test channels
id int
@ -48,26 +55,88 @@ type Widget struct {
Expand bool
}
type WidgetType int
type Action struct {
Type ActionType
// this should be the widget
// if the action is New, Hide, Enable, etc
Widget *Widget
// this is the widget
// where the other one should be put on New, Move, etc
Where *Widget
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
// The string is also used to set the button name
B bool
I int
// maybe safe if there is correctly working Custom() between goroutines?
// (still probably not, almost certainly not. not possible. layer violation?)
S string // not safe to have 'S'
// This GUI is intended for simple things
// We are not laying out PDF's here
// This is used for things like a slider(0,100)
Width int
Height int
X int
Y int
// Put space around elements to improve look & feel
Margin bool
// Make widgets fill up the space available
Expand bool
}
// https://ieftimov.com/post/golang-datastructures-trees/
// TODO: protobuf ?
const (
Unknown WidgetType = iota
Window
Tab
Group
Frame
Tab // internally, this should be a window (?)
Frame // should windows and tab's be frames (?)
Grid // a grid of frames ?
Group // internally, this should be a grid (?)
Box // internally, this should be a grid (?)
Button
Checkbox
Dropdown
Combobox
Combobox // dropdown with edit=true (?)
Label
Textbox
Textbox // is this a Label with edit=true?
Slider
Spinner
Grid
Box
Image
Area
Form
Font
Color
Dialog
)
const (
Add ActionType = iota
Delete
Get
Set
SetFlag
GetText
SetText
AddText
Show
Hide
Enable
Disable
Margin
Unmargin
Pad
Unpad
Append
Move
Dump
Flag
)
@ -77,10 +146,14 @@ func (s WidgetType) String() string {
return "Window"
case Tab:
return "Tab"
case Group:
return "Group"
case Frame:
return "Frame"
case Grid:
return "Grid"
case Group:
return "Group"
case Box:
return "Box"
case Button:
return "Button"
case Checkbox:
@ -97,18 +170,68 @@ func (s WidgetType) String() string {
return "Slider"
case Spinner:
return "Spinner"
case Grid:
return "Grid"
case Box:
return "Box"
case Image:
return "Image"
case Flag:
return "Flag"
case Area:
return "Area"
case Form:
return "Form"
case Font:
return "Font"
case Color:
return "Color"
case Dialog:
return "Dialog"
case Unknown:
return "Unknown"
}
return "GuiToolkitTUndefinedType"
return "Widget.Type.String() Error"
}
func (s ActionType) String() string {
switch s {
case Add:
return "Add"
case Delete:
return "Delete"
case Get:
return "Get"
case Set:
return "Set"
case SetFlag:
return "SetFlag"
case GetText:
return "GetText"
case SetText:
return "SetText"
case AddText:
return "AddText"
case Show:
return "Show"
case Hide:
return "Hide"
case Enable:
return "Enable"
case Disable:
return "Disable"
case Margin:
return "Margin"
case Unmargin:
return "Unmargin"
case Pad:
return "Pad"
case Unpad:
return "Unpad"
case Append:
return "Append"
case Move:
return "Move"
case Flag:
return "Flag"
case Dump:
return "Dump"
}
return "Action.Type.String() Error"
}
// this is hopefully just used in a very few places for

View File

@ -41,6 +41,9 @@ func NewWindow() *Node {
log(debugGui, "Window()", Config.Title)
send(nil, newNode)
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, Config.master)
return newNode
}