v0.4.1 set sane toolkit default look and feel

autogenerate README.md from doc.go (goreadme cmd)
    remove passing arguements on a mouse click()
    make defaults for padding, margin, stretchy, etc
    add a checkbox widget
    function rename to NewButton()
    keep cleaning up toolkit code
    fix date. I was somehow in the future

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2022-10-21 11:40:08 -05:00
parent d28f0eb8c1
commit c5735353a6
33 changed files with 799 additions and 319 deletions

View File

@ -22,3 +22,9 @@ examples-gui-demo:
doc: doc:
GO111MODULE="off" godoc -v GO111MODULE="off" godoc -v
# GO111MODULE=on go install github.com/posener/goreadme/cmd/goreadme@latest (worked Oct 20 2022)
readme:
# goreadme > README.md
goreadme -factories -types -functions -variabless > README.md

256
README.md
View File

@ -1,14 +1,248 @@
This is an abstraction layer around the excellent # gui
cross platform UI toolkit from andlabs/ui
This abstraction layer makes it easier to write Package gui implements a abstraction layer for Go visual elements in
simple interfaces for like our cloud control panel a cross platform and library independent way. (hopefully this is will work)
The cross platform UI has 'quirks' due to it being A quick overview of the features, some general design guidelines
cross platform. Some of the abstraction layer here and principles for how this package should generally work:
attemps to obfuscate the ui objects so that it is
more difficult to trigger inconsistancies.
In this regard, this is an attempt to restrict Definitions:
all andlabs/ui (and andlabs/libui) interaction to
the calls within this library. ```go
* Toolkit: the underlying library (MacOS gui, Windows gui, gtk, qt, etc)
* Node: A binary tree of all the underlying GUI toolkit elements
```
Principles:
```go
* Make code using this package simple to use
* When in doubt, search upward in the binary tree
* It's ok to guess. We will return something close.
* Hide complexity internally here
* Isolate the GUI toolkit
* Function names should follow [Wikipedia Graphical widget]
```
## Quick Start
This section demonstrates how to quickly get started with spew. See the
sections below for further details on formatting and configuration options.
```go
// This creates a simple hello world window
package main
import (
"log"
"git.wit.org/wit/gui"
)
var window *gui.Node // This is the beginning of the binary tree of widgets
// go will sit here until the window exits
func main() {
gui.Main(helloworld)
}
// This initializes the first window and 2 tabs
func helloworld() {
gui.Config.Title = "Hello World golang wit/gui Window"
gui.Config.Width = 640
gui.Config.Height = 480
window := gui.NewWindow()
addTab(window, "A Simple Tab Demo")
addTab(window, "A Second Tab")
}
func addTab(w *gui.Node, title string) {
tab := w.NewTab(title)
group := tab.NewGroup("foo bar")
group.NewButton("hello", func() {
log.Println("world")
})
}
```
## Debian Build
This worked on debian sid on 2022/10/22
I didn't record the dependances needed
```go
GO111MODULE="off" go get -v -t -u git.wit.org/wit/gui
cd ~/go/src/git.wit.org/wit/gui/cmds/helloworld/
GO111MODULE="off" go build -v -x
[./helloworld](./helloworld)
```
## Toolkits
The goal is to design something that will work with more than one.
Right now, this abstraction is built on top of the go package 'andlabs/ui'
which does the cross platform support.
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 and
hopefully also things like libSDL, faiface/pixel, slint
[Wikipedia Graphical widget]: [https://en.wikipedia.org/wiki/Graphical_widget](https://en.wikipedia.org/wiki/Graphical_widget)
## Errors
Since it is possible for custom Stringer/error interfaces to panic, spew
detects them and handles them internally by printing the panic information
inline with the output. Since spew is intended to provide deep pretty printing
capabilities on structures, it intentionally does not return any errors.
## Debugging
To dump variables with full newlines, indentation, type, and pointer
information this uses spew.Dump()
## Bugs
"The author's idea of friendly may differ to that of many other people."
-- manpage quote from the excellent minimalistic window manager 'evilwm'
External References
## Functions
### func [DebugTab](/window-debug.go#L26)
`func DebugTab()`
this function is used by the examples to add a tab
dynamically to the bugWin node
TODO: make this smarter once this uses toolkit/
### func [DebugWindow](/window-debug.go#L14)
`func DebugWindow()`
Creates a window helpful for debugging this package
### func [DemoToolkitWindow](/window-demo-toolkit.go#L24)
`func DemoToolkitWindow()`
This creates a window that shows how the toolkit works
internally using it's raw unchanged code for the toolkit itself
This is a way to test and see if the toolkit is working at all
right now it shows the andlabs/ui/DemoNumbersPage()
### func [DemoWindow](/window-demo.go#L10)
`func DemoWindow()`
This creates a window that shows how this package works
### func [GolangDebugWindow](/window-golang-debug.go#L20)
`func GolangDebugWindow()`
### func [IndentPrintln](/structs.go#L161)
`func IndentPrintln(a ...interface{})`
### func [Main](/main.go#L34)
`func Main(f func())`
### func [Queue](/main.go#L45)
`func Queue(f func())`
Other goroutines must use this to access the GUI
You can not acess / process the GUI thread directly from
other goroutines. This is due to the nature of how
Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
For example: gui.Queue(NewWindow())
### func [StandardClose](/window-golang-debug.go#L12)
`func StandardClose(n *Node)`
## Types
### type [GuiConfig](/structs.go#L24)
`type GuiConfig struct { ... }`
#### Variables
```golang
var Config GuiConfig
```
### type [Node](/structs.go#L79)
`type Node struct { ... }`
The Node is simply the name and the size of whatever GUI element exists
#### func [NewStandardWindow](/window-demo-toolkit.go#L7)
`func NewStandardWindow(title string) *Node`
#### func [NewWindow](/window.go#L15)
`func NewWindow() *Node`
This routine creates a blank window with a Title and size (W x H)
This routine can not have any arguements due to the nature of how
it can be passed via the 'andlabs/ui' queue which, because it is
cross platform, must pass UI changes into the OS threads (that is
my guess).
This example demonstrates how to create a NewWindow()
Interacting with a GUI in a cross platform fashion adds some
unusual problems. To obvuscate those, andlabs/ui starts a
goroutine that interacts with the native gui toolkits
on the Linux, MacOS, Windows, etc.
Because of this oddity, to initialize a new window, the
function is not passed any arguements and instead passes
the information via the Config type.
```golang
package main
import (
"git.wit.org/wit/gui"
)
func main() {
// Define the name and size
gui.Config.Title = "WIT GUI Window 1"
gui.Config.Width = 640
gui.Config.Height = 480
// Create the Window
gui.NewWindow()
}
```
Output:
```
You get a window
```
### type [Widget](/structs.go#L49)
`type Widget int`
---
Readme created from Go doc with [goreadme](https://github.com/posener/goreadme)

View File

@ -2,7 +2,7 @@ package gui
import "log" import "log"
func (n *Node) AddButton(name string, custom func(*Node)) *Node { func (n *Node) NewButton(name string, custom func()) *Node {
if (n.toolkit == nil) { if (n.toolkit == nil) {
log.Println("gui.Node.AppendButton() filed node.toolkit == nil") log.Println("gui.Node.AppendButton() filed node.toolkit == nil")
panic("gui.Node.AppendButton() filed node.toolkit == nil") panic("gui.Node.AppendButton() filed node.toolkit == nil")
@ -10,9 +10,12 @@ func (n *Node) AddButton(name string, custom func(*Node)) *Node {
} }
newNode := n.New(name) newNode := n.New(name)
newNode.toolkit = n.toolkit.NewButton(name) newNode.toolkit = n.toolkit.NewButton(name)
// TODO: this is still confusing and probably wrong. This needs to communicate through a channel
newNode.toolkit.Custom = func() { newNode.toolkit.Custom = func() {
log.Println("gui.AppendButton() Button Clicked. Running custom()") log.Println("gui.AppendButton() Button Clicked. Running custom() from outside toolkit START")
custom(newNode) custom()
log.Println("gui.AppendButton() Button Clicked. Running custom() from outside toolkit END")
} }
newNode.custom = custom newNode.custom = custom

48
checkbox.go Normal file
View File

@ -0,0 +1,48 @@
package gui
import "log"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
func (n *Node) verify() {
if (n.toolkit == nil) {
log.Println("gui/wit node.Verify(): toolkit == nil", n.Name)
panic("gui/wit node.Verify(): toolkit == nil")
}
}
func (n *Node) Checked() bool {
n.Dump()
return n.checked
}
func (n *Node) NewCheckbox(name string) *Node {
var newt *toolkit.Toolkit
var c *Node
log.Println("toolkit.NewCheckbox() START", name)
n.verify()
// make a *Node with a *toolkit.Group
c = n.New(name + " part1")
newt = n.toolkit.NewCheckbox(name)
newt.Name = name
c.toolkit = newt
c.custom = n.custom
newt.Custom = func () {
println("AM IN CALLBACK. SETTING NODE.checked START")
if newt.Checked() {
println("is checked")
c.checked = true
} else {
println("is not checked")
c.checked = false
}
commonCallback(c)
println("AM IN CALLBACK. SETTING NODE.checked END")
}
c.Dump()
return c
}

View File

@ -4,6 +4,7 @@ run: build
build-release: build-release:
go get -v -u -x . go get -v -u -x .
go build go build
./helloworld
build: build:
GO111MODULE="off" go get -v -x . GO111MODULE="off" go get -v -x .

45
doc.go
View File

@ -1,4 +1,5 @@
/* /*
Package gui implements a abstraction layer for Go visual elements in Package gui implements a abstraction layer for Go visual elements in
a cross platform and library independent way. (hopefully this is will work) a cross platform and library independent way. (hopefully this is will work)
@ -17,7 +18,8 @@ Principles:
* It's ok to guess. We will return something close. * It's ok to guess. We will return something close.
* Hide complexity internally here * Hide complexity internally here
* Isolate the GUI toolkit * Isolate the GUI toolkit
* Function names should follow https://en.wikipedia.org/wiki/Graphical_widget * Function names should follow [Wikipedia Graphical widget]
Quick Start Quick Start
@ -28,31 +30,51 @@ sections below for further details on formatting and configuration options.
package main package main
import ( import (
"log"
"git.wit.org/wit/gui" "git.wit.org/wit/gui"
) )
var window *gui.Node // This is the beginning of the binary tree of widgets
// go will sit here until the window exits
func main() { func main() {
gui.Main(helloworld) gui.Main(helloworld)
} }
// This initializes the first window // This initializes the first window and 2 tabs
func helloworld() { func helloworld() {
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
node1 := gui.NewWindow()
addDemoTab(node1, "A Simple Tab Demo") window := gui.NewWindow()
addDemoTab(node1, "A Second Tab") addTab(window, "A Simple Tab Demo")
addTab(window, "A Second Tab")
} }
func addDemoTab(n *gui.Node, title string) { func addTab(w *gui.Node, title string) {
newNode := n.AddTab(title, nil) tab := w.NewTab(title)
groupNode1 := newNode.NewGroup("group 1") group := tab.NewGroup("foo bar")
groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") group.NewButton("hello", func() {
log.Println("world")
})
} }
Toolkits (hopefully more than one will work)
Debian Build
This worked on debian sid on 2022/10/20
I didn't record the dependances needed
GO111MODULE="off" go get -v -t -u git.wit.org/wit/gui
cd ~/go/src/git.wit.org/wit/gui/cmds/helloworld/
GO111MODULE="off" go build -v -x
./helloworld
Toolkits
The goal is to design something that will work with more than one.
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.
@ -61,6 +83,8 @@ 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 and It should be able to add Fyne, WASM, native macos & windows, android and
hopefully also things like libSDL, faiface/pixel, slint hopefully also things like libSDL, faiface/pixel, slint
[Wikipedia Graphical widget]: https://en.wikipedia.org/wiki/Graphical_widget
Errors Errors
Since it is possible for custom Stringer/error interfaces to panic, spew Since it is possible for custom Stringer/error interfaces to panic, spew
@ -79,6 +103,7 @@ Bugs
-- manpage quote from the excellent minimalistic window manager 'evilwm' -- manpage quote from the excellent minimalistic window manager 'evilwm'
External References
*/ */
package gui package gui

View File

@ -4,40 +4,40 @@ import "log"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs" import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
func commonCallback(n *Node) {
// TODO: make all of this common code to all the widgets
if (n.OnChanged == nil) {
log.Println("Not Running n.OnChanged(n) == nil")
} else {
log.Println("Running n.OnChanged(n)")
n.OnChanged(n)
}
if (n.custom == nil) {
log.Println("Not Running n.custom(n) == nil")
} else {
log.Println("Running n.custom()")
n.custom()
}
}
func (n *Node) NewDropdown(name string) *Node { func (n *Node) NewDropdown(name string) *Node {
var newT *toolkit.Toolkit var newT *toolkit.Toolkit
var sNode *Node var sNode *Node
log.Println("toolkit.NewDropdown() START", name) log.Println("toolkit.NewDropdown() START", name)
// make this generic n.verify()
if (n.toolkit == nil) {
log.Println("toolkit.NewSlider() toolkit == nil")
panic("toolkit should never be nil")
}
sNode = n.New(name + " part1") sNode = n.New(name + " part1")
newT = n.toolkit.NewDropdown(name) newT = n.toolkit.NewDropdown(name)
newT.Name = name newT.Name = name
sNode.custom = n.custom sNode.custom = n.custom
newT.Custom = func () { newT.Custom = func () {
// TODO: make all of this common code to all the widgets commonCallback(sNode)
if (n.custom == nil) {
log.Println("Not Running n.custom(n) == nil")
} else {
log.Println("Running n.custom(n)")
sNode.custom(sNode)
}
if (sNode.OnChanged == nil) {
log.Println("Not Running n.OnChanged(n) == nil")
} else {
log.Println("Running n.OnChanged(n)")
sNode.OnChanged(sNode)
}
} }
sNode.toolkit = newT sNode.toolkit = newT
sNode.Dump() sNode.Dump()
sNode.toolkit.Dump()
// panic("checking Custom()") // panic("checking Custom()")
return sNode return sNode

View File

@ -17,15 +17,16 @@ func (n *Node) NewGroup(name string) *Node {
} }
// make a *Node with a *toolkit.Group // make a *Node with a *toolkit.Group
gNode = n.New(name + " part1") gNode = n.New(name)
newT = n.toolkit.NewGroup(name) newT = n.toolkit.NewGroup(name)
gNode.toolkit = newT gNode.toolkit = newT
log.Println("################## gNode ####### ", name)
gNode.Dump() gNode.Dump()
return gNode return gNode
} }
/*
func (n *Node) AddGroup(title string) *Node { func (n *Node) AddGroup(title string) *Node {
return n.NewGroup(title + " deprecated AddGroup") return n.NewGroup(title + " deprecated AddGroup")
} }
*/

4
int.go
View File

@ -4,6 +4,8 @@ import "log"
import "github.com/davecgh/go-spew/spew" import "github.com/davecgh/go-spew/spew"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
/* /*
Get the int from the gui toolkit Get the int from the gui toolkit
because eventually this gui package should become it's own seperate go routine and never interact from the because eventually this gui package should become it's own seperate go routine and never interact from the
@ -14,7 +16,7 @@ import "github.com/davecgh/go-spew/spew"
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 {
if (Config.DebugToolkit) { if (toolkit.DebugToolkit) {
log.Println("gui.Node.Int() for node name =", n.Name) log.Println("gui.Node.Int() for node name =", n.Name)
scs := spew.ConfigState{MaxDepth: 1} scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(n) scs.Dump(n)

View File

@ -23,10 +23,10 @@ func init() {
title := "master" title := "master"
w := 640 w := 640
h := 480 h := 480
f := StandardClose // f := StandardClose
Config.master = addNode(title, w, h) Config.master = addNode(title, w, h)
Config.master.custom = f // Config.master.custom = f
Config.master.Dump() Config.master.Dump()
} }

View File

@ -10,10 +10,7 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
log.Println("toolkit.NewSlider() START", name) log.Println("toolkit.NewSlider() START", name)
if (n.toolkit == nil) { n.verify()
log.Println("toolkit.NewSlider() toolkit == nil")
panic("Toolkit should never be nil")
}
// make a *Node with a *toolkit.Group // make a *Node with a *toolkit.Group
sNode = n.New(name + " part1") sNode = n.New(name + " part1")
@ -21,19 +18,7 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
newT.Name = name newT.Name = name
sNode.custom = n.custom sNode.custom = n.custom
newT.Custom = func () { newT.Custom = func () {
// TODO: make all of this common code to all the widgets commonCallback(sNode)
if (n.custom == nil) {
log.Println("Not Running n.custom(n) == nil")
} else {
log.Println("Running n.custom(n)")
sNode.custom(sNode)
}
if (sNode.OnChanged == nil) {
log.Println("Not Running n.OnChanged(n) == nil")
} else {
log.Println("Running n.OnChanged(n)")
sNode.OnChanged(sNode)
}
} }
sNode.toolkit = newT sNode.toolkit = newT
sNode.Dump() sNode.Dump()

View File

@ -10,17 +10,18 @@ func (n *Node) NewSpinner(name string, x int, y int) *Node {
log.Println("toolkit.NewSpinner() START", name) log.Println("toolkit.NewSpinner() START", name)
if (n.toolkit == nil) { n.verify()
log.Println("toolkit.NewSpinner() toolkit == nil")
panic("toolkit should never be nil")
}
// make a *Node with a *toolkit.Group // make a *Node with a *toolkit.Group
sNode = n.New(name + " part1") sNode = n.New(name + " part1")
newT = n.toolkit.NewSpinner(name, x, y) newT = n.toolkit.NewSpinner(name, x, y)
newT.Name = name newT.Name = name
sNode.toolkit = newT sNode.toolkit = newT
sNode.Dump() // sNode.Dump()
newT.Custom = func () {
commonCallback(sNode)
}
return sNode return sNode
} }

View File

@ -2,7 +2,7 @@ package gui
import ( import (
"log" "log"
"reflect"
) )
import toolkit "git.wit.org/wit/gui/toolkit/andlabs" import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
@ -21,6 +21,25 @@ import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
var Config GuiConfig var Config GuiConfig
func SetDebugToolkit (s bool) {
toolkit.DebugToolkit = s
}
func GetDebugToolkit () bool {
return toolkit.DebugToolkit
}
func ShowDebugValues() {
log.Println("\t wit/gui Debug =", Config.Debug)
log.Println("\t wit/gui DebugDump =", Config.DebugDump)
log.Println("\t wit/gui DebugNode =", Config.DebugNode)
log.Println("\t wit/gui DebugTabs =", Config.DebugTabs)
log.Println("\t wit/gui DebugTable =", Config.DebugTable)
log.Println("\t wit/gui DebugWindow =", Config.DebugWindow)
log.Println("\t wit/gui DebugWindow =", Config.DebugWindow)
log.Println("\t wit/gui DebugToolkit =", toolkit.DebugToolkit)
}
type GuiConfig struct { type GuiConfig struct {
// This is the master node. The Binary Tree starts here // This is the master node. The Binary Tree starts here
master *Node master *Node
@ -34,11 +53,11 @@ type GuiConfig struct {
// These are global debugging settings // These are global debugging settings
// TODO: move to a standard logging system // TODO: move to a standard logging system
Debug bool Debug bool
DebugDump bool
DebugNode bool DebugNode bool
DebugTabs bool DebugTabs bool
DebugTable bool DebugTable bool
DebugWindow bool DebugWindow bool
DebugToolkit bool
// hacks // hacks
depth int depth int
@ -84,10 +103,14 @@ type Node struct {
Height int Height int
parent *Node parent *Node
// TODO: make children a double linked list since some toolkits require order
children []*Node children []*Node
custom func(*Node) // things that may not really be needed (?)
custom func()
OnChanged func(*Node) OnChanged func(*Node)
checked bool
text string
toolkit *toolkit.Toolkit toolkit *toolkit.Toolkit
} }
@ -101,6 +124,10 @@ func (n *Node) Window() *Node {
} }
func (n *Node) Dump() { func (n *Node) Dump() {
if ! Config.DebugDump {
return
}
IndentPrintln("NODE DUMP START")
IndentPrintln("id = ", n.id) IndentPrintln("id = ", n.id)
IndentPrintln("Name = ", n.Name) IndentPrintln("Name = ", n.Name)
IndentPrintln("Width = ", n.Width) IndentPrintln("Width = ", n.Width)
@ -109,27 +136,30 @@ func (n *Node) Dump() {
if (n.parent == nil) { if (n.parent == nil) {
IndentPrintln("parent = nil") IndentPrintln("parent = nil")
} else { } else {
IndentPrintln("parent =", n.parent.id) IndentPrintln("parent.id =", n.parent.id)
} }
if (n.children != nil) { if (n.children != nil) {
IndentPrintln("children = ", n.children) IndentPrintln("children = ", n.children)
} }
if (n.toolkit != nil) {
IndentPrintln("toolkit = ", n.toolkit)
n.toolkit.Dump()
}
if (n.custom != nil) { if (n.custom != nil) {
IndentPrintln("custom = ", n.custom) IndentPrintln("custom = ", n.custom)
} }
IndentPrintln("checked = ", n.checked)
if (n.OnChanged != nil) { if (n.OnChanged != nil) {
IndentPrintln("OnChanged = ", n.OnChanged) IndentPrintln("OnChanged = ", n.OnChanged)
} }
IndentPrintln("text = ", reflect.ValueOf(n.text).Kind(), n.text)
if (n.toolkit != nil) {
IndentPrintln("toolkit = ", reflect.ValueOf(n.toolkit).Kind())
n.toolkit.Dump()
}
if (n.id == "") { if (n.id == "") {
// Node structs should never have a nil id. // Node structs should never have a nil id.
// I probably shouldn't panic here, but this is just to check the sanity of // 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 // 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") panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
} }
IndentPrintln("NODE DUMP END")
} }
func (n *Node) SetName(name string) { func (n *Node) SetName(name string) {

21
text.go
View File

@ -1,7 +1,7 @@
package gui package gui
import "log" import "log"
import "errors" // import "errors"
import "regexp" import "regexp"
// functions for handling text related GUI elements // functions for handling text related GUI elements
@ -17,10 +17,17 @@ func (n *Node) NewLabel(text string) *Node {
return newNode return newNode
} }
func (n *Node) SetText(value string) error { func (n *Node) SetText(str string) bool {
log.Println("gui.SetText() value =", value) log.Println("gui.SetText() value =", str)
panic("redo SetText()") if (n.toolkit == nil) {
return errors.New("nothing found for gui.Node.SetText()") return false
}
return n.toolkit.SetText(str)
}
func (n *Node) GetText() string {
return n.toolkit.GetText()
} }
/* /*
@ -56,7 +63,3 @@ func normalizeInt(s string) string {
log.Println("normalizeInt() s =", clean) log.Println("normalizeInt() s =", clean)
return clean return clean
} }
func (n *Node) GetText() string {
return n.toolkit.GetText()
}

35
textbox.go Normal file
View File

@ -0,0 +1,35 @@
package gui
import "log"
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
func (n *Node) NewTextbox(name string) *Node {
var newt *toolkit.Toolkit
var c *Node
log.Println("toolkit.NewTextbox() START", name)
n.verify()
// make a new Node and a new toolbox struct
c = n.New(name)
newt = n.toolkit.NewTextbox(name)
c.toolkit = newt
c.custom = n.custom
newt.Name = name
// newt.Custom = func () {
newt.OnChanged = func (*toolkit.Toolkit) {
println("AM IN CALLBACK. SETTING NODE.checked START")
c.text = c.toolkit.GetText()
c.Dump()
c.toolkit.Dump()
c.OnChanged(n)
println("n.toolkit.GetText() =", c.text)
println("AM IN CALLBACK. SETTING NODE.checked END")
}
return c
}

View File

@ -15,35 +15,29 @@ func (t *Toolkit) NewBox() *Toolkit {
log.Println("gui.Toolbox.NewBox() START create default") log.Println("gui.Toolbox.NewBox() START create default")
t.Dump() t.Dump()
if (t.uiGroup != nil) { if (t.uiGroup != nil) {
log.Println("gui.Toolbox.NewBox() is a Group") log.Println("\tgui.Toolbox.NewBox() is a Group")
var newTK Toolkit var newTK Toolkit
vbox := ui.NewVerticalBox() vbox := ui.NewVerticalBox()
vbox.SetPadded(true) vbox.SetPadded(padded)
t.uiGroup.SetChild(vbox) t.uiGroup.SetChild(vbox)
newTK.uiBox = vbox newTK.uiBox = vbox
return &newTK return &newTK
} }
if (t.uiBox != nil) { if (t.uiBox != nil) {
log.Println("gui.Toolbox.NewBox() is a Box") log.Println("\tgui.Toolbox.NewBox() is a Box")
// return t var newTK Toolkit
vbox := ui.NewVerticalBox()
vbox.SetPadded(padded)
t.uiBox.Append(vbox, stretchy)
newTK.uiBox = vbox
newTK.Name = t.Name
return &newTK
} }
log.Println("gui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box") log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box")
t.Dump() t.Dump()
return nil return nil
} }
// Make a new box
func MakeBox(name string) *Toolkit {
var newt Toolkit
vbox := ui.NewVerticalBox()
vbox.SetPadded(border)
newt.uiBox = vbox
newt.Name = name
log.Println("gui.Toolbox.MakeBox() name =", name)
newt.Dump()
return &newt
}

View File

@ -44,7 +44,7 @@ func (t Toolkit) NewButton(name string) *Toolkit {
log.Println("TODO: LEFT TOOLKIT GOROUTINE button name =", name) log.Println("TODO: LEFT TOOLKIT GOROUTINE button name =", name)
}) })
t.uiBox.Append(b, false) t.uiBox.Append(b, stretchy)
return &newt return &newt
} }

View File

@ -0,0 +1,34 @@
package toolkit
import "log"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
func (t Toolkit) NewCheckbox(name string) *Toolkit {
log.Println("gui.Toolkit.NewCheckbox()", name)
var newt Toolkit
if t.broken() {
return nil
}
c := ui.NewCheckbox(name)
newt.uiCheckbox = c
newt.uiBox = t.uiBox
t.uiBox.Append(c, stretchy)
c.OnToggled(func(spin *ui.Checkbox) {
newt.commonChange("Checkbox")
})
return &newt
}
func (t Toolkit) Checked() bool {
if t.broken() {
return false
}
return t.uiCheckbox.Checked()
}

46
toolkit/andlabs/common.go Normal file
View File

@ -0,0 +1,46 @@
package toolkit
import "log"
// import "github.com/andlabs/ui"
// import _ "github.com/andlabs/ui/winmanifest"
func init() {
log.Println("gui/toolkit init() Setting defaultBehavior = true")
setDefaultBehavior(true)
}
func (t Toolkit) commonChange(widget string) {
s := t.String()
log.Println("gui.Toolkit.ui.OnChanged() =", s)
if (DebugToolkit) {
log.Println("gui.Toolkit.ui.OnChanged() =", s)
}
if (t.OnChanged != nil) {
log.Println("gui.Toolkit.OnChanged() trying to run toolkit.OnChanged() entered val =", s)
t.OnChanged(&t)
return
}
if (t.Custom != nil) {
log.Println("gui.Toolkit.OnChanged() Running toolkit.Custom()")
t.Dump()
t.Custom()
return
}
log.Println("gui.Toolkit.OnChanged() ENDED without finding any callback")
}
func (t Toolkit) broken() bool {
if (t.uiBox == nil) {
log.Println("gui.Toolkit.UiBox == nil. I can't add a widget without a place to put it")
// log.Println("probably could just make a box here?")
// corruption or something horrible?
panic("wit/gui toolkit/andlabs func broken() invalid goroutine access into this toolkit?")
return true
}
if (t.uiWindow == nil) {
log.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)")
return false
}
return false
}

View File

@ -5,7 +5,12 @@ import "log"
import "github.com/andlabs/ui" import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
import "github.com/davecgh/go-spew/spew" /*
This is a code example taken directly from the toolkit andlabs/ui
This code is here to double check that the toolkit itself still works
the same way. This is intended as a sanity check.
*/
func BlankWindow(w *ui.Window) *ui.Box { func BlankWindow(w *ui.Window) *ui.Box {
hbox := ui.NewHorizontalBox() hbox := ui.NewHorizontalBox()
@ -17,54 +22,15 @@ func BlankWindow(w *ui.Window) *ui.Box {
func (t *Toolkit) DemoNumbersPage() { func (t *Toolkit) DemoNumbersPage() {
var w *ui.Window var w *ui.Window
log.Println("Starting wit/gui toolkit andlabs/ui DemoNumbersPage()")
w = t.uiWindow w = t.uiWindow
t.uiBox = makeNumbersPage() t.uiBox = makeNumbersPage()
t.uiBox.SetPadded(true) t.uiBox.SetPadded(true)
w.SetChild(t.uiBox) w.SetChild(t.uiBox)
w.SetTitle("Internal demo of andlabs/ui toolkit") w.SetTitle("Internal demo of andlabs/ui toolkit")
if (DebugToolkit) {
log.Println("gui.Toolbox.DemoNumbersPage()")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
} }
/*
func Demo(b *ui.Box) *Toolkit {
x := 22
y := 33
// 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 nil
}
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
}
*/
func makeNumbersPage() *ui.Box { func makeNumbersPage() *ui.Box {
hbox := ui.NewHorizontalBox() hbox := ui.NewHorizontalBox()
hbox.SetPadded(true) hbox.SetPadded(true)

View File

@ -7,23 +7,19 @@ import "os"
import "github.com/andlabs/ui" import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
import "github.com/davecgh/go-spew/spew" func (t *Toolkit) NewDropdown(title string) *Toolkit {
func (pt *Toolkit) NewDropdown(title string) *Toolkit {
// make new node here // make new node here
log.Println("gui.Toolbox.NewDropdownCombobox()") log.Println("gui.Toolbox.NewDropdownCombobox()")
var newt Toolkit var newt Toolkit
if (pt.uiBox == nil) { if t.broken() {
log.Println("gui.ToolboxNode.NewDropdown() node.UiBox == nil. I can't add a range UI element without a place to put it")
os.Exit(0)
return nil return nil
} }
s := ui.NewCombobox() s := ui.NewCombobox()
newt.uiCombobox = s newt.uiCombobox = s
newt.uiBox = pt.uiBox newt.uiBox = t.uiBox
pt.uiBox.Append(s, false) t.uiBox.Append(s, stretchy)
// initialize the index // initialize the index
newt.c = 0 newt.c = 0
@ -36,24 +32,7 @@ func (pt *Toolkit) NewDropdown(title string) *Toolkit {
os.Exit(0) os.Exit(0)
} }
newt.text = newt.val[i] newt.text = newt.val[i]
val := newt.text newt.commonChange("Dropdown")
log.Println("gui.Toolbox.ui.Dropdown.OnChanged() val =", i, val)
if (DebugToolkit) {
log.Println("gui.Toolbox.ui.OnChanged() val =", i, val)
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(newt)
}
if (newt.OnChanged != nil) {
log.Println("gui.Toolbox.OnChanged() trying to run toolkit.OnChanged() entered val =", i, val)
newt.OnChanged(&newt)
return
}
if (newt.Custom != nil) {
log.Println("gui.Toolbox.OnChanged() Running toolkit.Custom()", i, val)
newt.Custom()
return
}
log.Println("gui.Toolbox.Dropdown.OnChanged() ENDED without finding any callback", i, val)
}) })
return &newt return &newt

View File

@ -1,23 +0,0 @@
package toolkit
import "log"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
func NewEntry(b *ui.Box, name string) *Toolkit {
// make new node here
log.Println("gui.Toolbox.NewEntry", name)
var t Toolkit
if (b == nil) {
log.Println("gui.ToolboxNode.NewEntry() node.UiBox == nil. I can't add a range UI element without a place to put it")
return &t
}
l := ui.NewEntry()
t.uiEntry = l
t.uiBox = b
t.uiBox.Append(l, false)
return &t
}

View File

@ -19,11 +19,11 @@ func (t Toolkit) NewGroup(title string) *Toolkit {
log.Println("gui.Toolbox.NewGroup() create", title) log.Println("gui.Toolbox.NewGroup() create", title)
g := ui.NewGroup(title) g := ui.NewGroup(title)
g.SetMargined(true) g.SetMargined(margin)
t.uiBox.Append(g, streachy) t.uiBox.Append(g, stretchy)
hbox := ui.NewVerticalBox() hbox := ui.NewVerticalBox()
hbox.SetPadded(true) hbox.SetPadded(padded)
g.SetChild(hbox) g.SetChild(hbox)
newt.uiGroup = g newt.uiGroup = g

View File

@ -1,31 +1,21 @@
package toolkit package toolkit
import "log" import "log"
import "os"
import "github.com/andlabs/ui" import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
// func NewLabel(b *ui.Box, name string) *Toolkit {
func (t *Toolkit) NewLabel(name string) *Toolkit { func (t *Toolkit) NewLabel(name string) *Toolkit {
// make new node here // make new node here
log.Println("gui.Toolbox.NewLabel", name) log.Println("gui.Toolbox.NewLabel", name)
if (t.uiBox == nil) { if t.broken() {
log.Println("gui.ToolboxNode.NewLabel() node.UiBox == nil. I can't add a range UI element without a place to put it")
os.Exit(0)
return nil return nil
} }
var newt Toolkit var newt Toolkit
newt.uiLabel = ui.NewLabel(name) newt.uiLabel = ui.NewLabel(name)
newt.uiBox = t.uiBox newt.uiBox = t.uiBox
t.uiBox.Append(newt.uiLabel, false) t.uiBox.Append(newt.uiLabel, false)
log.Println("parent toolkit")
t.Dump()
log.Println("newt toolkit")
newt.Dump()
// panic("got here")
return &newt return &newt
} }

View File

@ -24,7 +24,7 @@ func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit {
s := ui.NewSlider(x, y) s := ui.NewSlider(x, y)
newt.uiSlider = s newt.uiSlider = s
newt.uiBox = t.uiBox newt.uiBox = t.uiBox
t.uiBox.Append(s, false) t.uiBox.Append(s, stretchy)
s.OnChanged(func(spin *ui.Slider) { s.OnChanged(func(spin *ui.Slider) {
i := spin.Value() i := spin.Value()

View File

@ -23,7 +23,7 @@ func (t Toolkit) NewSpinner(title string, x int, y int) *Toolkit {
s := ui.NewSpinbox(x, y) s := ui.NewSpinbox(x, y)
newt.uiSpinbox = s newt.uiSpinbox = s
newt.uiBox = t.uiBox newt.uiBox = t.uiBox
t.uiBox.Append(s, false) t.uiBox.Append(s, stretchy)
s.OnChanged(func(s *ui.Spinbox) { s.OnChanged(func(s *ui.Spinbox) {
i := s.Value() i := s.Value()

View File

@ -7,11 +7,42 @@ import _ "github.com/andlabs/ui/winmanifest"
import "github.com/davecgh/go-spew/spew" import "github.com/davecgh/go-spew/spew"
var DebugToolkit bool = false var defaultBehavior bool = true
var streachy = true var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
var border = true var canvas bool // if set to true, the windows are a raw canvas
var menubar bool // for windows
var stretchy bool // expand things like buttons to the maximum size
var padded bool // add space between things like buttons
var margin bool // add space around the frames of windows
var DebugToolkit bool
func setDefaultBehavior(s bool) {
defaultBehavior = s
if (defaultBehavior) {
log.Println("Setting this toolkit to use the default behavior.")
log.Println("This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
stretchy = false
padded = true
menubar = true
margin = true
canvas = false
bookshelf = true // 99% of the time, things make a vertical stack of objects
DebugToolkit = false
} else {
log.Println("This toolkit is set to ignore the default behavior.")
}
}
func SetDebugToolkit (s bool) {
DebugToolkit = s
}
func GetDebugToolkit () bool {
return DebugToolkit
}
// stores the raw toolkit internals // stores the raw toolkit internals
type Toolkit struct { type Toolkit struct {
@ -31,7 +62,9 @@ type Toolkit struct {
uiButton *ui.Button uiButton *ui.Button
uiControl *ui.Control uiControl *ui.Control
uiCombobox *ui.Combobox uiCombobox *ui.Combobox
uiCheckbox *ui.Checkbox
uiEntry *ui.Entry uiEntry *ui.Entry
uiMultilineEntry *ui.MultilineEntry
uiGroup *ui.Group uiGroup *ui.Group
uiLabel *ui.Label uiLabel *ui.Label
uiSlider *ui.Slider uiSlider *ui.Slider
@ -49,7 +82,18 @@ type Toolkit struct {
text string text string
} }
func (t *Toolkit) String() string {
return t.GetText()
}
func forceDump(t *Toolkit) {
DebugToolkit = true
t.Dump()
DebugToolkit = false
}
func (t *Toolkit) GetText() string { func (t *Toolkit) GetText() string {
forceDump(t)
if (DebugToolkit) { if (DebugToolkit) {
log.Println("gui.Toolkit.Text() Enter") log.Println("gui.Toolkit.Text() Enter")
scs := spew.ConfigState{MaxDepth: 1} scs := spew.ConfigState{MaxDepth: 1}
@ -57,10 +101,19 @@ func (t *Toolkit) GetText() string {
} }
if (t.uiEntry != nil) { if (t.uiEntry != nil) {
if (DebugToolkit) { if (DebugToolkit) {
log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) log.Println("gui.Toolkit.Value() =", t.uiEntry.Text())
} }
return t.uiEntry.Text() return t.uiEntry.Text()
} }
if (t.uiMultilineEntry != nil) {
if (DebugToolkit) {
log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text())
}
text := t.uiMultilineEntry.Text()
log.Println("gui.Toolkit.Value() text =", text)
t.text = text
return text
}
if (t.uiCombobox != nil) { if (t.uiCombobox != nil) {
if (DebugToolkit) { if (DebugToolkit) {
log.Println("gui.Toolkit.GetText() =", t.text) log.Println("gui.Toolkit.GetText() =", t.text)
@ -83,6 +136,13 @@ func (t *Toolkit) SetText(s string) bool {
t.uiEntry.SetText(s) t.uiEntry.SetText(s)
return true return true
} }
if (t.uiMultilineEntry != nil) {
if (DebugToolkit) {
log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text)
}
t.uiMultilineEntry.SetText(s)
return true
}
return false return false
} }
@ -138,34 +198,47 @@ func (t *Toolkit) Value() int {
} }
func (t *Toolkit) Dump() { func (t *Toolkit) Dump() {
log.Println("gui.Toolkit.Dump()", t.Name, t.Width, t.Height) if ! DebugToolkit {
return
}
log.Println("gui.Toolkit.Dump() Name = ", t.Name, t.Width, t.Height)
if (t.uiBox != nil) { if (t.uiBox != nil) {
log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox) log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox)
} }
if (t.uiButton != nil) { if (t.uiButton != nil) {
log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton) log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton)
} }
if (t.uiCombobox != nil) { if (t.uiCombobox != nil) {
log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox) log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox)
} }
if (t.uiWindow != nil) { if (t.uiWindow != nil) {
log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow) log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow)
} }
if (t.uiTab != nil) { if (t.uiTab != nil) {
log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab) log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab)
} }
if (t.uiGroup != nil) { if (t.uiGroup != nil) {
log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup) log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log.Println("gui.Toolkit.Dump() uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log.Println("gui.Toolkit.Dump() uiMultilineEntry =", t.uiMultilineEntry)
} }
if (t.uiSlider != nil) { if (t.uiSlider != nil) {
log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider) log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log.Println("gui.Toolkit.Dump() uiCheckbox =", t.uiCheckbox)
} }
if (t.OnExit != nil) { if (t.OnExit != nil) {
log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit) log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit)
} }
if (t.Custom != nil) { if (t.Custom != nil) {
log.Println("gui.Toolkit.Dump() Custom =", t.Custom) log.Println("gui.Toolkit.Dump() Custom =", t.Custom)
} }
log.Println("gui.Toolkit.Dump() c =", t.c) log.Println("gui.Toolkit.Dump() c =", t.c)
log.Println("gui.Toolkit.Dump() val =", t.val) log.Println("gui.Toolkit.Dump() val =", t.val)
log.Println("gui.Toolkit.Dump() text =", t.text)
} }

View File

@ -22,68 +22,47 @@ import (
any existing tabs rather than adding a new one any existing tabs rather than adding a new one
*/ */
func (t *Toolkit) AddTab(name string) *Toolkit { func (t *Toolkit) AddTab(name string) *Toolkit {
var w *ui.Window // var w *ui.Window
var newt *Toolkit var newt *Toolkit
log.Println("gui.toolkit.AddTab() sleep 3") log.Println("gui.toolkit.AddTab() sleep 3")
w = t.uiWindow if (t.uiWindow == nil) {
if (w == nil) { log.Println("gui.Toolkit.UiWindow == nil. I can't add a toolbar without window")
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
return nil return nil
} }
if (t.uiTab == nil) { if (t.uiTab == nil) {
// this means you have to make a new tab // this means you have to make a new tab
log.Println("gui.toolkit.NewTab() GOOD. This should be the first tab:", name) log.Println("gui.toolkit.NewTab() GOOD. This should be the first tab:", name)
newt = newTab(w, name) newt = newTab(t.uiWindow, name)
t.uiTab = newt.uiTab t.uiTab = newt.uiTab
} else { } else {
// this means you have to append a tab
log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name) log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name)
newt = t.appendTab(name) newt = t.appendTab(name)
// this means you have to append a tab
} }
log.Println("t:")
t.Dump() newt.Name = name
log.Println("newt:")
newt.Dump() if (DebugToolkit) {
log.Println("t:")
t.Dump()
log.Println("newt:")
newt.Dump()
}
return newt return newt
} }
func (t *Toolkit) SetTabBox(box *ui.Box) {
var tab *ui.Tab
log.Println("wit/gui/toolkit SetTabBox()")
t.Dump()
if (t.uiTab == nil) {
log.Println("wit/gui/toolkit SetTabBox() got uiTab == nil")
panic("fucknuts")
return
}
if (t.uiBox == nil) {
log.Println("wit/gui/toolkit SetTabBox() got uiBox == nil. Appending a new tab here")
tab = t.uiTab
tab.Append(t.Name, box)
tabSetMargined(tab)
return
} else {
log.Println("wit/gui/toolkit SetTabBox() got uiBox != nil. Appending the box to the existing box strechy = true")
t.uiBox.Append(box, true) // strechy == true
t.uiBox2 = box
// t.uiBox.Append(box, false) // strechy == false
return
}
}
// 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) {
c := tab.NumPages() c := tab.NumPages()
for i := 0; i < c; i++ { for i := 0; i < c; i++ {
tab.SetMargined(i, true) log.Println("SetMargined", i, margin)
tab.SetMargined(i, margin)
} }
} }
@ -99,20 +78,18 @@ func newTab(w *ui.Window, name string) *Toolkit {
return nil return nil
} }
log.Println("gui.toolkit.AddTab() START name =", name) log.Println("gui.toolkit.AddTab() START name =", name)
// time.Sleep(2 * time.Second)
tab := ui.NewTab() tab := ui.NewTab()
w.SetMargined(true) w.SetMargined(margin)
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
// hbox := ui.NewVerticalBox() hbox.SetPadded(padded)
hbox.SetPadded(true)
tab.Append(name, hbox) tab.Append(name, hbox)
tabSetMargined(tab) // TODO: run this in the right place(?)
w.SetChild(tab) w.SetChild(tab)
t.uiWindow = w t.uiWindow = w
t.uiTab = tab t.uiTab = tab
t.uiBox = hbox t.uiBox = hbox
// tabSetMargined(newNode.uiTab)
return &t return &t
} }
@ -120,24 +97,27 @@ func (t *Toolkit) appendTab(name string) *Toolkit {
log.Println("gui.toolkit.NewTab() ADD", name) log.Println("gui.toolkit.NewTab() ADD", name)
var newT Toolkit var newT Toolkit
if (t.uiWindow == nil) { if (t.uiTab == nil) {
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") log.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it")
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window") panic("should never have happened. wit/gui/toolkit has ui.Tab == nil")
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
time.Sleep(1 * time.Second)
return nil
} }
log.Println("gui.toolkit.AddTab() START name =", name) log.Println("gui.toolkit.AddTab() START name =", name)
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon var hbox *ui.Box
// hbox := ui.NewVerticalBox() if (defaultBehavior) {
hbox.SetPadded(true) hbox = ui.NewHorizontalBox()
} else {
if (bookshelf) {
hbox = ui.NewHorizontalBox()
} else {
hbox = ui.NewVerticalBox()
}
}
hbox.SetPadded(padded)
t.uiTab.Append(name, hbox) t.uiTab.Append(name, hbox)
// w.SetChild(tab)
newT.uiWindow = t.uiWindow newT.uiWindow = t.uiWindow
newT.uiTab = t.uiTab newT.uiTab = t.uiTab
newT.uiBox = hbox newT.uiBox = hbox
// tabSetMargined(newNode.uiTab)
return &newT return &newT
} }

