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:
parent
d28f0eb8c1
commit
c5735353a6
6
Makefile
6
Makefile
|
@ -22,3 +22,9 @@ examples-gui-demo:
|
|||
|
||||
doc:
|
||||
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
256
README.md
|
@ -1,14 +1,248 @@
|
|||
This is an abstraction layer around the excellent
|
||||
cross platform UI toolkit from andlabs/ui
|
||||
# gui
|
||||
|
||||
This abstraction layer makes it easier to write
|
||||
simple interfaces for like our cloud control panel
|
||||
Package gui implements a abstraction layer for Go visual elements in
|
||||
a cross platform and library independent way. (hopefully this is will work)
|
||||
|
||||
The cross platform UI has 'quirks' due to it being
|
||||
cross platform. Some of the abstraction layer here
|
||||
attemps to obfuscate the ui objects so that it is
|
||||
more difficult to trigger inconsistancies.
|
||||
A quick overview of the features, some general design guidelines
|
||||
and principles for how this package should generally work:
|
||||
|
||||
In this regard, this is an attempt to restrict
|
||||
all andlabs/ui (and andlabs/libui) interaction to
|
||||
the calls within this library.
|
||||
Definitions:
|
||||
|
||||
```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)
|
||||
|
|
|
@ -2,7 +2,7 @@ package gui
|
|||
|
||||
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) {
|
||||
log.Println("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.toolkit = n.toolkit.NewButton(name)
|
||||
|
||||
// TODO: this is still confusing and probably wrong. This needs to communicate through a channel
|
||||
newNode.toolkit.Custom = func() {
|
||||
log.Println("gui.AppendButton() Button Clicked. Running custom()")
|
||||
custom(newNode)
|
||||
log.Println("gui.AppendButton() Button Clicked. Running custom() from outside toolkit START")
|
||||
custom()
|
||||
log.Println("gui.AppendButton() Button Clicked. Running custom() from outside toolkit END")
|
||||
}
|
||||
newNode.custom = custom
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -4,6 +4,7 @@ run: build
|
|||
build-release:
|
||||
go get -v -u -x .
|
||||
go build
|
||||
./helloworld
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go get -v -x .
|
||||
|
|
45
doc.go
45
doc.go
|
@ -1,4 +1,5 @@
|
|||
/*
|
||||
|
||||
Package gui implements a abstraction layer for Go visual elements in
|
||||
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.
|
||||
* Hide complexity internally here
|
||||
* Isolate the GUI toolkit
|
||||
* Function names should follow https://en.wikipedia.org/wiki/Graphical_widget
|
||||
* Function names should follow [Wikipedia Graphical widget]
|
||||
|
||||
|
||||
Quick Start
|
||||
|
||||
|
@ -28,31 +30,51 @@ sections below for further details on formatting and configuration options.
|
|||
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
|
||||
// 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
|
||||
node1 := gui.NewWindow()
|
||||
addDemoTab(node1, "A Simple Tab Demo")
|
||||
addDemoTab(node1, "A Second Tab")
|
||||
|
||||
window := gui.NewWindow()
|
||||
addTab(window, "A Simple Tab Demo")
|
||||
addTab(window, "A Second Tab")
|
||||
}
|
||||
|
||||
func addDemoTab(n *gui.Node, title string) {
|
||||
newNode := n.AddTab(title, nil)
|
||||
func addTab(w *gui.Node, title string) {
|
||||
tab := w.NewTab(title)
|
||||
|
||||
groupNode1 := newNode.NewGroup("group 1")
|
||||
groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
||||
group := tab.NewGroup("foo bar")
|
||||
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'
|
||||
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
|
||||
hopefully also things like libSDL, faiface/pixel, slint
|
||||
|
||||
[Wikipedia Graphical widget]: https://en.wikipedia.org/wiki/Graphical_widget
|
||||
|
||||
Errors
|
||||
|
||||
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'
|
||||
|
||||
External References
|
||||
|
||||
*/
|
||||
package gui
|
||||
|
|
38
dropdown.go
38
dropdown.go
|
@ -4,40 +4,40 @@ import "log"
|
|||
|
||||
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 {
|
||||
var newT *toolkit.Toolkit
|
||||
var sNode *Node
|
||||
|
||||
log.Println("toolkit.NewDropdown() START", name)
|
||||
|
||||
// make this generic
|
||||
if (n.toolkit == nil) {
|
||||
log.Println("toolkit.NewSlider() toolkit == nil")
|
||||
panic("toolkit should never be nil")
|
||||
}
|
||||
n.verify()
|
||||
|
||||
sNode = n.New(name + " part1")
|
||||
newT = n.toolkit.NewDropdown(name)
|
||||
newT.Name = name
|
||||
sNode.custom = n.custom
|
||||
newT.Custom = func () {
|
||||
// TODO: make all of this common code to all the widgets
|
||||
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)
|
||||
}
|
||||
commonCallback(sNode)
|
||||
}
|
||||
sNode.toolkit = newT
|
||||
sNode.Dump()
|
||||
sNode.toolkit.Dump()
|
||||
// panic("checking Custom()")
|
||||
|
||||
return sNode
|
||||
|
|
5
group.go
5
group.go
|
@ -17,15 +17,16 @@ func (n *Node) NewGroup(name string) *Node {
|
|||
}
|
||||
|
||||
// make a *Node with a *toolkit.Group
|
||||
gNode = n.New(name + " part1")
|
||||
gNode = n.New(name)
|
||||
newT = n.toolkit.NewGroup(name)
|
||||
gNode.toolkit = newT
|
||||
log.Println("################## gNode ####### ", name)
|
||||
gNode.Dump()
|
||||
|
||||
return gNode
|
||||
}
|
||||
|
||||
/*
|
||||
func (n *Node) AddGroup(title string) *Node {
|
||||
return n.NewGroup(title + " deprecated AddGroup")
|
||||
}
|
||||
*/
|
||||
|
|
4
int.go
4
int.go
|
@ -4,6 +4,8 @@ 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
|
||||
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)
|
||||
*/
|
||||
func (n *Node) Int() int {
|
||||
if (Config.DebugToolkit) {
|
||||
if (toolkit.DebugToolkit) {
|
||||
log.Println("gui.Node.Int() for node name =", n.Name)
|
||||
scs := spew.ConfigState{MaxDepth: 1}
|
||||
scs.Dump(n)
|
||||
|
|
4
main.go
4
main.go
|
@ -23,10 +23,10 @@ func init() {
|
|||
title := "master"
|
||||
w := 640
|
||||
h := 480
|
||||
f := StandardClose
|
||||
// f := StandardClose
|
||||
|
||||
Config.master = addNode(title, w, h)
|
||||
Config.master.custom = f
|
||||
// Config.master.custom = f
|
||||
|
||||
Config.master.Dump()
|
||||
}
|
||||
|
|
19
slider.go
19
slider.go
|
@ -10,10 +10,7 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
|
|||
|
||||
log.Println("toolkit.NewSlider() START", name)
|
||||
|
||||
if (n.toolkit == nil) {
|
||||
log.Println("toolkit.NewSlider() toolkit == nil")
|
||||
panic("Toolkit should never be nil")
|
||||
}
|
||||
n.verify()
|
||||
|
||||
// make a *Node with a *toolkit.Group
|
||||
sNode = n.New(name + " part1")
|
||||
|
@ -21,19 +18,7 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
|
|||
newT.Name = name
|
||||
sNode.custom = n.custom
|
||||
newT.Custom = func () {
|
||||
// TODO: make all of this common code to all the widgets
|
||||
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)
|
||||
}
|
||||
commonCallback(sNode)
|
||||
}
|
||||
sNode.toolkit = newT
|
||||
sNode.Dump()
|
||||
|
|
11
spinner.go
11
spinner.go
|
@ -10,17 +10,18 @@ func (n *Node) NewSpinner(name string, x int, y int) *Node {
|
|||
|
||||
log.Println("toolkit.NewSpinner() START", name)
|
||||
|
||||
if (n.toolkit == nil) {
|
||||
log.Println("toolkit.NewSpinner() toolkit == nil")
|
||||
panic("toolkit should never be nil")
|
||||
}
|
||||
n.verify()
|
||||
|
||||
// make a *Node with a *toolkit.Group
|
||||
sNode = n.New(name + " part1")
|
||||
newT = n.toolkit.NewSpinner(name, x, y)
|
||||
newT.Name = name
|
||||
sNode.toolkit = newT
|
||||
sNode.Dump()
|
||||
// sNode.Dump()
|
||||
|
||||
newT.Custom = func () {
|
||||
commonCallback(sNode)
|
||||
}
|
||||
|
||||
return sNode
|
||||
}
|
||||
|
|
46
structs.go
46
structs.go
|
@ -2,7 +2,7 @@ package gui
|
|||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"reflect"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
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 {
|
||||
// This is the master node. The Binary Tree starts here
|
||||
master *Node
|
||||
|
@ -34,11 +53,11 @@ type GuiConfig struct {
|
|||
// These are global debugging settings
|
||||
// TODO: move to a standard logging system
|
||||
Debug bool
|
||||
DebugDump bool
|
||||
DebugNode bool
|
||||
DebugTabs bool
|
||||
DebugTable bool
|
||||
DebugWindow bool
|
||||
DebugToolkit bool
|
||||
|
||||
// hacks
|
||||
depth int
|
||||
|
@ -84,10 +103,14 @@ type Node struct {
|
|||
Height int
|
||||
|
||||
parent *Node
|
||||
// TODO: make children a double linked list since some toolkits require order
|
||||
children []*Node
|
||||
|
||||
custom func(*Node)
|
||||
// things that may not really be needed (?)
|
||||
custom func()
|
||||
OnChanged func(*Node)
|
||||
checked bool
|
||||
text string
|
||||
|
||||
toolkit *toolkit.Toolkit
|
||||
}
|
||||
|
@ -101,6 +124,10 @@ func (n *Node) Window() *Node {
|
|||
}
|
||||
|
||||
func (n *Node) Dump() {
|
||||
if ! Config.DebugDump {
|
||||
return
|
||||
}
|
||||
IndentPrintln("NODE DUMP START")
|
||||
IndentPrintln("id = ", n.id)
|
||||
IndentPrintln("Name = ", n.Name)
|
||||
IndentPrintln("Width = ", n.Width)
|
||||
|
@ -109,27 +136,30 @@ func (n *Node) Dump() {
|
|||
if (n.parent == nil) {
|
||||
IndentPrintln("parent = nil")
|
||||
} else {
|
||||
IndentPrintln("parent =", n.parent.id)
|
||||
IndentPrintln("parent.id =", n.parent.id)
|
||||
}
|
||||
if (n.children != nil) {
|
||||
IndentPrintln("children = ", n.children)
|
||||
}
|
||||
if (n.toolkit != nil) {
|
||||
IndentPrintln("toolkit = ", n.toolkit)
|
||||
n.toolkit.Dump()
|
||||
}
|
||||
if (n.custom != nil) {
|
||||
IndentPrintln("custom = ", n.custom)
|
||||
}
|
||||
IndentPrintln("checked = ", n.checked)
|
||||
if (n.OnChanged != nil) {
|
||||
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 == "") {
|
||||
// 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")
|
||||
}
|
||||
IndentPrintln("NODE DUMP END")
|
||||
}
|
||||
|
||||
func (n *Node) SetName(name string) {
|
||||
|
|
21
text.go
21
text.go
|
@ -1,7 +1,7 @@
|
|||
package gui
|
||||
|
||||
import "log"
|
||||
import "errors"
|
||||
// import "errors"
|
||||
import "regexp"
|
||||
|
||||
// functions for handling text related GUI elements
|
||||
|
@ -17,10 +17,17 @@ func (n *Node) NewLabel(text string) *Node {
|
|||
return newNode
|
||||
}
|
||||
|
||||
func (n *Node) SetText(value string) error {
|
||||
log.Println("gui.SetText() value =", value)
|
||||
panic("redo SetText()")
|
||||
return errors.New("nothing found for gui.Node.SetText()")
|
||||
func (n *Node) SetText(str string) bool {
|
||||
log.Println("gui.SetText() value =", str)
|
||||
if (n.toolkit == nil) {
|
||||
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)
|
||||
return clean
|
||||
}
|
||||
|
||||
func (n *Node) GetText() string {
|
||||
return n.toolkit.GetText()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -15,35 +15,29 @@ func (t *Toolkit) NewBox() *Toolkit {
|
|||
log.Println("gui.Toolbox.NewBox() START create default")
|
||||
t.Dump()
|
||||
if (t.uiGroup != nil) {
|
||||
log.Println("gui.Toolbox.NewBox() is a Group")
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Group")
|
||||
var newTK Toolkit
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
vbox.SetPadded(true)
|
||||
vbox.SetPadded(padded)
|
||||
t.uiGroup.SetChild(vbox)
|
||||
newTK.uiBox = vbox
|
||||
|
||||
return &newTK
|
||||
}
|
||||
if (t.uiBox != nil) {
|
||||
log.Println("gui.Toolbox.NewBox() is a Box")
|
||||
// return t
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Box")
|
||||
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()
|
||||
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
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ func (t Toolkit) NewButton(name string) *Toolkit {
|
|||
log.Println("TODO: LEFT TOOLKIT GOROUTINE button name =", name)
|
||||
})
|
||||
|
||||
t.uiBox.Append(b, false)
|
||||
t.uiBox.Append(b, stretchy)
|
||||
|
||||
return &newt
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -5,7 +5,12 @@ import "log"
|
|||
import "github.com/andlabs/ui"
|
||||
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 {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
|
@ -17,54 +22,15 @@ func BlankWindow(w *ui.Window) *ui.Box {
|
|||
func (t *Toolkit) DemoNumbersPage() {
|
||||
var w *ui.Window
|
||||
|
||||
log.Println("Starting wit/gui toolkit andlabs/ui DemoNumbersPage()")
|
||||
|
||||
w = t.uiWindow
|
||||
t.uiBox = makeNumbersPage()
|
||||
t.uiBox.SetPadded(true)
|
||||
w.SetChild(t.uiBox)
|
||||
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 {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
|
|
|
@ -7,23 +7,19 @@ import "os"
|
|||
import "github.com/andlabs/ui"
|
||||
import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
import "github.com/davecgh/go-spew/spew"
|
||||
|
||||
func (pt *Toolkit) NewDropdown(title string) *Toolkit {
|
||||
func (t *Toolkit) NewDropdown(title string) *Toolkit {
|
||||
// make new node here
|
||||
log.Println("gui.Toolbox.NewDropdownCombobox()")
|
||||
var newt Toolkit
|
||||
|
||||
if (pt.uiBox == nil) {
|
||||
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)
|
||||
if t.broken() {
|
||||
return nil
|
||||
}
|
||||
|
||||
s := ui.NewCombobox()
|
||||
newt.uiCombobox = s
|
||||
newt.uiBox = pt.uiBox
|
||||
pt.uiBox.Append(s, false)
|
||||
newt.uiBox = t.uiBox
|
||||
t.uiBox.Append(s, stretchy)
|
||||
|
||||
// initialize the index
|
||||
newt.c = 0
|
||||
|
@ -36,24 +32,7 @@ func (pt *Toolkit) NewDropdown(title string) *Toolkit {
|
|||
os.Exit(0)
|
||||
}
|
||||
newt.text = newt.val[i]
|
||||
val := newt.text
|
||||
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)
|
||||
newt.commonChange("Dropdown")
|
||||
})
|
||||
|
||||
return &newt
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -19,11 +19,11 @@ func (t Toolkit) NewGroup(title string) *Toolkit {
|
|||
|
||||
log.Println("gui.Toolbox.NewGroup() create", title)
|
||||
g := ui.NewGroup(title)
|
||||
g.SetMargined(true)
|
||||
t.uiBox.Append(g, streachy)
|
||||
g.SetMargined(margin)
|
||||
t.uiBox.Append(g, stretchy)
|
||||
|
||||
hbox := ui.NewVerticalBox()
|
||||
hbox.SetPadded(true)
|
||||
hbox.SetPadded(padded)
|
||||
g.SetChild(hbox)
|
||||
|
||||
newt.uiGroup = g
|
||||
|
|
|
@ -1,31 +1,21 @@
|
|||
package toolkit
|
||||
|
||||
import "log"
|
||||
import "os"
|
||||
|
||||
import "github.com/andlabs/ui"
|
||||
import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
// func NewLabel(b *ui.Box, name string) *Toolkit {
|
||||
|
||||
func (t *Toolkit) NewLabel(name string) *Toolkit {
|
||||
// make new node here
|
||||
log.Println("gui.Toolbox.NewLabel", name)
|
||||
|
||||
if (t.uiBox == nil) {
|
||||
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)
|
||||
if t.broken() {
|
||||
return nil
|
||||
}
|
||||
var newt Toolkit
|
||||
newt.uiLabel = ui.NewLabel(name)
|
||||
newt.uiBox = t.uiBox
|
||||
t.uiBox.Append(newt.uiLabel, false)
|
||||
log.Println("parent toolkit")
|
||||
t.Dump()
|
||||
log.Println("newt toolkit")
|
||||
newt.Dump()
|
||||
// panic("got here")
|
||||
|
||||
return &newt
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit {
|
|||
s := ui.NewSlider(x, y)
|
||||
newt.uiSlider = s
|
||||
newt.uiBox = t.uiBox
|
||||
t.uiBox.Append(s, false)
|
||||
t.uiBox.Append(s, stretchy)
|
||||
|
||||
s.OnChanged(func(spin *ui.Slider) {
|
||||
i := spin.Value()
|
||||
|
|
|
@ -23,7 +23,7 @@ func (t Toolkit) NewSpinner(title string, x int, y int) *Toolkit {
|
|||
s := ui.NewSpinbox(x, y)
|
||||
newt.uiSpinbox = s
|
||||
newt.uiBox = t.uiBox
|
||||
t.uiBox.Append(s, false)
|
||||
t.uiBox.Append(s, stretchy)
|
||||
|
||||
s.OnChanged(func(s *ui.Spinbox) {
|
||||
i := s.Value()
|
||||
|
|
|
@ -7,11 +7,42 @@ import _ "github.com/andlabs/ui/winmanifest"
|
|||
|
||||
import "github.com/davecgh/go-spew/spew"
|
||||
|
||||
var DebugToolkit bool = false
|
||||
var defaultBehavior bool = true
|
||||
|
||||
var streachy = true
|
||||
var border = true
|
||||
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
||||
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
|
||||
type Toolkit struct {
|
||||
|
@ -31,7 +62,9 @@ type Toolkit struct {
|
|||
uiButton *ui.Button
|
||||
uiControl *ui.Control
|
||||
uiCombobox *ui.Combobox
|
||||
uiCheckbox *ui.Checkbox
|
||||
uiEntry *ui.Entry
|
||||
uiMultilineEntry *ui.MultilineEntry
|
||||
uiGroup *ui.Group
|
||||
uiLabel *ui.Label
|
||||
uiSlider *ui.Slider
|
||||
|
@ -49,7 +82,18 @@ type Toolkit struct {
|
|||
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 {
|
||||
forceDump(t)
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolkit.Text() Enter")
|
||||
scs := spew.ConfigState{MaxDepth: 1}
|
||||
|
@ -57,10 +101,19 @@ func (t *Toolkit) GetText() string {
|
|||
}
|
||||
if (t.uiEntry != nil) {
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolkit.Value() =", t.uiEntry.Text)
|
||||
log.Println("gui.Toolkit.Value() =", 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 (DebugToolkit) {
|
||||
log.Println("gui.Toolkit.GetText() =", t.text)
|
||||
|
@ -83,6 +136,13 @@ func (t *Toolkit) SetText(s string) bool {
|
|||
t.uiEntry.SetText(s)
|
||||
return true
|
||||
}
|
||||
if (t.uiMultilineEntry != nil) {
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolkit.Value() =", t.uiMultilineEntry.Text)
|
||||
}
|
||||
t.uiMultilineEntry.SetText(s)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -138,34 +198,47 @@ func (t *Toolkit) Value() int {
|
|||
}
|
||||
|
||||
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) {
|
||||
log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox)
|
||||
log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox)
|
||||
}
|
||||
if (t.uiButton != nil) {
|
||||
log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton)
|
||||
log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton)
|
||||
}
|
||||
if (t.uiCombobox != nil) {
|
||||
log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox)
|
||||
log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox)
|
||||
}
|
||||
if (t.uiWindow != nil) {
|
||||
log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow)
|
||||
log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow)
|
||||
}
|
||||
if (t.uiTab != nil) {
|
||||
log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab)
|
||||
log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab)
|
||||
}
|
||||
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) {
|
||||
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) {
|
||||
log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit)
|
||||
log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit)
|
||||
}
|
||||
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() val =", t.val)
|
||||
log.Println("gui.Toolkit.Dump() c =", t.c)
|
||||
log.Println("gui.Toolkit.Dump() val =", t.val)
|
||||
log.Println("gui.Toolkit.Dump() text =", t.text)
|
||||
}
|
||||
|
|
|
@ -22,68 +22,47 @@ import (
|
|||
any existing tabs rather than adding a new one
|
||||
*/
|
||||
func (t *Toolkit) AddTab(name string) *Toolkit {
|
||||
var w *ui.Window
|
||||
// var w *ui.Window
|
||||
var newt *Toolkit
|
||||
|
||||
log.Println("gui.toolkit.AddTab() sleep 3")
|
||||
|
||||
w = t.uiWindow
|
||||
if (w == nil) {
|
||||
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||
if (t.uiWindow == nil) {
|
||||
log.Println("gui.Toolkit.UiWindow == nil. I can't add a toolbar without window")
|
||||
return nil
|
||||
}
|
||||
|
||||
if (t.uiTab == nil) {
|
||||
// this means you have to make a new tab
|
||||
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
|
||||
} else {
|
||||
// this means you have to append a tab
|
||||
log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name)
|
||||
newt = t.appendTab(name)
|
||||
// this means you have to append a tab
|
||||
}
|
||||
log.Println("t:")
|
||||
t.Dump()
|
||||
log.Println("newt:")
|
||||
newt.Dump()
|
||||
|
||||
newt.Name = name
|
||||
|
||||
if (DebugToolkit) {
|
||||
log.Println("t:")
|
||||
t.Dump()
|
||||
log.Println("newt:")
|
||||
newt.Dump()
|
||||
}
|
||||
|
||||
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
|
||||
//
|
||||
// TODO: do proper tab tracking (will be complicated). low priority
|
||||
func tabSetMargined(tab *ui.Tab) {
|
||||
c := tab.NumPages()
|
||||
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
|
||||
}
|
||||
log.Println("gui.toolkit.AddTab() START name =", name)
|
||||
// time.Sleep(2 * time.Second)
|
||||
tab := ui.NewTab()
|
||||
w.SetMargined(true)
|
||||
w.SetMargined(margin)
|
||||
|
||||
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
|
||||
// hbox := ui.NewVerticalBox()
|
||||
hbox.SetPadded(true)
|
||||
hbox.SetPadded(padded)
|
||||
tab.Append(name, hbox)
|
||||
tabSetMargined(tab) // TODO: run this in the right place(?)
|
||||
w.SetChild(tab)
|
||||
|
||||
t.uiWindow = w
|
||||
t.uiTab = tab
|
||||
t.uiBox = hbox
|
||||
// tabSetMargined(newNode.uiTab)
|
||||
return &t
|
||||
}
|
||||
|
||||
|
@ -120,24 +97,27 @@ func (t *Toolkit) appendTab(name string) *Toolkit {
|
|||
log.Println("gui.toolkit.NewTab() ADD", name)
|
||||
var newT Toolkit
|
||||
|
||||
if (t.uiWindow == nil) {
|
||||
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||
time.Sleep(1 * time.Second)
|
||||
return nil
|
||||
if (t.uiTab == nil) {
|
||||
log.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it")
|
||||
panic("should never have happened. wit/gui/toolkit has ui.Tab == nil")
|
||||
}
|
||||
log.Println("gui.toolkit.AddTab() START name =", name)
|
||||
|
||||
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
|
||||
// hbox := ui.NewVerticalBox()
|
||||
hbox.SetPadded(true)
|
||||
var hbox *ui.Box
|
||||
if (defaultBehavior) {
|
||||
hbox = ui.NewHorizontalBox()
|
||||
} else {
|
||||
if (bookshelf) {
|
||||
hbox = ui.NewHorizontalBox()
|
||||
} else {
|
||||
hbox = ui.NewVerticalBox()
|
||||
}
|
||||
}
|
||||
hbox.SetPadded(padded)
|
||||
t.uiTab.Append(name, hbox)
|
||||
// w.SetChild(tab)
|
||||
|
||||
newT.uiWindow = t.uiWindow
|
||||
newT.uiTab = t.uiTab
|
||||
newT.uiBox = hbox
|
||||
// tabSetMargined(newNode.uiTab)
|
||||
return &newT
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -18,8 +18,9 @@ func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) {
|
|||
func NewWindow(title string, x int, y int) *Toolkit {
|
||||
var t Toolkit
|
||||
log.Println("toolkit NewWindow", title, x, y)
|
||||
w := ui.NewWindow(title, x, y, false)
|
||||
w.SetBorderless(false)
|
||||
w := ui.NewWindow(title, x, y, menubar)
|
||||
w.SetBorderless(canvas)
|
||||
w.SetMargined(margin)
|
||||
w.OnClosing(func(*ui.Window) bool {
|
||||
log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here")
|
||||
t.Dump()
|
||||
|
@ -34,7 +35,6 @@ func NewWindow(title string, x int, y int) *Toolkit {
|
|||
log.Println("ui.Window().OnExit() Toolkit.OnExit is nil")
|
||||
return true
|
||||
})
|
||||
w.SetMargined(true)
|
||||
w.Show()
|
||||
t.uiWindow = w
|
||||
t.UiWindowBad = w // deprecate this as soon as possible
|
||||
|
|
|
@ -31,8 +31,10 @@ func DebugTab() {
|
|||
bugWin.DebugTab("does this work?")
|
||||
}
|
||||
|
||||
var checkd, checkdn, checkdt, checkdtk *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)
|
||||
newN = n.NewTab(title)
|
||||
|
@ -40,20 +42,53 @@ func (n *Node) DebugTab(title string) *Node {
|
|||
|
||||
gog = newN.NewGroup("GOLANG")
|
||||
gog.NewLabel("go language")
|
||||
gog.AddButton("GO Language Debug", func (*Node) {
|
||||
gog.NewButton("GO Language Debug", func () {
|
||||
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.AddButton("WIT/GUI Package Debug", func (*Node) {
|
||||
gog.NewButton("WIT/GUI Package Debug", func () {
|
||||
Config.Width = 640
|
||||
Config.Height = 480
|
||||
Queue(DebugWindow)
|
||||
})
|
||||
gog.AddButton("Demo wit/gui", func (*Node) {
|
||||
gog.NewButton("Demo wit/gui", func () {
|
||||
DemoWindow()
|
||||
})
|
||||
gog.AddButton("Demo toolkit andlabs/ui", func (*Node) {
|
||||
gog.NewButton("Demo toolkit andlabs/ui", func () {
|
||||
DemoToolkitWindow()
|
||||
})
|
||||
|
||||
|
@ -78,38 +113,38 @@ func (n *Node) DebugTab(title string) *Node {
|
|||
dd.SetDropdown(0)
|
||||
|
||||
g2 = newN.NewGroup("Debug Window")
|
||||
g2.AddButton("SetMargined(tab)", func (*Node) {
|
||||
g2.NewButton("SetMargined(tab)", func () {
|
||||
log.Println("\tSTART")
|
||||
name := dd.GetText()
|
||||
log.Println("\tENDed with", name)
|
||||
// gw.UiTab.SetMargined(*gw.TabNumber, true)
|
||||
})
|
||||
g2.AddButton("Hide(tab)", func (*Node) {
|
||||
g2.NewButton("Hide(tab)", func () {
|
||||
// gw.UiTab.Hide()
|
||||
})
|
||||
g2.AddButton("Show(tab)", func (*Node) {
|
||||
g2.NewButton("Show(tab)", func () {
|
||||
// gw.UiTab.Show()
|
||||
})
|
||||
g2.AddButton("Delete(tab)", func (*Node) {
|
||||
g2.NewButton("Delete(tab)", func () {
|
||||
// gw.UiTab.Delete(*gw.TabNumber)
|
||||
})
|
||||
g2.AddButton("change Title", func (*Node) {
|
||||
g2.NewButton("change Title", func () {
|
||||
// mainWindow.SetText("hello world")
|
||||
})
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
g3 = newN.NewGroup("Node Debug")
|
||||
|
||||
g3.AddButton("Node.Dump()", func (n *Node) {
|
||||
n.Dump()
|
||||
g3.NewButton("Node.Dump()", func () {
|
||||
bugWin.Dump()
|
||||
})
|
||||
g3.AddButton("Node.ListChildren(false)", func (n *Node) {
|
||||
n.ListChildren(false)
|
||||
g3.NewButton("Node.ListChildren(false)", func () {
|
||||
bugWin.ListChildren(false)
|
||||
})
|
||||
g3.AddButton("Node.ListChildren(true)", func (n *Node) {
|
||||
n.ListChildren(true)
|
||||
g3.NewButton("Node.ListChildren(true)", func () {
|
||||
bugWin.ListChildren(true)
|
||||
})
|
||||
g3.AddButton("AddDebugTab()", func (n *Node) {
|
||||
g3.NewButton("AddDebugTab()", func () {
|
||||
if (bugWin != nil) {
|
||||
bugWin.DebugTab("added this DebugTab")
|
||||
}
|
||||
|
|
|
@ -31,46 +31,46 @@ func GolangDebugWindow() {
|
|||
|
||||
|
||||
/////////////////////////////// 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")
|
||||
buf := make([]byte, 1<<16)
|
||||
runtime.Stack(buf, true)
|
||||
log.Printf("%s", buf)
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("dumpModuleInfo()", func (*Node) {
|
||||
g.NewButton("dumpModuleInfo()", func () {
|
||||
log.Println("\tSTART")
|
||||
dumpModuleInfo()
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("debug.PrintStack()", func (*Node) {
|
||||
g.NewButton("debug.PrintStack()", func () {
|
||||
log.Println("\tSTART")
|
||||
debug.PrintStack()
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("pprof.Lookup(goroutine)", func (*Node) {
|
||||
g.NewButton("pprof.Lookup(goroutine)", func () {
|
||||
log.Println("\tSTART")
|
||||
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("pprof.Lookup(heap)", func (*Node) {
|
||||
g.NewButton("pprof.Lookup(heap)", func () {
|
||||
log.Println("\tSTART")
|
||||
pprof.Lookup("heap").WriteTo(os.Stdout, 1)
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("pprof.Lookup(block)", func (*Node) {
|
||||
g.NewButton("pprof.Lookup(block)", func () {
|
||||
log.Println("\tSTART")
|
||||
pprof.Lookup("block").WriteTo(os.Stdout, 1)
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("pprof.Lookup threadcreate", func (*Node) {
|
||||
g.NewButton("pprof.Lookup threadcreate", func () {
|
||||
log.Println("\tSTART")
|
||||
pprof.Lookup("threadcreate").WriteTo(os.Stdout, 1)
|
||||
log.Println("\tEND")
|
||||
})
|
||||
g.AddButton("runtime.ReadMemStats", func (*Node) {
|
||||
g.NewButton("runtime.ReadMemStats", func () {
|
||||
var s runtime.MemStats
|
||||
runtime.ReadMemStats(&s)
|
||||
log.Printf("alloc: %v bytes\n", s.Alloc)
|
||||
|
|
14
window.go
14
window.go
|
@ -19,21 +19,21 @@ func NewWindow() *Node {
|
|||
title := Config.Title
|
||||
w := Config.Width
|
||||
h := Config.Height
|
||||
f := Config.Exit
|
||||
// f := Config.Exit
|
||||
|
||||
// Windows are created off of the master node of the Binary Tree
|
||||
n = Config.master.New(title)
|
||||
n.custom = f
|
||||
// n.custom = f
|
||||
|
||||
t = toolkit.NewWindow(title, w, h)
|
||||
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) {
|
||||
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)
|
||||
log.Println("Got to wit/gui Window Close END custom()")
|
||||
n.custom()
|
||||
log.Println("Got to wit/gui Window Close END user defined close()")
|
||||
}
|
||||
n.toolkit = t
|
||||
|
||||
|
|
Loading…
Reference in New Issue