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

View File

@ -4,6 +4,13 @@ import "git.wit.org/wit/gui/toolkit"
func (n *Node) NewButton(name string, custom func()) *Node { func (n *Node) NewButton(name string, custom func()) *Node {
newNode := n.New(name, toolkit.Button, custom) 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 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" import "git.wit.org/wit/gui/toolkit"
func (n *Node) Checked() bool { func (n *Node) Checked() bool {
n.Dump()
return n.widget.B return n.widget.B
} }
func (n *Node) NewCheckbox(name string) *Node { func (n *Node) NewCheckbox(name string) *Node {
newNode := n.New(name, toolkit.Checkbox, nil) 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 return newNode
} }

View File

@ -20,21 +20,10 @@ var args struct {
} }
func main() { func main() {
// this implements ./cmd --gui-debug --gui-toolkit, etc
arg.MustParse(&args) arg.MustParse(&args)
// fmt.Println(args.Foo, args.Bar, args.User)
log.Println("Toolkit = ", args.Toolkit) 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.InitPlugins([]string{"andlabs"})
gui.Main(initGUI) gui.Main(initGUI)
} }
@ -52,32 +41,40 @@ func initGUI() {
log.Println("myDefaultExit(w)") log.Println("myDefaultExit(w)")
myDefaultExit(w) myDefaultExit(w)
} }
w.Dump()
addDemoTab(w, "A Simple Tab Demo") addDemoTab(w, "A Simple Tab Demo")
addDemoTab(w, "A Second Tab") addDemoTab(w, "A Second Tab")
if (args.GuiDebug) { if (args.GuiDebug) {
gui.DebugWindow() gui.DebugWindow()
} }
if (args.GuiVerbose) { if (args.GuiVerbose) {
gui.SetDebug(true) gui.SetDebug(true)
} }
} }
func addDemoTab(window *gui.Node, title string) { func addDemoTab(window *gui.Node, title string) {
var newNode, g, g2, tb *gui.Node var newNode, g *gui.Node
newNode = window.NewTab(title) newNode = window.NewTab(title)
log.Println("addDemoTab() newNode.Dump") log.Println("addDemoTab() newNode START")
newNode.Dump() // newNode.Dump(true)
g = newNode.NewGroup("group 1") 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 1")
dd.AddDropdownName("more 2") dd.AddDropdownName("more 2")
dd.AddDropdownName("more 3") 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()) log.Println("tb =", tb.GetText())
tb.Custom = func() { tb.Custom = func() {
s := tb.GetText() s := tb.GetText()

119
common.go
View File

@ -1,52 +1,112 @@
package gui package gui
// Common actions for widgets like 'Enable' or 'Hide'
import ( import (
"regexp" "regexp"
// "errors" "git.wit.org/wit/gui/toolkit"
// "git.wit.org/wit/gui/toolkit"
) )
// functions for handling text related GUI elements // 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) { func (n *Node) Add(str string) {
log(debugGui, "gui.Add() value =", str) log(debugGui, "gui.Add() value =", str)
n.widget.Action = "Add"
n.widget.S = str var a toolkit.Action
send(n.parent, n) a.Type = toolkit.Add
a.S = str
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
} }
func (n *Node) SetText(str string) bool { func (n *Node) AddText(str string) {
log(debugChange, "gui.SetText() value =", str) log(debugChange, "AddText() value =", str)
n.widget.Action = "SetText"
n.widget.S = str var a toolkit.Action
send(n.parent, n) a.Type = toolkit.AddText
return true a.S = str
// a.Widget = &n.widget
// action(&a)
newaction(&a, n, nil)
} }
func (n *Node) Set(a any) bool { func (n *Node) SetText(str string) {
log(debugChange, "gui.Set() value =", a) log(debugChange, "SetText() value =", str)
n.widget.Action = "Set"
switch v := a.(type) { 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: case bool:
n.widget.B = a.(bool) a.B = val.(bool)
case string: case string:
n.widget.S = a.(string) a.S = val.(string)
case int: case int:
n.widget.I = a.(int) a.I = val.(int)
default: 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 { func (n *Node) AppendText(str string) {
n.widget.Action = "Set" var a toolkit.Action
a.Type = toolkit.SetText
tmp := n.widget.S + str tmp := n.widget.S + str
log(debugChange, "gui.AppendText() value =", tmp) log(debugChange, "AppendText() value =", tmp)
n.widget.S = tmp a.S = tmp
send(n.parent, n) // a.Widget = &n.widget
return true // action(&a)
newaction(&a, n, nil)
} }
func (n *Node) GetText() string { func (n *Node) GetText() string {
@ -87,11 +147,6 @@ func normalizeInt(s string) string {
return clean return clean
} }
func Delete(c *Node) {
c.widget.Action = "Delete"
send(c.parent, c)
}
func commonCallback(n *Node) { func commonCallback(n *Node) {
// TODO: make all of this common code to all the widgets // TODO: make all of this common code to all the widgets
// This might be common everywhere finally (2023/03/01) // 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 // various debugging flags
var debugNow bool = true // useful for active development
var debugGui bool = false var debugGui bool = false
var debugError bool = false var debugError bool = true
var debugDump bool = false var debugDump bool = false
var debugNode bool = false var debugNode bool = false
var debugTabs bool = false var debugTabs bool = false
var debugFlags bool = false var debugFlags bool = false
var debugChange bool = false // shows user events like mouse and keyboard var debugChange bool = false // shows user events like mouse and keyboard
var debugPlugin bool = false var debugPlugin bool = false
var debugAction bool = false
// for printing out the binary tree // for printing out the binary tree
var listChildrenParent *Node var listChildrenParent *Node
@ -64,12 +66,21 @@ func SetFlag (s string, b bool) {
} }
// send the flag to the toolkit // send the flag to the toolkit
n := Config.flag // n := Config.flag
log(debugChange, "Set() toolkit flag", s, "to", b) // log(debugChange, "Set() toolkit flag", s, "to", b)
n.widget.Action = "Set" // n.widget.Action = "Set"
n.widget.S = s // n.widget.S = s
n.widget.B = b // n.widget.B = b
send(nil, n) // 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() { func ShowDebugValues() {
@ -86,40 +97,47 @@ func ShowDebugValues() {
SetFlag("Show", true) SetFlag("Show", true)
} }
func (n *Node) Dump() { func (n *Node) Dump(b bool) {
if ! debugDump { // log("Dump() dump =", b)
if ! b {
return return
} }
Indent("NODE DUMP START") Indent(b, "NODE DUMP START")
Indent("id = ", n.id) Indent(b, "id = ", n.id)
Indent("Name = ", n.Name) Indent(b, "Name = ", n.Name)
Indent("Width = ", n.Width) Indent(b, "Width = ", n.Width)
Indent("Height = ", n.Height) Indent(b, "Height = ", n.Height)
Indent("Widget Name = ", n.widget.Name) Indent(b, "(X,Y) = ", n.X, n.Y)
Indent("Widget Type = ", n.widget.Type) Indent(b, "Next (X,Y) = ", n.NextX, n.NextY)
Indent("Widget Id = ", n.widget.GetId()) 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) { if (n.parent == nil) {
Indent("parent = nil") Indent(b, "parent = nil")
} else { } else {
Indent("parent.id =", n.parent.id) Indent(b, "parent.id =", n.parent.id)
} }
if (n.children != nil) { if (n.children != nil) {
Indent("children = ", n.children) Indent(b, "children = ", n.children)
} }
if (n.Custom != nil) { 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{}) { func Indent(b bool, a ...interface{}) {
logindent(listChildrenDepth, defaultPadding, a...) logindent(b, listChildrenDepth, defaultPadding, a...)
} }
func (n *Node) dumpWidget() string { func (n *Node) dumpWidget(b bool) string {
var info, d string var info, d string
if (n == nil) {
log(debugError, "dumpWidget() node == nil")
return ""
}
info = n.widget.Type.String() info = n.widget.Type.String()
info += ", " + n.widget.Name info += ", " + n.widget.Name
@ -137,22 +155,18 @@ func (n *Node) dumpWidget() string {
tabs = tabs + defaultPadding tabs = tabs + defaultPadding
} }
d = tabs + d d = tabs + d
logindent(listChildrenDepth, defaultPadding, n.id, info) logindent(b, listChildrenDepth, defaultPadding, n.id, info)
return d return d
} }
func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) { // func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
s := n.dumpWidget() func (n *Node) ListChildren(dump bool) {
if (dropdown != nil) { if (n == nil) {
dropdown.AddDropdownName(s) return
if (mapNodes != nil) {
mapNodes[s] = n
}
} }
if (dump == true) { n.dumpWidget(dump)
n.Dump() // n.Dump(dump)
}
if len(n.children) == 0 { if len(n.children) == 0 {
if (n.parent == nil) { if (n.parent == nil) {
return return
@ -161,7 +175,9 @@ func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node
if (listChildrenParent != nil) { if (listChildrenParent != nil) {
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id) log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
if (listChildrenParent.id != n.parent.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") 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? // 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") 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(debugDump)
child.Dump()
}
if (child.children == nil) { if (child.children == nil) {
log(debugNode, "\t\t", child.id, "has no children") log(debugNode, "\t\t", child.id, "has no children")
} else { } else {
@ -187,7 +201,8 @@ func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node
} }
listChildrenParent = n listChildrenParent = n
listChildrenDepth += 1 listChildrenDepth += 1
child.ListChildren(dump, dropdown, mapNodes) // child.ListChildren(dump, dropdown, mapNodes)
child.ListChildren(dump)
listChildrenDepth -= 1 listChildrenDepth -= 1
} }
return return

View File

@ -33,50 +33,59 @@ func (n *Node) DebugFlags(makeWindow bool) {
}) })
g = w.NewGroup("List") g = w.NewGroup("List")
g = g.NewGrid("flags grid", 2, 2)
// generally useful debugging // generally useful debugging
cb1 := g.NewCheckbox("debug Gui (like verbose=1)") cb1 := g.NewCheckbox("debug Gui")
g.NewLabel("like verbose=1")
cb1.Custom = func() { cb1.Custom = func() {
debugGui = cb1.widget.B debugGui = cb1.widget.B
log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B) log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B)
} }
// errors. by default these always output somewhere // 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() { cbE.Custom = func() {
SetFlag("Error", cbE.widget.B) SetFlag("Error", cbE.widget.B)
} }
// debugging that will show you things like mouse clicks, user inputing text, etc // debugging that will show you things like mouse clicks, user inputing text, etc
// also set toolkit.DebugChange // 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() { cb2.Custom = func() {
SetFlag("Change", cb2.widget.B) SetFlag("Change", cb2.widget.B)
} }
// supposed to tell if you are going to dump full variable output // 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() { cb3.Custom = func() {
SetFlag("Dump", cbE.widget.B) 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() { cb4.Custom = func() {
SetFlag("Tabs", cb4.widget.B) 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() { 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 // 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() { cb5.Custom = func() {
SetFlag("Plugin", cb5.widget.B) SetFlag("Plugin", cb5.widget.B)
} }
// turns on debugging inside the plugin toolkit // 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() { cb7.Custom = func() {
// SetDebugToolkit(cb7.widget.B) // SetDebugToolkit(cb7.widget.B)
SetFlag("Toolkit", cb7.widget.B) SetFlag("Toolkit", cb7.widget.B)

View File

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

View File

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

View File

@ -13,9 +13,18 @@ var bugWidget *Node
// the widget all these actions are run against // the widget all these actions are run against
var activeWidget *Node 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 // the label where the user can see which widget is active
var activeLabel *Node var activeLabel *Node
var activeLabelType *Node var activeLabelType *Node
var activeLabelNewName *Node
var activeLabelNewType *Node
var activeLabelNewX *Node
var activeLabelNewY *Node
var activeLabelNewB *Node
// tmp junk // tmp junk
var debugGrid *Node var debugGrid *Node
@ -37,19 +46,6 @@ func setActiveWidget(w *Node) {
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name
activeLabel.SetText(title) activeLabel.SetText(title)
activeLabelType.SetText("widget.Type = " + w.widget.Type.String()) 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 return
} }
@ -75,108 +71,113 @@ func DebugWidgetWindow(w *Node) {
g := bugWidget.NewGroup("widget:") g := bugWidget.NewGroup("widget:")
activeLabel = g.NewLabel("undef") g2 := g.NewGroup("widget:")
activeLabelType = g.NewLabel("undef") 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 // common things that should work against each widget
g = bugWidget.NewGroup("common things") g = bugWidget.NewGroup("common things")
g.NewButton("Disable()", func () {
activeWidget.widget.Action = "Disable"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Enable()", func () { g.NewButton("Enable()", func () {
activeWidget.widget.Action = "Enable" activeWidget.Enable()
send(activeWidget.parent, activeWidget) })
g.NewButton("Disable()", func () {
activeWidget.Disable()
}) })
g.NewButton("Show()", func () { g.NewButton("Show()", func () {
activeWidget.widget.Action = "Show" activeWidget.Show()
send(activeWidget.parent, activeWidget)
}) })
g.NewButton("Hide()", func () { g.NewButton("Hide()", func () {
activeWidget.widget.Action = "Hide" activeWidget.Hide()
send(activeWidget.parent, activeWidget)
})
g.NewButton("Delete()", func () {
Delete(activeWidget)
}) })
g.NewButton("Dump()", func () { g.NewButton("Dump()", func () {
g := debugGui activeWidget.Dump(true)
d := debugDump
debugGui = true var a toolkit.Action
debugDump = true a.Type = toolkit.Dump
activeWidget.Dump() newaction(&a, activeWidget, nil)
debugGui = g
debugDump = d
}) })
newG := bugWidget.NewGroup("add things") g = bugWidget.NewGroup("add things")
newG.debugAddWidgetButtons() g.debugAddWidgetButton()
g.NewLabel("experiments:")
g.debugAddWidgetButtons()
g = bugWidget.NewGroup("change things") g = bugWidget.NewGroup("change things")
g.NewButton("SetMargin(true)", func () { g.NewButton("AddText()", func () {
activeWidget.widget.Action = "SetMargin" var a toolkit.Action
activeWidget.widget.B = true a.Type = toolkit.AddText
send(activeWidget.parent, activeWidget) a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
}) })
g.NewButton("SetMargin(false)", func () { g.NewButton("SetText()", func () {
activeWidget.widget.Action = "SetMargin" var a toolkit.Action
activeWidget.widget.B = false a.Type = toolkit.SetText
send(activeWidget.parent, activeWidget) a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
}) })
g.NewButton("Value()", func () { g.NewButton("Margin()", func () {
log("activeWidget.B =", activeWidget.widget.B) var a toolkit.Action
log("activeWidget.I =", activeWidget.widget.I) a.Type = toolkit.Margin
log("activeWidget.S =", activeWidget.widget.S) newaction(&a, activeWidget, nil)
}) })
g.NewButton("Set(true)", func () { g.NewButton("Unmargin()", func () {
activeWidget.widget.Action = "Set" var a toolkit.Action
activeWidget.widget.B = true a.Type = toolkit.Unmargin
send(activeWidget.parent, activeWidget) newaction(&a, activeWidget, nil)
}) })
g.NewButton("Set(false)", func () { g.NewButton("Pad()", func () {
activeWidget.widget.Action = "Set" var a toolkit.Action
activeWidget.widget.B = false a.Type = toolkit.Pad
send(activeWidget.parent, activeWidget) newaction(&a, activeWidget, nil)
}) })
g.NewButton("Set(20)", func () { g.NewButton("Unpad()", func () {
activeWidget.widget.Action = "Set" var a toolkit.Action
activeWidget.widget.B = true a.Type = toolkit.Unpad
activeWidget.widget.I = 20 newaction(&a, activeWidget, nil)
activeWidget.widget.S = "20"
send(activeWidget.parent, activeWidget)
}) })
g.NewButton("SetText('foo')", func () { g.NewButton("Move(junk)", func () {
activeWidget.widget.Action = "Set" var a toolkit.Action
activeWidget.widget.S = "foo" a.Type = toolkit.Move
send(activeWidget.parent, activeWidget) newaction(&a, activeWidget, activeJunk)
}) })
g.NewButton("Delete()", func () { g.NewButton("Delete()", func () {
activeWidget.widget.Action = "Delete" var a toolkit.Action
send(activeWidget.parent, activeWidget) a.Type = toolkit.Delete
}) newaction(&a, activeWidget, activeJunk)
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)
}) })
g = bugWidget.NewGroup("not working?") g = bugWidget.NewGroup("not working?")
g.NewButton("Add('foo')", func () { g.NewButton("Dump Widget Values()", func () {
activeWidget.widget.Action = "Add" log("activeWidget.B =", activeWidget.widget.B)
activeWidget.widget.S = "foo" log("activeWidget.I =", activeWidget.widget.I)
send(activeWidget.parent, activeWidget) log("activeWidget.S =", activeWidget.widget.S)
}) log("activeWidget.X =", activeWidget.widget.X)
g.NewButton("Add button to (1,1)", func () { log("activeWidget.Y =", activeWidget.widget.Y)
activeWidget.widget.Action = "AddGrid" log("activeWidget.Width =", activeWidget.widget.Width)
activeWidget.widget.B = false log("activeWidget.Height =", activeWidget.widget.Height)
send(activeWidget, debugGridLabel) log("activeWidget.Margin =", activeWidget.widget.Margin)
// debugGrid = gShoactiveWidget.NewGrid("tmp grid", 2, 3) log("activeWidget.Expand =", activeWidget.widget.Expand)
}) })
activeJunk = bugWidget.NewGroup("junk:")
activeJunk.NewLabel("test junk")
if (activeWidget == nil) { if (activeWidget == nil) {
setActiveWidget(Config.master) setActiveWidget(Config.master)
@ -184,53 +185,20 @@ func DebugWidgetWindow(w *Node) {
} }
func (n *Node) debugAddWidgetButtons() { 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 () { n.NewButton("Dropdown", func () {
a := activeWidget.NewDropdown("tmp dropdown") a := activeWidget.NewDropdown("tmp dropdown")
a.AddDropdownName("this is better than tcl/tk") a.AddText("this is better than tcl/tk")
a.AddDropdownName("make something for tim") a.AddText("make something for tim")
a.AddDropdownName("for qflow") a.AddText("for qflow")
a.Add("and for riscv") a.AddText("and for riscv")
a.Custom = func () { a.Custom = func () {
log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id) log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id)
} }
}) })
n.NewButton("Combobox", func () { n.NewButton("Combobox", func () {
a := activeWidget.NewCombobox("tmp combobox") a := activeWidget.NewCombobox("tmp combobox")
a.Add("mirrors.wit.com") a.AddText("mirrors.wit.com")
a.Add("go.wit.org") a.AddText("go.wit.org")
a.Custom = func () { a.Custom = func () {
log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id) log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id)
} }
@ -245,31 +213,121 @@ func (n *Node) debugAddWidgetButtons() {
// SetDebug(true) // SetDebug(true)
debugGrid = activeWidget.NewGrid("tmp grid", 2, 3) debugGrid = activeWidget.NewGrid("tmp grid", 2, 3)
debugGridLabel = debugGrid.NewLabel("mirrors.wit.com") 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) // SetDebug(false)
DebugWidgetWindow(debugGrid) DebugWidgetWindow(debugGrid)
}) })
n.NewButton("Image", func () { n.NewButton("Image", func () {
activeWidget.NewImage("image") 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 () { n.NewButton("Box(horizontal)", func () {
a := activeWidget.NewBox("hBox", true) a := activeWidget.NewBox("hBox", true)
a.Custom = func () { a.NewLabel("hBox")
log("this code is more better", a.widget.B, "id=", a.id) a.NewLabel("hBox 2")
}
}) })
n.NewButton("Box(vertical)", func () { n.NewButton("Box(vertical)", func () {
a := activeWidget.NewBox("vBox", true) a := activeWidget.NewBox("vBox", false)
a.Custom = func () { a.NewLabel("vBox")
log("this code is more better", a.widget.B, "id=", a.id) 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 package gui
import ( import (
"git.wit.org/wit/gui/toolkit" // "git.wit.org/wit/gui/toolkit"
) )
// TODO: move all this shit into somewhere not global // 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) // time.Sleep(1 * time.Second)
newN = n.NewTab(title) newN = n.NewTab(title)
newN.Dump()
//////////////////////// main debug things ////////////////////////////////// //////////////////////// main debug things //////////////////////////////////
gog = newN.NewGroup("Debugging Windows:") gog = newN.NewGroup("Debugging Windows:")
@ -77,23 +76,11 @@ func (n *Node) DebugTab(title string) *Node {
g2 := newN.NewGroup("node things") 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 () { g2.NewButton("Node.ListChildren(true)", func () {
g := debugGui if (activeWidget == nil) {
d := debugDump activeWidget = Config.master
debugGui = true }
debugDump = true activeWidget.ListChildren(true)
activeWidget.ListChildren(true, nil, nil)
debugGui = g
debugDump = d
}) })
return newN return newN
@ -111,14 +98,15 @@ func dropdownWindow(p *Node) {
log("The Window was set to", name) log("The Window was set to", name)
} }
log(debugGui, "dd =", dd) 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 = "" // var last = ""
for _, child := range Config.master.children { for _, child := range Config.master.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name) 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) dd.AddDropdownName(child.Name)
// last = child.Name // last = child.Name
mapWindows[child.Name] = child mapWindows[child.Name] = child
@ -141,5 +129,21 @@ func dropdownWindowWidgets(p *Node) {
} }
log(debugGui, "dd =", dd) 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 // add a new entry to the dropdown name
func (n *Node) AddDropdownName(name string) { func (n *Node) AddDropdownName(name string) {
n.Add(name) n.AddText(name)
} }
// Set the dropdown menu to 'name' // Set the dropdown menu to 'name'
@ -21,12 +21,26 @@ func (n *Node) SetDropdownName(name string) {
func (n *Node) NewDropdown(name string) *Node { func (n *Node) NewDropdown(name string) *Node {
newNode := n.New(name, toolkit.Dropdown, nil) 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 return newNode
} }
func (n *Node) NewCombobox(name string) *Node { func (n *Node) NewCombobox(name string) *Node {
newNode := n.New(name, toolkit.Combobox, nil) 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 return newNode
} }

47
grid.go
View File

@ -4,34 +4,43 @@ import (
"git.wit.org/wit/gui/toolkit" "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 { func (n *Node) NewGrid(name string, x int, y int) *Node {
newNode := n.New(name, toolkit.Grid, func() { newNode := n.New(name, toolkit.Grid, func() {
log(debugChange, "click() NewGrid not defined =", name) 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 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, b bool) *Node {
func (n *Node) NewBox(name string, horizontal bool) *Node { newNode := n.New(name, toolkit.Box, nil)
var newNode *Node
newNode = n.New(name, toolkit.Box, nil)
newNode.widget.X = 3 var a toolkit.Action
newNode.widget.Y = 1 a.Type = toolkit.Add
newNode.widget.B = horizontal a.B = b
newaction(&a, newNode, n)
send(n, newNode)
return 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" "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 { func (n *Node) NewGroup(name string) *Node {
var newNode *Node var newNode *Node
newNode = n.New(name, toolkit.Group, nil) 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 { func (n *Node) NewImage(name string) *Node {
var newNode *Node var newNode *Node
newNode = n.New(name, toolkit.Image, nil) 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 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. 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) 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 { func (n *Node) Int() int {
return n.widget.I return n.widget.I
} }
@ -23,7 +24,7 @@ func (n *Node) Value() int {
func (n *Node) SetValue(i int) { func (n *Node) SetValue(i int) {
log(debugGui, "gui.SetValue() START") log(debugGui, "gui.SetValue() START")
n.Dump()
// FIXME: this needs to be redone // FIXME: this needs to be redone
// n.toolkit.SetValue(i) // n.toolkit.SetValue(i)
} }
*/

View File

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

5
log.go
View File

@ -122,7 +122,8 @@ func loggo() {
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine()) 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 var tabs string
for i := 0; i < depth; i++ { for i := 0; i < depth; i++ {
tabs = tabs + format 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: // array prepend(). Why isn't this a standard function. It should be:
// a.prepend(debugGui, newFormat) // a.prepend(debugGui, newFormat)
a = append([]any{debugGui, newFormat}, a...) a = append([]any{b, newFormat}, a...)
log(a...) log(a...)
} }

View File

@ -2,7 +2,7 @@ package gui
import ( import (
// "embed" // "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? // 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") Config.master = addNode("guiBinaryTree")
// used to pass debugging flags to the toolkit plugins // 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() { func doGuiChan() {

View File

@ -10,13 +10,12 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
newN = addNode(title) newN = addNode(title)
newN.widget.Type = t newN.widget.Type = t
newN.widget.Action = "New" // newN.widget.Action = "New"
newN.Custom = custom newN.Custom = custom
// TODO: This should not be defined for each widget. This has to be stupid // 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? // or wait a second, is this where I send something to a channel?
newN.widget.Custom = func() { 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) log(debugChange, "Trying to find Window Close. widget.Type =", newN.widget.Type)
if (newN.widget.Type == toolkit.Window) { if (newN.widget.Type == toolkit.Window) {
log(debugChange, "Need to delete newN here") log(debugChange, "Need to delete newN here")
@ -64,9 +63,9 @@ func (n *Node) Append(child *Node) {
n.children = append(n.children, child) n.children = append(n.children, child)
if (debugNode) { if (debugNode) {
log(debugNode, "child node:") log(debugNode, "child node:")
child.Dump() child.Dump(debugDump)
log(debugNode, "parent node:") 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 // simplifies passing to the plugin
Send func(*toolkit.Widget, *toolkit.Widget) Send func(*toolkit.Widget, *toolkit.Widget)
// should replace Send()
Action func(*toolkit.Action)
} }
var allPlugins []*aplug var allPlugins []*aplug
@ -78,7 +81,12 @@ func LoadToolkit(name string) bool {
// Sends a widget (button, checkbox, etc) and it's parent widget // Sends a widget (button, checkbox, etc) and it's parent widget
// This includes instructions like "Add", "Delete", "Disable", etc // 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) allPlugins = append(allPlugins, &newPlug)
@ -128,6 +136,27 @@ func loadFunc2(p *aplug, funcName string) func(*toolkit.Widget, *toolkit.Widget)
return newfunc 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 // This is probably dangerous and should never be done
// executing arbitrary functions will cause them to run inside the goroutine that // executing arbitrary functions will cause them to run inside the goroutine that
// the GUI toolkit itself is running in. TODO: move to channels here // the GUI toolkit itself is running in. TODO: move to channels here
@ -201,15 +230,97 @@ func loadfile(filename string) *plugin.Plugin {
return plug return plug
} }
/*
// Sends a widget and what to do with it to the plugin // Sends a widget and what to do with it to the plugin
// parent = n, child = c // parent = n, child = c
func send(p *Node, c *Node) { func send(p *Node, c *Node) {
for _, aplug := range allPlugins { for _, aplug := range allPlugins {
log(debugPlugin, "Send() aplug =", aplug.name, "type=", c.widget.Type, "action=", c.widget.Action, "name=", c.widget.Name) log(debugPlugin, "Send() aplug =", aplug.name, "type=", c.widget.Type, "action=", c.widget.Action, "name=", c.widget.Name)
if (aplug.Send == nil) { if (aplug.Send == nil) {
log(debugPlugin, "\tSend() failed (aplug.Selete = nil) for", aplug.name) log(debugPlugin, "Failed. Send() == nil for", aplug.name)
continue continue
} }
aplug.Send(&c.parent.widget, &c.widget) 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() { newNode := n.New(name, toolkit.Slider, func() {
log(debugGui, "even newer clicker() name in NewSlider name =", name) 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 return newNode
} }

View File

@ -6,11 +6,17 @@ import (
func (n *Node) NewSpinner(name string, x int, y int) *Node { func (n *Node) NewSpinner(name string, x int, y int) *Node {
newNode := n.New(name, toolkit.Spinner, func() { 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 return newNode
} }

View File

@ -59,11 +59,25 @@ type Node struct {
widget toolkit.Widget widget toolkit.Widget
// deprecate these and use toolkit.Widget
Name string Name string
// used for Windows
Width int Width int
Height 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 // this function is run when there are mouse or keyboard events
Custom func() Custom func()

5
tab.go
View File

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

View File

@ -6,9 +6,15 @@ import (
func (n *Node) NewTextbox(name string) *Node { func (n *Node) NewTextbox(name string) *Node {
newNode := n.New(name, toolkit.Textbox, func() { 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 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 package main
import "github.com/andlabs/ui" import (
import _ "github.com/andlabs/ui/winmanifest" "git.wit.org/wit/gui/toolkit"
// create a new box "github.com/andlabs/ui"
func (t *andlabsT) getBox() *ui.Box { _ "github.com/andlabs/ui/winmanifest"
return t.uiBox )
// 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 // make new Box using andlabs/ui
func (t *andlabsT) newBox() *andlabsT { func (t *andlabsT) rawBox(title string, b bool) *andlabsT {
log(debugToolkit, "newBox() START create default") var newt andlabsT
t.Dump(debugToolkit) var box *ui.Box
if (t.uiGroup != nil) { newt.Name = title
log(debugToolkit, "\tnewBox() is a Group")
var newTK andlabsT
vbox := ui.NewVerticalBox() log(debugToolkit, "rawBox() create", newt.Name)
vbox.SetPadded(padded)
t.uiGroup.SetChild(vbox)
newTK.uiBox = vbox
return &newTK if (b) {
box = ui.NewHorizontalBox()
} else {
box = ui.NewVerticalBox()
} }
if (t.uiBox != nil) { box.SetPadded(padded)
log(debugToolkit, "\tnewBox() is a Box")
var newTK andlabsT
vbox := ui.NewVerticalBox() newt.uiBox = box
vbox.SetPadded(padded) newt.uiControl = box
t.uiBox.Append(vbox, stretchy)
newTK.uiBox = vbox
newTK.Name = t.Name
return &newTK return &newt
}
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
} }

View File

@ -7,24 +7,23 @@ import (
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
) )
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) { func newButton(a *toolkit.Action) {
var t, newt *andlabsT var t, newt *andlabsT
var b *ui.Button var b *ui.Button
w := a.Widget
log(debugToolkit, "newButton()", w.Name) log(debugToolkit, "newButton()", w.Name)
t = mapToolkits[parentW] t = mapToolkits[a.Where]
if (t == nil) { 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 return
} }
if t.broken() {
return
}
newt = new(andlabsT) newt = new(andlabsT)
b = ui.NewButton(w.Name) b = ui.NewButton(w.Name)
newt.uiButton = b newt.uiButton = b
newt.uiControl = b
newt.tw = w newt.tw = w
newt.parent = t newt.parent = t
@ -32,66 +31,6 @@ func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
newt.commonChange(newt.tw) newt.commonChange(newt.tw)
}) })
log(debugToolkit, "newButton() about to append to Box parent t:", w.Name) place(a, t, newt)
log(debugToolkit, "newButton() about to append to Box new t:", w.Name) mapWidgetsToolkits(a, newt)
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")
}
} }

View File

@ -11,14 +11,8 @@ func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
var newt andlabsT var newt andlabsT
newt.tw = w newt.tw = w
if t.broken() {
return nil
}
newt.uiCheckbox = ui.NewCheckbox(w.Name) newt.uiCheckbox = ui.NewCheckbox(w.Name)
newt.uiBox = t.uiBox newt.uiControl = newt.uiCheckbox
// t.doAppend(&newt, *newt.uiCheckbox)
t.uiBox.Append(newt.uiCheckbox, stretchy)
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) { newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
newt.tw.B = newt.checked() newt.tw.B = newt.checked()
@ -30,14 +24,12 @@ func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
} }
func (t *andlabsT) checked() bool { func (t *andlabsT) checked() bool {
if t.broken() {
return false
}
return t.uiCheckbox.Checked() 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) log(debugToolkit, "newCheckbox()", w.Name)
t := mapToolkits[parentW] t := mapToolkits[parentW]
@ -46,45 +38,6 @@ func newCheckbox(parentW *toolkit.Widget, w *toolkit.Widget) {
return return
} }
newt := t.newCheckbox(w) newt := t.newCheckbox(w)
mapWidgetsToolkits(w, newt) place(a, t, newt)
} mapWidgetsToolkits(a, 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")
}
} }

View File

@ -10,15 +10,10 @@ func (t *andlabsT) newCombobox(w *toolkit.Widget) *andlabsT {
var newt andlabsT var newt andlabsT
log(debugToolkit, "newCombobox() START", w.Name) log(debugToolkit, "newCombobox() START", w.Name)
if t.broken() {
return nil
}
newt.tw = w newt.tw = w
s := ui.NewEditableCombobox() s := ui.NewEditableCombobox()
newt.uiEditableCombobox = s newt.uiEditableCombobox = s
newt.uiBox = t.uiBox newt.uiControl = s
t.uiBox.Append(s, stretchy)
// initialize the index // initialize the index
newt.c = 0 newt.c = 0
@ -46,7 +41,9 @@ func (t *andlabsT) AddComboboxName(title string) {
t.c = t.c + 1 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) log(debugToolkit, "newCombobox()", w.Name)
t := mapToolkits[parentW] t := mapToolkits[parentW]
@ -56,45 +53,6 @@ func newCombobox(parentW *toolkit.Widget, w *toolkit.Widget) {
return return
} }
newt := t.newCombobox(w) newt := t.newCombobox(w)
mapWidgetsToolkits(w, newt) place(a, t, newt)
} mapWidgetsToolkits(a, 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")
}
} }

View File

@ -2,11 +2,10 @@ package main
import ( import (
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
// "github.com/davecgh/go-spew/spew"
) )
func (t *andlabsT) commonChange(tw *toolkit.Widget) { 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) { if (tw == nil) {
log(true, "commonChange() What the fuck. there is no widget t.tw == nil") log(true, "commonChange() What the fuck. there is no widget t.tw == nil")
return return
@ -19,44 +18,6 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget) {
log(debugChange, "commonChange() END Widget.Custom()", t.tw.Name, t.tw.Type) 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) { func dump(p *toolkit.Widget, c *toolkit.Widget, b bool) {
log(b, "Parent:") log(b, "Parent:")
pt := mapToolkits[p] pt := mapToolkits[p]

View File

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

View File

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

View File

@ -10,15 +10,10 @@ func (t *andlabsT) newDropdown(w *toolkit.Widget) *andlabsT {
var newt andlabsT var newt andlabsT
log(debugToolkit, "gui.Toolbox.newDropdown() START", w.Name) log(debugToolkit, "gui.Toolbox.newDropdown() START", w.Name)
if t.broken() {
return nil
}
newt.tw = w newt.tw = w
s := ui.NewCombobox() s := ui.NewCombobox()
newt.uiCombobox = s newt.uiCombobox = s
newt.uiBox = t.uiBox newt.uiControl = s
t.uiBox.Append(s, stretchy)
// initialize the index // initialize the index
newt.c = 0 newt.c = 0
@ -57,16 +52,16 @@ func (t *andlabsT) SetDropdown(i int) {
t.uiCombobox.SetSelected(i) t.uiCombobox.SetSelected(i)
} }
func AddDropdownName(w *toolkit.Widget, s string) { func AddDropdownName(a *toolkit.Action) {
log(debugToolkit, "gui.andlabs.AddDropdownName()", w.Name, "add:", s) log(debugToolkit, "gui.andlabs.AddDropdownName()", a.Widget.Name, "add:", a.S)
t := mapToolkits[w] t := mapToolkits[a.Widget]
if (t == nil) { 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) listMap(debugToolkit)
return return
} }
t.AddDropdownName(s) t.AddDropdownName(a.S)
} }
func SetDropdownName(w *toolkit.Widget, s string) { func SetDropdownName(w *toolkit.Widget, s string) {
@ -82,7 +77,9 @@ func SetDropdownName(w *toolkit.Widget, s string) {
t.tw.S = s 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) log(debugToolkit, "gui.andlabs.newDropdown()", w.Name)
t := mapToolkits[parentW] t := mapToolkits[parentW]
@ -92,68 +89,6 @@ func newDropdown(parentW *toolkit.Widget, w *toolkit.Widget) {
return return
} }
newt := t.newDropdown(w) newt := t.newDropdown(w)
mapWidgetsToolkits(w, newt) place(a, t, newt)
} mapWidgetsToolkits(a, 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")
}
} }

View File

@ -12,80 +12,21 @@ import (
// -- (1,1) -- (2,1) -- (3,1) -- // -- (1,1) -- (2,1) -- (3,1) --
// -- (1,2) -- (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 var newt *andlabsT
log(debugToolkit, "NewGrid()", w.Name) log(debugToolkit, "newGrid()", a.Widget.Name, "to", a.Where.Type)
t := mapToolkits[parentW] t := mapToolkits[a.Where]
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
}
newt = new(andlabsT) newt = new(andlabsT)
c := ui.NewGrid() c := ui.NewGrid()
newt.uiGrid = c newt.uiGrid = c
newt.uiBox = t.uiBox newt.uiControl = c
newt.tw = w newt.tw = a.Widget
t.doAppend(toolkit.Grid, newt, nil) newt.gridX = 0
mapWidgetsToolkits(w, newt) newt.gridY = 0
}
func doGrid(p *toolkit.Widget, c *toolkit.Widget) { place(a, t, newt)
if broken(c) { mapWidgetsToolkits(a, newt)
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")
}
} }

View File

@ -7,7 +7,9 @@ import (
_ "github.com/andlabs/ui/winmanifest" _ "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) log(debugToolkit, "NewGroup()", w.Name)
t := mapToolkits[parentW] t := mapToolkits[parentW]
@ -16,7 +18,8 @@ func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
listMap(debugToolkit) listMap(debugToolkit)
} }
newt := t.rawGroup(w.Name) newt := t.rawGroup(w.Name)
mapWidgetsToolkits(w, newt) place(a, t, newt)
mapWidgetsToolkits(a, newt)
} }
// make new Group here // make new Group here
@ -29,69 +32,15 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
g := ui.NewGroup(newt.Name) g := ui.NewGroup(newt.Name)
g.SetMargined(margin) g.SetMargined(margin)
newt.uiGroup = g newt.uiGroup = g
newt.uiControl = g
t.doAppend(toolkit.Group, &newt, nil) // hbox := ui.NewVerticalBox()
// hbox.SetPadded(padded)
// g.SetChild(hbox)
hbox := ui.NewVerticalBox() // newt.uiBox = hbox
hbox.SetPadded(padded) // newt.uiWindow = t.uiWindow
g.SetChild(hbox) // newt.uiTab = t.uiTab
newt.uiBox = hbox
newt.uiWindow = t.uiWindow
newt.uiTab = t.uiTab
return &newt 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" "git.wit.org/wit/gui/toolkit"
) )
func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) { func newLabel(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget
log(debugToolkit, "NewLabel()", w.Name) log(debugToolkit, "NewLabel()", w.Name)
t := mapToolkits[parentW] t := mapToolkits[a.Where]
if (t == nil) { if (t == nil) {
listMap(debugError) listMap(debugError)
log(debugError, "ERROR newLabel() listMap()") log(debugError, "ERROR newLabel() listMap()")
@ -21,68 +22,13 @@ func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
} }
log(debugToolkit, "NewLabel()", w.Name) log(debugToolkit, "NewLabel()", w.Name)
if t.broken() {
return
}
newt = new(andlabsT) newt = new(andlabsT)
c := ui.NewLabel(w.Name) c := ui.NewLabel(w.Name)
newt.uiLabel = c newt.uiLabel = c
newt.uiControl = c
newt.uiBox = t.uiBox place(a, t, newt)
newt.tw = w mapWidgetsToolkits(a, newt)
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")
}
} }

View File

@ -19,73 +19,224 @@ import "git.wit.org/wit/gui/toolkit"
// TODO: make sure you can't escape this goroutine // TODO: make sure you can't escape this goroutine
// //
func Send(p *toolkit.Widget, c *toolkit.Widget) { func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) { log(debugPlugin, "Send() goodbye. not used anymore")
log(debugPlugin, "Send() parent = nil") }
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
/* func Action(a *toolkit.Action) {
if (c.Action == "SetMargin") { if (a == nil) {
log(debugError, "need to implement SetMargin here") log(debugPlugin, "Action = nil")
setMargin(c, c.B)
return return
} }
*/ f := func() {
rawAction(a)
}
switch c.Type { // f()
case toolkit.Window: Queue(f)
doWindow(c) }
case toolkit.Tab:
doTab(p, c) func rawAction(a *toolkit.Action) {
case toolkit.Group:
doGroup(p, c) log(debugAction, "Action() START a.Type =", a.Type)
case toolkit.Button: log(debugAction, "Action() START a.S =", a.S)
doButton(p, c) log(debugAction, "Action() START a.Widget =", a.Widget)
case toolkit.Checkbox:
doCheckbox(p, c) switch a.Type {
case toolkit.Label: case toolkit.Add:
doLabel(p, c) add(a)
case toolkit.Textbox: case toolkit.Show:
doTextbox(p, c) a.Widget.B = true
case toolkit.Slider: show(a.Widget)
doSlider(p, c) case toolkit.Hide:
case toolkit.Spinner: a.Widget.B = false
doSpinner(p, c) show(a.Widget)
case toolkit.Dropdown: case toolkit.Enable:
doDropdown(p, c) a.Widget.B = true
case toolkit.Combobox: enable(a.Widget)
doCombobox(p, c) case toolkit.Disable:
case toolkit.Grid: a.Widget.B = false
doGrid(p, c) enable(a.Widget)
case toolkit.Flag: case toolkit.Get:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type) setText(a)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type) case toolkit.GetText:
// log(debugFlags, "plugin Send() flag child.Action =", c.Action) switch a.Widget.Type {
// log(debugFlags, "plugin Send() flag child.S =", c.S) case toolkit.Textbox:
// log(debugFlags, "plugin Send() flag child.B =", c.B) t := mapToolkits[a.Widget]
// log(debugFlags, "plugin Send() what to flag?") a.S = t.s
// 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)
} }
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: default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type) log(debugError, "Action() Unknown =", a.Type, a.Widget)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type) }
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet") 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) log(debugToolkit, w.Name, w.Type, w.X, w.Y)
var newt andlabsT 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) s := ui.NewSlider(w.X, w.Y)
newt.uiSlider = s newt.uiSlider = s
newt.uiBox = t.uiBox newt.uiControl = s
newt.tw = w newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(spin *ui.Slider) { s.OnChanged(func(spin *ui.Slider) {
newt.tw.I = newt.uiSlider.Value() newt.tw.I = newt.uiSlider.Value()
@ -33,8 +25,10 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
return &newt return &newt
} }
func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) { func newSlider(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget
parentW := a.Where
log(debugToolkit, "newSlider()", w.Name) log(debugToolkit, "newSlider()", w.Name)
t := mapToolkits[parentW] 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) log(debugError, "newSlider() ERROR toolkit struct == nil. name=", parentW.Name, w.Name)
return return
} }
w.X = a.X
w.Y = a.Y
newt = t.newSlider(w) newt = t.newSlider(w)
mapWidgetsToolkits(w, newt) place(a, t, newt)
} mapWidgetsToolkits(a, 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")
}
} }

View File

@ -12,16 +12,10 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
log(debugToolkit, "newSpinner()", w.X, w.Y) log(debugToolkit, "newSpinner()", w.X, w.Y)
var newt andlabsT 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) s := ui.NewSpinbox(w.X, w.Y)
newt.uiSpinbox = s newt.uiSpinbox = s
newt.uiBox = t.uiBox newt.uiControl = s
newt.tw = w newt.tw = w
t.uiBox.Append(s, stretchy)
s.OnChanged(func(s *ui.Spinbox) { s.OnChanged(func(s *ui.Spinbox) {
newt.tw.I = newt.uiSpinbox.Value() newt.tw.I = newt.uiSpinbox.Value()
@ -31,61 +25,19 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
return &newt return &newt
} }
func newSpinner(parentW *toolkit.Widget, w *toolkit.Widget) { func newSpinner(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget
parentW := a.Where
t := mapToolkits[parentW] t := mapToolkits[parentW]
if (t == nil) { if (t == nil) {
log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name) log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name)
return return
} }
w.X = a.X
w.Y = a.Y
newt = t.newSpinner(w) newt = t.newSpinner(w)
mapWidgetsToolkits(w, newt) place(a, t, newt)
} mapWidgetsToolkits(a, 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")
}
} }

View File

@ -10,15 +10,16 @@ type andlabsT struct {
id string id string
Name string Name string
Type toolkit.WidgetType // Type toolkit.WidgetType
Width int Width int
Height int Height int
tw *toolkit.Widget tw *toolkit.Widget
parent *andlabsT parent *andlabsT
uiControl ui.Control
uiBox *ui.Box uiBox *ui.Box
uiButton *ui.Button uiButton *ui.Button
uiControl *ui.Control
uiCombobox *ui.Combobox uiCombobox *ui.Combobox
uiCheckbox *ui.Checkbox uiCheckbox *ui.Checkbox
uiEntry *ui.Entry uiEntry *ui.Entry
@ -31,11 +32,21 @@ type andlabsT struct {
uiMultilineEntry *ui.MultilineEntry uiMultilineEntry *ui.MultilineEntry
uiEditableCombobox *ui.EditableCombobox uiEditableCombobox *ui.EditableCombobox
uiGrid *ui.Grid uiGrid *ui.Grid
uiImage *ui.Image
gridX int
gridY int
// used as a counter to work around limitations of widgets like combobox // 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 // 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 // but it's working for now due to the need for need for a correct interaction layer betten toolkits
c int c int
i int
b bool
s string
val map[int]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 text string
} }

View File

@ -54,11 +54,11 @@ func (t *andlabsT) newTab(name string) *andlabsT {
// This sets _all_ the tabs to Margin = true // This sets _all_ the tabs to Margin = true
// //
// TODO: do proper tab tracking (will be complicated). low priority // 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() c := tab.NumPages()
for i := 0; i < c; i++ { for i := 0; i < c; i++ {
log(debugToolkit, "SetMargined", i, margin) log(debugToolkit, "SetMargined", i, b)
tab.SetMargined(i, margin) 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 := ui.NewHorizontalBox() // this makes everything go along the horizon
hbox.SetPadded(padded) hbox.SetPadded(padded)
tab.Append(name, hbox) 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) w.SetChild(tab)
newt.uiWindow = w newt.uiWindow = w
newt.uiTab = tab newt.uiTab = tab
newt.uiControl = tab
newt.uiBox = hbox newt.uiBox = hbox
return &newt return &newt
} }
@ -118,7 +119,9 @@ func (t *andlabsT) appendTab(name string) *andlabsT {
return &newT return &newT
} }
func newTab(parentW *toolkit.Widget, w *toolkit.Widget) { func newTab(a *toolkit.Action) {
parentW := a.Where
w := a.Widget
var newt *andlabsT var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name) log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
@ -128,55 +131,9 @@ func newTab(parentW *toolkit.Widget, w *toolkit.Widget) {
return return
} }
newt = t.newTab(w.Name) newt = t.newTab(w.Name)
mapWidgetsToolkits(w, newt) mapWidgetsToolkits(a, newt)
} }
func doTab(p *toolkit.Widget, c *toolkit.Widget) { func doTab(a *toolkit.Action) {
if broken(c) { newTab(a)
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")
}
} }

View File

@ -7,142 +7,38 @@ import (
_ "github.com/andlabs/ui/winmanifest" _ "github.com/andlabs/ui/winmanifest"
) )
func newTextbox(parentW *toolkit.Widget, w *toolkit.Widget) { // func newTextbox(a *toolkit.Action) {
log(debugToolkit, "NewTexbox()", w.Name) func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
var newt andlabsT
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
}
c := ui.NewNonWrappingMultilineEntry() c := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = c newt.uiMultilineEntry = c
newt.uiControl = c
newt.uiBox = t.uiBox
newt.Name = w.Name newt.Name = w.Name
newt.tw = w 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) { c.OnChanged(func(spin *ui.MultilineEntry) {
w.S = newt.uiMultilineEntry.Text() t.s = spin.Text()
// this is still dangerous // this is still dangerous
// newt.commonChange(newt.tw) // newt.commonChange(newt.tw)
log(debugChange, "Not yet safe to trigger on change for ui.MultilineEntry") 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) { t := mapToolkits[parentW]
if broken(c) { if (t == nil) {
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", parentW.Name, w.Name)
listMap(debugToolkit)
return return
} }
if (c.Action == "New") { newt := t.newTextbox(w)
newTextbox(p, c) place(a, t, newt)
return mapWidgetsToolkits(a, newt)
}
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")
}
} }

View File

@ -9,10 +9,11 @@ import (
var mapWidgets map[*andlabsT]*toolkit.Widget var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT 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) { func listMap(b bool) {
log(b, "listMap() HERE") log(b, "listMap() disabled HERE. output too big")
log(b, "listMap() HERE") return
for t, w := range mapWidgets { for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name) log(b, "andlabs =", t.Name, "widget =", w.Name)
} }
@ -25,7 +26,8 @@ func listMap(b bool) {
log(b, "listMap() HERE FIXME. output too big") 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)) { if ((mapToolkits[w] == nil) && (mapWidgets[t] == nil)) {
log(debugToolkit, "map a new widget", w, t) log(debugToolkit, "map a new widget", w, t)
mapToolkits[w] = t mapToolkits[w] = t
@ -63,5 +65,5 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
widgetDump(debugError, wt) 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) ui.MsgBoxError(t.uiWindow, msg1, msg2)
} }
func newWindow(w *toolkit.Widget) { func newWindow(a *toolkit.Action) {
w := a.Widget
var newt *andlabsT var newt *andlabsT
log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height) log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
@ -37,10 +38,11 @@ func newWindow(w *toolkit.Widget) {
}) })
win.Show() win.Show()
newt.uiWindow = win newt.uiWindow = win
newt.uiControl = win
// newt.UiWindowBad = win // deprecate this as soon as possible // newt.UiWindowBad = win // deprecate this as soon as possible
newt.Name = w.Name newt.Name = w.Name
mapWidgetsToolkits(w, newt) mapWidgetsToolkits(a, newt)
return return
} }
@ -54,46 +56,6 @@ func (t *andlabsT) SetWindowTitle(title string) {
} }
} }
func doWindow(c *toolkit.Widget) { func doWindow(a *toolkit.Action) {
if broken(c) { newWindow(a)
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")
}
} }