View File

@ -0,0 +1,32 @@
package toolkit
import "log"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
func (t Toolkit) NewTextbox(name string) *Toolkit {
log.Println("gui.Toolkit.NewTextbox()", name)
var newt Toolkit
if t.broken() {
return nil
}
c := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = c
newt.uiBox = t.uiBox
newt.Name = name
if (defaultBehavior) {
t.uiBox.Append(c, true)
} else {
t.uiBox.Append(c, stretchy)
}
c.OnChanged(func(spin *ui.MultilineEntry) {
newt.commonChange("Textbox")
})
return &newt
}

View File

@ -18,8 +18,9 @@ func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) {
func NewWindow(title string, x int, y int) *Toolkit { func NewWindow(title string, x int, y int) *Toolkit {
var t Toolkit var t Toolkit
log.Println("toolkit NewWindow", title, x, y) log.Println("toolkit NewWindow", title, x, y)
w := ui.NewWindow(title, x, y, false) w := ui.NewWindow(title, x, y, menubar)
w.SetBorderless(false) w.SetBorderless(canvas)
w.SetMargined(margin)
w.OnClosing(func(*ui.Window) bool { w.OnClosing(func(*ui.Window) bool {
log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here") log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here")
t.Dump() t.Dump()
@ -34,7 +35,6 @@ func NewWindow(title string, x int, y int) *Toolkit {
log.Println("ui.Window().OnExit() Toolkit.OnExit is nil") log.Println("ui.Window().OnExit() Toolkit.OnExit is nil")
return true return true
}) })
w.SetMargined(true)
w.Show() w.Show()
t.uiWindow = w t.uiWindow = w
t.UiWindowBad = w // deprecate this as soon as possible t.UiWindowBad = w // deprecate this as soon as possible

View File

@ -31,8 +31,10 @@ func DebugTab() {
bugWin.DebugTab("does this work?") bugWin.DebugTab("does this work?")
} }
var checkd, checkdn, checkdt, checkdtk *Node
func (n *Node) DebugTab(title string) *Node { func (n *Node) DebugTab(title string) *Node {
var newN, gog, g1, g2, g3, dd *Node var newN, gog, g1, g2, g3, dd, gf *Node
// time.Sleep(1 * time.Second) // time.Sleep(1 * time.Second)
newN = n.NewTab(title) newN = n.NewTab(title)
@ -40,20 +42,53 @@ func (n *Node) DebugTab(title string) *Node {
gog = newN.NewGroup("GOLANG") gog = newN.NewGroup("GOLANG")
gog.NewLabel("go language") gog.NewLabel("go language")
gog.AddButton("GO Language Debug", func (*Node) { gog.NewButton("GO Language Debug", func () {
GolangDebugWindow() GolangDebugWindow()
}) })
gf = newN.NewGroup("Debug Flags")
gf.NewLabel("flags to control debugging output")
checkd = gf.NewCheckbox("Debug")
checkd.OnChanged = func(*Node) {
checkd.checked = checkd.toolkit.Checked()
Config.Debug = checkd.checked
if (Config.Debug) {
} else {
}
}
checkdn = gf.NewCheckbox("Debug Node")
checkdn.OnChanged = func(*Node) {
checkdn.checked = checkdn.toolkit.Checked()
Config.DebugNode = checkdn.checked
}
checkdd := gf.NewCheckbox("Debug node.Dump()")
checkdd.OnChanged = func(*Node) {
Config.DebugDump = checkdd.toolkit.Checked()
}
checkdt = gf.NewCheckbox("Debug Tabs")
checkdtk = gf.NewCheckbox("Debug Toolkit")
// Debug bool
// DebugNode bool
// DebugTabs bool
// DebugTable bool
// DebugWindow bool
// DebugToolkit bool
gog.NewLabel("wit/gui package") gog.NewLabel("wit/gui package")
gog.AddButton("WIT/GUI Package Debug", func (*Node) { gog.NewButton("WIT/GUI Package Debug", func () {
Config.Width = 640 Config.Width = 640
Config.Height = 480 Config.Height = 480
Queue(DebugWindow) Queue(DebugWindow)
}) })
gog.AddButton("Demo wit/gui", func (*Node) { gog.NewButton("Demo wit/gui", func () {
DemoWindow() DemoWindow()
}) })
gog.AddButton("Demo toolkit andlabs/ui", func (*Node) { gog.NewButton("Demo toolkit andlabs/ui", func () {
DemoToolkitWindow() DemoToolkitWindow()
}) })
@ -78,38 +113,38 @@ func (n *Node) DebugTab(title string) *Node {
dd.SetDropdown(0) dd.SetDropdown(0)
g2 = newN.NewGroup("Debug Window") g2 = newN.NewGroup("Debug Window")
g2.AddButton("SetMargined(tab)", func (*Node) { g2.NewButton("SetMargined(tab)", func () {
log.Println("\tSTART") log.Println("\tSTART")
name := dd.GetText() name := dd.GetText()
log.Println("\tENDed with", name) log.Println("\tENDed with", name)
// gw.UiTab.SetMargined(*gw.TabNumber, true) // gw.UiTab.SetMargined(*gw.TabNumber, true)
}) })
g2.AddButton("Hide(tab)", func (*Node) { g2.NewButton("Hide(tab)", func () {
// gw.UiTab.Hide() // gw.UiTab.Hide()
}) })
g2.AddButton("Show(tab)", func (*Node) { g2.NewButton("Show(tab)", func () {
// gw.UiTab.Show() // gw.UiTab.Show()
}) })
g2.AddButton("Delete(tab)", func (*Node) { g2.NewButton("Delete(tab)", func () {
// gw.UiTab.Delete(*gw.TabNumber) // gw.UiTab.Delete(*gw.TabNumber)
}) })
g2.AddButton("change Title", func (*Node) { g2.NewButton("change Title", func () {
// mainWindow.SetText("hello world") // mainWindow.SetText("hello world")
}) })
///////////////////////////////////////////////////// /////////////////////////////////////////////////////
g3 = newN.NewGroup("Node Debug") g3 = newN.NewGroup("Node Debug")
g3.AddButton("Node.Dump()", func (n *Node) { g3.NewButton("Node.Dump()", func () {
n.Dump() bugWin.Dump()
}) })
g3.AddButton("Node.ListChildren(false)", func (n *Node) { g3.NewButton("Node.ListChildren(false)", func () {
n.ListChildren(false) bugWin.ListChildren(false)
}) })
g3.AddButton("Node.ListChildren(true)", func (n *Node) { g3.NewButton("Node.ListChildren(true)", func () {
n.ListChildren(true) bugWin.ListChildren(true)
}) })
g3.AddButton("AddDebugTab()", func (n *Node) { g3.NewButton("AddDebugTab()", func () {
if (bugWin != nil) { if (bugWin != nil) {
bugWin.DebugTab("added this DebugTab") bugWin.DebugTab("added this DebugTab")
} }

View File

@ -31,46 +31,46 @@ func GolangDebugWindow() {
/////////////////////////////// Column DEBUG GOLANG ////////////////////// /////////////////////////////// Column DEBUG GOLANG //////////////////////
g := t.AddGroup("GO Language") g := t.NewGroup("GO Language")
g.AddButton("runtime.Stack()", func (*Node) { g.NewButton("runtime.Stack()", func () {
log.Println("\tSTART") log.Println("\tSTART")
buf := make([]byte, 1<<16) buf := make([]byte, 1<<16)
runtime.Stack(buf, true) runtime.Stack(buf, true)
log.Printf("%s", buf) log.Printf("%s", buf)
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("dumpModuleInfo()", func (*Node) { g.NewButton("dumpModuleInfo()", func () {
log.Println("\tSTART") log.Println("\tSTART")
dumpModuleInfo() dumpModuleInfo()
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("debug.PrintStack()", func (*Node) { g.NewButton("debug.PrintStack()", func () {
log.Println("\tSTART") log.Println("\tSTART")
debug.PrintStack() debug.PrintStack()
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("pprof.Lookup(goroutine)", func (*Node) { g.NewButton("pprof.Lookup(goroutine)", func () {
log.Println("\tSTART") log.Println("\tSTART")
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1) pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("pprof.Lookup(heap)", func (*Node) { g.NewButton("pprof.Lookup(heap)", func () {
log.Println("\tSTART") log.Println("\tSTART")
pprof.Lookup("heap").WriteTo(os.Stdout, 1) pprof.Lookup("heap").WriteTo(os.Stdout, 1)
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("pprof.Lookup(block)", func (*Node) { g.NewButton("pprof.Lookup(block)", func () {
log.Println("\tSTART") log.Println("\tSTART")
pprof.Lookup("block").WriteTo(os.Stdout, 1) pprof.Lookup("block").WriteTo(os.Stdout, 1)
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("pprof.Lookup threadcreate", func (*Node) { g.NewButton("pprof.Lookup threadcreate", func () {
log.Println("\tSTART") log.Println("\tSTART")
pprof.Lookup("threadcreate").WriteTo(os.Stdout, 1) pprof.Lookup("threadcreate").WriteTo(os.Stdout, 1)
log.Println("\tEND") log.Println("\tEND")
}) })
g.AddButton("runtime.ReadMemStats", func (*Node) { g.NewButton("runtime.ReadMemStats", func () {
var s runtime.MemStats var s runtime.MemStats
runtime.ReadMemStats(&s) runtime.ReadMemStats(&s)
log.Printf("alloc: %v bytes\n", s.Alloc) log.Printf("alloc: %v bytes\n", s.Alloc)

View File

@ -19,21 +19,21 @@ func NewWindow() *Node {
title := Config.Title title := Config.Title
w := Config.Width w := Config.Width
h := Config.Height h := Config.Height
f := Config.Exit // f := Config.Exit
// Windows are created off of the master node of the Binary Tree // Windows are created off of the master node of the Binary Tree
n = Config.master.New(title) n = Config.master.New(title)
n.custom = f // n.custom = f
t = toolkit.NewWindow(title, w, h) t = toolkit.NewWindow(title, w, h)
t.Custom = func () { t.Custom = func () {
log.Println("Got to wit/gui Window Close for window:", title) log.Println("Got to wit/gui Window Close START user defined close()")
if (n.custom == nil) { if (n.custom == nil) {
log.Println("Got to wit/gui Window Close custom() == nil") log.Println("Got to wit/gui Window Close SKIP node.custom() == nil")
return
} }
log.Println("Got to wit/gui Window Close START custom()") n.custom()
n.custom(n) log.Println("Got to wit/gui Window Close END user defined close()")
log.Println("Got to wit/gui Window Close END custom()")
} }
n.toolkit = t n.toolkit = t