Add slander and spinbox in toolkit/andlabs

fix the helloworld demo
    move slider into toolkit/
    move more into the toolkit directory
    add spinbox()
    fix example
    minor update
    fix examples
    Fix andlabs.ui.Slider() to work again
    correctly implement custom OnChange() callback

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2022-10-16 08:07:13 -05:00
parent 9076499b30
commit fbf97443d5
19 changed files with 331 additions and 160 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.swp *.swp
cmds/gui-example/gui-example cmds/gui-example/gui-example
cmds/gui-demo/gui-demo cmds/gui-demo/gui-demo
cmds/helloworld/helloworld

View File

@ -10,4 +10,9 @@ update:
go get -v -t -u ./... go get -v -t -u ./...
examples: examples:
make -C gui-example make -C cmds/helloworld
make -C cmds/gui-example
make -C cmds/gui-demo
doc:
godoc -v

18
box.go
View File

@ -192,6 +192,7 @@ func (n *Node) AddComboBox(title string, s ...string) *Node {
return n return n
} }
newNode := n.AddNode(title)
ecbox := ui.NewEditableCombobox() ecbox := ui.NewEditableCombobox()
for id, name := range s { for id, name := range s {
@ -202,18 +203,27 @@ func (n *Node) AddComboBox(title string, s ...string) *Node {
ecbox.OnChanged(func(*ui.EditableCombobox) { ecbox.OnChanged(func(*ui.EditableCombobox) {
test := ecbox.Text() test := ecbox.Text()
log.Println("node.Name = '" + n.Name + "' text for '" + title + "' is now: '" + test + "'") log.Println("node.Name = '" + n.Name + "' text for '" + title + "' is now: '" + test + "'")
log.Println("need to call node.OnChanged() here")
if (newNode.OnChanged == nil) {
log.Println("node.OnChanged() is nil")
log.Println("need to call node.OnChanged() here", newNode.OnChanged)
newNode.Dump()
} else {
log.Println("need to call node.OnChanged() here", newNode.OnChanged)
newNode.OnChanged(newNode)
}
}) })
box.Append(ecbox, false) box.Append(ecbox, false)
newNode := n.AddNode(title)
newNode.uiText = ecbox newNode.uiText = ecbox
return newNode return newNode
} }
func (n *Node) OnChanged(f func()) { //func (n *Node) OnChanged(f func()) {
f() // log.Println("not doing shit here in Node.OnChanged()")
} // f()
//}
func (n *Node) GetText() string { func (n *Node) GetText() string {
if (n.uiText == nil) { if (n.uiText == nil) {

View File

@ -2,5 +2,5 @@ run: build
./gui-example ./gui-example
build: build:
GO111MODULE="off" go -v get . GO111MODULE="off" go get -v .
GO111MODULE="off" go build GO111MODULE="off" go build

View File

@ -33,9 +33,9 @@ func addDemoTab(n *gui.Node, title string) {
groupNode1 := newNode.AddGroup("group 1") groupNode1 := newNode.AddGroup("group 1")
cbNode := groupNode1.AddComboBox("username", "root", "jcarr", "hugo") cbNode := groupNode1.AddComboBox("username", "root", "jcarr", "hugo")
cbNode.OnChanged(func () { cbNode.OnChanged = func (cbNode *gui.Node) {
username = cbNode.GetText() username = cbNode.GetText()
}) }
groupNode1.AddComboBox("demoCombo3", "foo 3", "bar", "stuff") groupNode1.AddComboBox("demoCombo3", "foo 3", "bar", "stuff")
groupNode1.Dump() groupNode1.Dump()

14
cmds/helloworld/Makefile Normal file
View File

@ -0,0 +1,14 @@
run: build
./helloworld
build:
go get -v -u -x .
go build
build-master:
GO111MODULE="off" go get -v -x .
GO111MODULE="off" go build
./helloworld
update:
GO111MODULE="off" go get -v -u -x .

View File

@ -2,6 +2,8 @@
package main package main
import ( import (
"os"
"log"
"git.wit.org/wit/gui" "git.wit.org/wit/gui"
) )
@ -14,6 +16,8 @@ func initGUI() {
gui.Config.Title = "Hello World golang wit/gui Window" gui.Config.Title = "Hello World golang wit/gui Window"
gui.Config.Width = 640 gui.Config.Width = 640
gui.Config.Height = 480 gui.Config.Height = 480
gui.Config.Exit = myDefaultExit
node1 := gui.NewWindow() node1 := gui.NewWindow()
addDemoTab(node1, "A Simple Tab Demo") addDemoTab(node1, "A Simple Tab Demo")
addDemoTab(node1, "A Second Tab") addDemoTab(node1, "A Second Tab")
@ -25,3 +29,9 @@ func addDemoTab(n *gui.Node, title string) {
groupNode1 := newNode.AddGroup("group 1") groupNode1 := newNode.AddGroup("group 1")
groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
} }
func myDefaultExit(n *gui.Node) {
log.Println("You can Do exit() things here")
os.Exit(0)
}

20
doc.go
View File

@ -42,28 +42,14 @@ sections below for further details on formatting and configuration options.
groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
} }
Configuration Options
Configuration of the GUI is handled by fields in the ConfigType type. For
convenience, all of the top-level functions use a global state available
via the gui.Config global.
The following configuration options are available:
* Width
When creating a new window, this is the width
* Height
When creating a new window, this is the height
* Debug
When 'true' log more output
Toolkit Usage Toolkit Usage
Right now, this abstraction is built on top of the go package 'andlabs/ui' Right now, this abstraction is built on top of the go package 'andlabs/ui'
which does the cross platform support. which does the cross platform support.
The next step is to intent is to allow this to work directly against GTK and QT. The next step is to intent is to allow this to work directly against GTK and QT.
It should be able to add Fyne, WASM, native macos & windows, android, etc.
It should be able to add Fyne, WASM, native macos & windows, android and
hopefully also things like libSDL, faiface/pixel, slint
Errors Errors

111
entry.go
View File

@ -1,7 +1,7 @@
package gui package gui
import "log" import "log"
import "fmt" // import "fmt"
import "github.com/andlabs/ui" import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
@ -15,10 +15,8 @@ func NewLabel(box *GuiBox, text string) {
func (n *Node) NewLabel(text string) *Node { func (n *Node) NewLabel(text string) *Node {
// make new node here // make new node here
// n.Append(ui.NewLabel(text), false)
newNode := makeNode(n, text, 333, 334) newNode := makeNode(n, text, 333, 334)
newNode.Dump() newNode.Dump()
// panic("node.NewLabel()")
n.Append(newNode) n.Append(newNode)
return newNode return newNode
@ -52,110 +50,3 @@ func (n *Node) SetText(value string) error {
} }
return nil return nil
} }
func SetText(box *GuiBox, name string, value string) error {
if (box == nil) {
return fmt.Errorf("gui.SetText() ERROR box == nil")
}
if (box.Window.EntryMap == nil) {
return fmt.Errorf("gui.SetText() ERROR b.Box.Window.EntryMap == nil")
}
spew.Dump(box.Window.EntryMap)
if (box.Window.EntryMap[name] == nil) {
return fmt.Errorf("gui.SetText() ERROR box.Window.EntryMap[" + name + "] == nil ")
}
e := box.Window.EntryMap[name]
log.Println("gui.SetText() box.Window.EntryMap[", name, "] = ", e.UiEntry.Text())
e.UiEntry.SetText(value)
log.Println("gui.SetText() box.Window.EntryMap[", name, "] = ", e.UiEntry.Text())
log.Println("gui.SetText() END")
return nil
}
// makeEntryBox(box, "hostname:", "blah.foo.org") {
func MakeEntryVbox(box *GuiBox, a string, startValue string, edit bool, action string) *GuiEntry {
// Start 'Nickname' vertical box
vboxN := ui.NewVerticalBox()
vboxN.SetPadded(true)
vboxN.Append(ui.NewLabel(a), false)
e := defaultMakeEntry(startValue, edit, action)
vboxN.Append(e.UiEntry, false)
box.UiBox.Append(vboxN, false)
// End 'Nickname' vertical box
return e
}
func MakeEntryHbox(box *GuiBox, a string, startValue string, edit bool, action string) *GuiEntry {
hboxN := ui.NewHorizontalBox()
hboxN.SetPadded(true)
hboxN.Append(ui.NewLabel(a), false)
e := defaultMakeEntry(startValue, edit, action)
hboxN.Append(e.UiEntry, true)
box.UiBox.Append(hboxN, true)
return e
}
func AddEntry(box *GuiBox, name string) *GuiEntry {
var ge *GuiEntry
ge = new(GuiEntry)
ue := ui.NewEntry()
ue.SetReadOnly(false)
ue.OnChanged(func(*ui.Entry) {
log.Println("gui.AddEntry() OK. ue.Text() =", ue.Text())
})
box.UiBox.Append(ue, false)
ge.UiEntry = ue
box.Window.EntryMap[name] = ge
return ge
}
func defaultEntryChange(e *ui.Entry) {
for key, em := range Data.AllEntries {
if (Config.Debug) {
log.Println("\tdefaultEntryChange() Data.AllEntries =", key, em)
}
if Data.AllEntries[key].UiEntry == e {
log.Println("defaultEntryChange() FOUND",
"Name =", Data.AllEntries[key].Name,
"Last =", Data.AllEntries[key].Last,
"e.Text() =", e.Text())
Data.AllEntries[key].Last = e.Text()
if Data.AllEntries[key].Normalize != nil {
fixed := Data.AllEntries[key].Normalize(e.Text())
e.SetText(fixed)
}
return
}
}
log.Println("defaultEntryChange() ERROR. MISSING ENTRY MAP. e.Text() =", e.Text())
}
func defaultMakeEntry(startValue string, edit bool, action string) *GuiEntry {
e := ui.NewEntry()
e.SetText(startValue)
if (edit == false) {
e.SetReadOnly(true)
}
e.OnChanged(defaultEntryChange)
// add the entry field to the global map
var newEntry GuiEntry
newEntry.UiEntry = e
newEntry.Edit = edit
newEntry.Name = action
if (action == "INT") {
newEntry.Normalize = normalizeInt
}
Data.AllEntries = append(Data.AllEntries, &newEntry)
return &newEntry
}

2
go.mod
View File

@ -5,5 +5,5 @@ go 1.17
require ( require (
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e
github.com/davecgh/go-spew v1.1.1 github.com/davecgh/go-spew v1.1.1
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d golang.org/x/image v0.0.0-20220902085622-e7cb96979f69
) )

3
go.sum
View File

@ -4,5 +4,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69 h1:Lj6HJGCSn5AjxRAH2+r35Mir4icalbqku+CLUtjnvXY=
golang.org/x/image v0.0.0-20220902085622-e7cb96979f69/go.mod h1:doUCurBvlfPMKfmIpRIywoHmhN3VyhnoFDbvIEWF4hY=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

28
int.go Normal file
View File

@ -0,0 +1,28 @@
package gui
import "log"
import "github.com/davecgh/go-spew/spew"
// import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
// Get the int from the gui toolkit
// TODO: instead store the int in the Node structure? (this is probably a better idea)
// because eventually this gui package should become it's own seperate go routine and never interact from the
// gui subroutine back into the upstream application using the gui package
func (n *Node) Int() int {
if (Config.DebugToolkit) {
log.Println("gui.Node.Int() for node name =", n.Name)
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(n)
}
if (n.Toolkit == nil) {
log.Println("gui.Node.Int() for toolkit struct = nil")
return 0
}
i := n.Toolkit.Value()
return i
}

View File

@ -9,8 +9,11 @@ import (
"github.com/andlabs/ui" "github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest" _ "github.com/andlabs/ui/winmanifest"
) )
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
type Element int type Element int
// https://ieftimov.com/post/golang-datastructures-trees/ // https://ieftimov.com/post/golang-datastructures-trees/
@ -39,8 +42,10 @@ func (s Element) String() string {
return "unknown" return "unknown"
} }
// The Node is simply the name and the size of whatever GUI element exists
type Node struct { type Node struct {
id string id string
Name string Name string
Width int Width int
Height int Height int
@ -50,10 +55,15 @@ type Node struct {
window *GuiWindow window *GuiWindow
box *GuiBox box *GuiBox
custom func(*Node) custom func(*Node)
OnChanged func(*Node)
Toolkit *toolkit.Toolkit
uiControl *ui.Control uiControl *ui.Control
uiButton *ui.Button uiButton *ui.Button
uiSlider *ui.Slider
uiSpinbox *ui.Spinbox
uiWindow *ui.Window uiWindow *ui.Window
uiTab *ui.Tab uiTab *ui.Tab
uiBox *ui.Box uiBox *ui.Box
@ -69,28 +79,53 @@ func (n *Node) Window() *Node {
} }
func (n *Node) Dump() { func (n *Node) Dump() {
log.Println("gui.Node.Dump() id = ", n.id) IndentPrintln("id = ", n.id)
log.Println("gui.Node.Dump() Name = ", n.Name) IndentPrintln("Name = ", n.Name)
log.Println("gui.Node.Dump() Width = ", n.Width) IndentPrintln("Width = ", n.Width)
log.Println("gui.Node.Dump() Height = ", n.Height) IndentPrintln("Height = ", n.Height)
if (n.parent == nil) { if (n.parent == nil) {
log.Println("gui.Node.Dump() parent = nil") IndentPrintln("parent = nil")
} else { } else {
log.Println("gui.Node.Dump() parent = ", n.parent.id) IndentPrintln("parent =", n.parent.id)
}
if (n.children != nil) {
IndentPrintln("children = ", n.children)
} }
log.Println("gui.Node.Dump() children = ", n.children)
log.Println("gui.Node.Dump() window = ", n.window) if (n.window != nil) {
log.Println("gui.Node.Dump() box = ", n.box) IndentPrintln("window = ", n.window)
}
if (n.window != nil) {
IndentPrintln("box = ", n.box)
}
log.Println("gui.Node.Dump() uiWindow = ", n.uiWindow) if (n.window != nil) {
log.Println("gui.Node.Dump() uiTab = ", n.uiTab) IndentPrintln("uiWindow = ", n.uiWindow)
log.Println("gui.Node.Dump() uiBox = ", n.uiBox) }
log.Println("gui.Node.Dump() uiControl = ", n.uiControl) if (n.uiTab != nil) {
log.Println("gui.Node.Dump() uiButton = ", n.uiButton) IndentPrintln("uiTab = ", n.uiTab)
}
if (n.uiBox != nil) {
IndentPrintln("uiBox = ", n.uiBox)
}
if (n.uiControl != nil) {
IndentPrintln("uiControl = ", n.uiControl)
}
if (n.uiButton != nil) {
IndentPrintln("uiButton = ", n.uiButton)
}
if (n.custom != nil) {
IndentPrintln("custom = ", n.custom)
}
if (n.OnChanged != nil) {
IndentPrintln("OnChanged = ", n.OnChanged)
}
if (n.id == "") { if (n.id == "") {
panic("gui.Node.Dump() id == nil") // Node structs should never have a nil id.
// I probably shouldn't panic here, but this is just to check the sanity of
// the gui package to make sure it's not exiting
panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
} }
} }
@ -130,11 +165,16 @@ func (n *Node) List() {
var listChildrenParent *Node var listChildrenParent *Node
var listChildrenDepth int = 0 var listChildrenDepth int = 0
var defaultPadding = " "
func IndentPrintln(a ...interface{}) {
indentPrintln(listChildrenDepth, defaultPadding, a)
}
func indentPrintln(depth int, format string, a ...interface{}) { func indentPrintln(depth int, format string, a ...interface{}) {
var tabs string var tabs string
for i := 0; i < depth; i++ { for i := 0; i < depth; i++ {
tabs = tabs + "\t" tabs = tabs + format
} }
// newFormat := tabs + strconv.Itoa(depth) + " " + format // newFormat := tabs + strconv.Itoa(depth) + " " + format
@ -143,7 +183,7 @@ func indentPrintln(depth int, format string, a ...interface{}) {
} }
func (n *Node) ListChildren(dump bool) { func (n *Node) ListChildren(dump bool) {
indentPrintln(listChildrenDepth, "\t", n.id, n.Width, n.Height, n.Name) indentPrintln(listChildrenDepth, defaultPadding, n.id, n.Width, n.Height, n.Name)
if (dump == true) { if (dump == true) {
n.Dump() n.Dump()

24
slider.go Normal file
View File

@ -0,0 +1,24 @@
package gui
import "log"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
func (n *Node) NewSlider(name string, x int, y int) *Node {
// make new node here
log.Println("toolkit.NewSlider", x, y)
newNode := n.makeNode(name, 767, 676 + Config.counter)
newNode.Name = name
t := toolkit.NewSlider(n.uiBox, name, x, y)
t.OnChanged = func(t *toolkit.Toolkit) {
log.Println("toolkit.NewSlider() value =", t.Value())
if (newNode.OnChanged != nil) {
newNode.OnChanged(newNode)
}
}
newNode.Toolkit = t
return newNode
}

24
spinbox.go Normal file
View File

@ -0,0 +1,24 @@
package gui
import "log"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
func (n *Node) NewSpinbox(name string, x int, y int) *Node {
// make new node here
log.Println("toolkit.NewSpinbox", x, y)
newNode := n.makeNode(name, 767, 676 + Config.counter)
newNode.Name = name
t := toolkit.NewSpinbox(n.uiBox, name, x, y)
t.OnChanged = func(t *toolkit.Toolkit) {
log.Println("toolkit.NewSpinbox() value =", t.Value())
if (newNode.OnChanged != nil) {
newNode.OnChanged(newNode)
}
}
newNode.Toolkit = t
return newNode
}

View File

@ -7,7 +7,9 @@ import (
"github.com/andlabs/ui" "github.com/andlabs/ui"
"golang.org/x/image/font" "golang.org/x/image/font"
_ "github.com/andlabs/ui/winmanifest" // "github.com/davecgh/go-spew/spew"
// _ "github.com/andlabs/ui/winmanifest"
) )
// //
@ -24,11 +26,12 @@ type GuiConfig struct {
Height int Height int
Exit func(*Node) Exit func(*Node)
Debug bool Debug bool
DebugNode bool DebugNode bool
DebugTabs bool DebugTabs bool
DebugTable bool DebugTable bool
DebugWindow bool DebugWindow bool
DebugToolkit bool
depth int depth int
counter int // used to make unique ID's counter int // used to make unique ID's
@ -171,6 +174,8 @@ func (b *GuiBox) SetNode(n *Node) {
func (b *GuiBox) Append(child ui.Control, x bool) { func (b *GuiBox) Append(child ui.Control, x bool) {
if b.UiBox == nil { if b.UiBox == nil {
// spew.Dump(b)
b.Dump()
panic("GuiBox.Append() can't work. UiBox == nil") panic("GuiBox.Append() can't work. UiBox == nil")
return return
} }

38
toolkit/andlabs/slider.go Normal file
View File

@ -0,0 +1,38 @@
package toolkit
import "log"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
import "github.com/davecgh/go-spew/spew"
func NewSlider(b *ui.Box, name string, x int, y int) *Toolkit {
// make new node here
log.Println("gui.Toolbox.NewSpinbox()", x, y)
var t Toolkit
if (b == nil) {
log.Println("gui.ToolboxNode.NewSpinbox() node.UiBox == nil. I can't add a range UI element without a place to put it")
return &t
}
s := ui.NewSlider(x, y)
t.uiSlider = s
t.uiBox = b
t.uiBox.Append(s, false)
s.OnChanged(func(spin *ui.Slider) {
i := spin.Value()
if (DebugToolkit) {
log.Println("gui.Toolbox.ui.OnChanged() val =", i)
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t.OnChanged != nil) {
log.Println("gui.Toolbox.OnChanged() entered val =", i)
t.OnChanged(&t)
}
})
return &t
}

View File

@ -0,0 +1,86 @@
package toolkit
import "log"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
import "github.com/davecgh/go-spew/spew"
var DebugToolkit bool = false
// stores the raw toolkit internals
type Toolkit struct {
id string
Name string
Width int
Height int
OnChanged func(*Toolkit)
uiControl *ui.Control
uiButton *ui.Button
uiSlider *ui.Slider
uiSpinbox *ui.Spinbox
uiWindow *ui.Window
uiTab *ui.Tab
uiBox *ui.Box
uiText *ui.EditableCombobox
}
func (t *Toolkit) Value() int {
if (DebugToolkit) {
log.Println("gui.Toolkit.Value() Enter")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t == nil) {
log.Println("gui.Toolkit.Value() can not get value t == nil")
return 0
}
if (t.uiSlider != nil) {
if (DebugToolkit) {
log.Println("gui.Toolkit.Value() =", t.uiSlider.Value)
}
return t.uiSlider.Value()
}
if (t.uiSpinbox != nil) {
if (DebugToolkit) {
log.Println("gui.Toolkit.Value() =", t.uiSpinbox.Value)
}
return t.uiSpinbox.Value()
}
log.Println("gui.Toolkit.Value() Could not find a ui element to get a value from")
return 0
}
func NewSpinbox(b *ui.Box, name string, x int, y int) *Toolkit {
// make new node here
log.Println("gui.Toolbox.NewSpinbox()", x, y)
var t Toolkit
if (b == nil) {
log.Println("gui.ToolboxNode.NewSpinbox() node.UiBox == nil. I can't add a range UI element without a place to put it")
return &t
}
spin := ui.NewSpinbox(x, y)
t.uiSpinbox = spin
t.uiBox = b
t.uiBox.Append(spin, false)
spin.OnChanged(func(spin *ui.Spinbox) {
i := spin.Value()
if (DebugToolkit) {
log.Println("gui.Toolbox.ui.OnChanged() val =", i)
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t.OnChanged != nil) {
log.Println("gui.Toolbox.OnChanged() entered val =", i)
t.OnChanged(&t)
}
})
return &t
}

View File

@ -58,6 +58,12 @@ func DeleteWindow(name string) {
} }
} }
/*
generic function to create a newnode structure on the tree of nodes
If the parent is null, it tries to find out where it should go otherwise
it creates a new window or new tab depending on the toolkit or OS
*/
func makeNode(parent *Node, title string, x int, y int) *Node { func makeNode(parent *Node, title string, x int, y int) *Node {
var node Node var node Node
node.Name = title node.Name = title