View File

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

View File

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

View File

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

View File

@ -1,18 +1,24 @@
package toolkit package toolkit
type WidgetType int
type ActionType int
// passes information between the toolkit library (plugin) // passes information between the toolkit library (plugin)
// //
// All Toolkit interactions should be done via a channel or Queue() // 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 // This is the only thing that is passed between the toolkit plugin
// //
// what names should be used? This is not part of [[Graphical Widget]] // 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?) // Could a protobuf be used here? (Can functions be passed?)
type Widget struct { type Widget struct {
Name string Name string
Action string // "New", "Delete", "Set", aka something to do // Action string // "New", "Delete", "Set", aka something to do
Type WidgetType Type WidgetType
// This function is how you interact with the toolkit // 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 // Hopefully this will be the barrier between the goroutines
// TODO: move this interaction to channels // TODO: move this interaction to channels
Custom func() Custom func()
Callback func()
// re-adding an id to test channels // re-adding an id to test channels
id int id int
@ -48,26 +55,88 @@ type Widget struct {
Expand bool 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/ // https://ieftimov.com/post/golang-datastructures-trees/
// TODO: protobuf ?
const ( const (
Unknown WidgetType = iota Unknown WidgetType = iota
Window Window
Tab Tab // internally, this should be a window (?)
Group Frame // should windows and tab's be frames (?)
Frame Grid // a grid of frames ?
Group // internally, this should be a grid (?)
Box // internally, this should be a grid (?)
Button Button
Checkbox Checkbox
Dropdown Dropdown
Combobox Combobox // dropdown with edit=true (?)
Label Label
Textbox Textbox // is this a Label with edit=true?
Slider Slider
Spinner Spinner
Grid
Box
Image 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 Flag
) )
@ -77,10 +146,14 @@ func (s WidgetType) String() string {
return "Window" return "Window"
case Tab: case Tab:
return "Tab" return "Tab"
case Group:
return "Group"
case Frame: case Frame:
return "Frame" return "Frame"
case Grid:
return "Grid"
case Group:
return "Group"
case Box:
return "Box"
case Button: case Button:
return "Button" return "Button"
case Checkbox: case Checkbox:
@ -97,18 +170,68 @@ func (s WidgetType) String() string {
return "Slider" return "Slider"
case Spinner: case Spinner:
return "Spinner" return "Spinner"
case Grid:
return "Grid"
case Box:
return "Box"
case Image: case Image:
return "Image" return "Image"
case Flag: case Area:
return "Flag" return "Area"
case Form:
return "Form"
case Font:
return "Font"
case Color:
return "Color"
case Dialog:
return "Dialog"
case Unknown: case Unknown:
return "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 // 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) log(debugGui, "Window()", Config.Title)
send(nil, newNode) var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, Config.master)
return newNode return newNode
} }