the golang way. everything in it's own repo
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
commit
b25f15ea78
|
@ -0,0 +1,13 @@
|
|||
all: plugin
|
||||
|
||||
plugin:
|
||||
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../andlabs.so
|
||||
|
||||
goget:
|
||||
GO111MODULE="off" go get -v -t -u
|
||||
|
||||
redomod:
|
||||
rm -f go.*
|
||||
GO111MODULE= go mod init
|
||||
GO111MODULE= go mod tidy
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
// this will check to make sure that the node
|
||||
// is valid for making a New TK andlabs widget
|
||||
// Basically, it makes sure there is a parent ID
|
||||
// and that there already a widget created
|
||||
func notNew(n *tree.Node) bool {
|
||||
if n == nil {
|
||||
log.Warn("ready() n = nil")
|
||||
return true
|
||||
}
|
||||
if n.TK != nil {
|
||||
log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
|
||||
return true
|
||||
}
|
||||
if n.Parent == nil {
|
||||
log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
|
||||
return true
|
||||
}
|
||||
if n.Parent.TK == nil {
|
||||
log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
|
||||
log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
|
||||
return true
|
||||
}
|
||||
// this means you can add a new widgets
|
||||
return false
|
||||
}
|
||||
|
||||
func ready(n *tree.Node) bool {
|
||||
if n == nil {
|
||||
log.Warn("ready() n = nil")
|
||||
return false
|
||||
}
|
||||
if n.TK == nil {
|
||||
log.Warn("ready() n.TK = nil", n.WidgetId, n.GetProgName())
|
||||
return false
|
||||
}
|
||||
if n.Parent == nil {
|
||||
log.Warn("ready() n.Parent = nil", n.WidgetId, n.GetProgName())
|
||||
return false
|
||||
}
|
||||
if n.Parent.TK == nil {
|
||||
log.Warn("ready() n.Parent.TK = nil", n.WidgetId, n.GetProgName())
|
||||
log.Warn("ready() n.Parent.TK = nil", n.Parent.WidgetId, n.Parent.GetProgName())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
func (n *node) ready() bool {
|
||||
if n == nil {
|
||||
return false
|
||||
}
|
||||
if n.tk == nil {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func show(n *tree.Node, b bool) {
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
// tk = getTK(n)
|
||||
|
||||
if tk == nil {
|
||||
return
|
||||
}
|
||||
if tk.uiControl == nil {
|
||||
return
|
||||
}
|
||||
if b {
|
||||
tk.uiControl.Show()
|
||||
} else {
|
||||
tk.uiControl.Hide()
|
||||
}
|
||||
}
|
||||
|
||||
func enable(n *tree.Node, b bool) {
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
if n == nil {
|
||||
panic("WHAT? enable was passed nil. How does this even happen?")
|
||||
}
|
||||
if tk == nil {
|
||||
return
|
||||
}
|
||||
if tk.uiControl == nil {
|
||||
return
|
||||
}
|
||||
if b {
|
||||
tk.uiControl.Enable()
|
||||
} else {
|
||||
tk.uiControl.Disable()
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) pad(b bool) {
|
||||
log.Warn("pad() on WidgetId =", n.WidgetId)
|
||||
|
||||
t := n.tk
|
||||
if t == nil {
|
||||
log.Log(ERROR, "pad() toolkit struct == nil. for", n.WidgetId)
|
||||
return
|
||||
}
|
||||
|
||||
switch n.WidgetType {
|
||||
case widget.Window:
|
||||
t.uiWindow.SetMargined(b)
|
||||
t.uiWindow.SetBorderless(b)
|
||||
case widget.Tab:
|
||||
tabSetMargined(t.uiTab, b)
|
||||
case widget.Group:
|
||||
t.uiGroup.SetMargined(b)
|
||||
case widget.Grid:
|
||||
t.uiGrid.SetPadded(b)
|
||||
case widget.Box:
|
||||
t.uiBox.SetPadded(b)
|
||||
default:
|
||||
log.Log(ERROR, "TODO: implement pad() for", n.WidgetType, n.progname)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) move(newParent *node) {
|
||||
p := n.parent
|
||||
|
||||
switch p.WidgetType {
|
||||
case widget.Group:
|
||||
case widget.Tab:
|
||||
// tabSetMargined(tParent.uiTab, true)
|
||||
case widget.Window:
|
||||
// t.uiWindow.SetBorderless(false)
|
||||
case widget.Grid:
|
||||
// t.uiGrid.SetPadded(true)
|
||||
case widget.Box:
|
||||
log.Log(INFO, "TODO: move() where =", p.ParentId)
|
||||
log.Log(INFO, "TODO: move() for widget =", n.WidgetId)
|
||||
|
||||
stretchy = true
|
||||
if p.tk.uiBox != nil {
|
||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
||||
}
|
||||
default:
|
||||
log.Log(ERROR, "TODO: need to implement move() for type =", n.WidgetType)
|
||||
log.Log(ERROR, "TODO: need to implement move() for where =", p.ParentId)
|
||||
log.Log(ERROR, "TODO: need to implement move() for widget =", n.WidgetId)
|
||||
}
|
||||
}
|
||||
|
||||
func (n *node) Delete() {
|
||||
p := n.parent
|
||||
log.Log(NOW, "uiDelete()", n.WidgetId, "to", p.WidgetId)
|
||||
|
||||
if n.WidgetType == widget.Window {
|
||||
log.Warn("DESTROY uiWindow here")
|
||||
log.Warn("NEED TO REMOVE n from parent.Children")
|
||||
n.tk.uiWindow.Destroy()
|
||||
n.tk.uiWindow = nil
|
||||
for i, child := range p.children {
|
||||
log.Warn("parent has child:", i, child.WidgetId, child.progname)
|
||||
if n == child {
|
||||
log.Warn("Found child ==", i, child.WidgetId, child.progname)
|
||||
log.Warn("Found n ==", i, n.WidgetId, n.progname)
|
||||
p.children = append(p.children[:i], p.children[i+1:]...)
|
||||
}
|
||||
// t.uiWindow.SetBorderless(false)
|
||||
}
|
||||
for i, child := range p.children {
|
||||
log.Warn("parent now has child:", i, child.WidgetId, child.progname)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch p.WidgetType {
|
||||
case widget.Group:
|
||||
// tParent.uiGroup.SetMargined(true)
|
||||
case widget.Tab:
|
||||
// tabSetMargined(tParent.uiTab, true)
|
||||
case widget.Window:
|
||||
case widget.Grid:
|
||||
// t.uiGrid.SetPadded(true)
|
||||
case widget.Box:
|
||||
log.Log(NOW, "tWidget.boxC =", p.progname)
|
||||
log.Log(NOW, "is there a tParent parent? =", p.parent)
|
||||
if p.tk.boxC < 1 {
|
||||
log.Log(NOW, "Can not delete from Box. already empty. tWidget.boxC =", p.tk.boxC)
|
||||
return
|
||||
}
|
||||
p.tk.uiBox.Delete(0)
|
||||
p.tk.boxC -= 1
|
||||
|
||||
// this didn't work:
|
||||
// tWidget.uiControl.Disable()
|
||||
// sleep(.8)
|
||||
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
|
||||
default:
|
||||
log.Log(ERROR, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
|
||||
log.Log(ERROR, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
|
||||
}
|
||||
}
|
||||
|
||||
func rawAction(a *widget.Action) {
|
||||
log.Log(INFO, "rawAction() START a.ActionType =", a.ActionType, "a.Value", a.Value)
|
||||
|
||||
if a.ActionType == widget.ToolkitInit {
|
||||
Init()
|
||||
return
|
||||
}
|
||||
switch a.WidgetType {
|
||||
case widget.Root:
|
||||
me.treeRoot = me.myTree.AddNode(a)
|
||||
log.Log(INFO, "doAction() found treeRoot")
|
||||
return
|
||||
}
|
||||
|
||||
log.Warn("andlabs rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId, a.ActionType)
|
||||
switch a.WidgetType {
|
||||
case widget.Flag:
|
||||
log.Log(ERROR, "rawAction() RE-IMPLEMENT LOG FLAGS")
|
||||
return
|
||||
}
|
||||
|
||||
if me.treeRoot == nil {
|
||||
panic("me.treeRoot == nil")
|
||||
}
|
||||
|
||||
n := me.treeRoot.FindWidgetId(a.WidgetId)
|
||||
|
||||
if a.ActionType == widget.Add {
|
||||
me.treeRoot.ListWidgets()
|
||||
// ui.QueueMain(func() {
|
||||
add(a)
|
||||
// })
|
||||
// TODO: remove this artificial delay
|
||||
// sleep(.001)
|
||||
return
|
||||
}
|
||||
|
||||
if a.ActionType == widget.Dump {
|
||||
log.Log(NOW, "rawAction() Dump =", a.ActionType, a.WidgetType, n.State.ProgName)
|
||||
// me.rootNode.listChildren(true)
|
||||
return
|
||||
}
|
||||
|
||||
if n == nil {
|
||||
log.Error(errors.New("andlabs rawAction() ERROR findWidgetId found nil"), a.ActionType, a.WidgetType)
|
||||
log.Log(NOW, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
|
||||
log.Log(NOW, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
|
||||
log.Log(NOW, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
|
||||
me.treeRoot.ListWidgets()
|
||||
return
|
||||
panic("findWidgetId found nil for id = " + string(a.WidgetId))
|
||||
}
|
||||
|
||||
switch a.ActionType {
|
||||
case widget.Show:
|
||||
show(n, true)
|
||||
// n.show(true)
|
||||
case widget.Hide:
|
||||
show(n, false)
|
||||
//n.show(false)
|
||||
case widget.Enable:
|
||||
enable(n, true)
|
||||
// n.enable(true)
|
||||
case widget.Disable:
|
||||
log.Warn("andlabs got disable for", n.WidgetId, n.State.ProgName)
|
||||
enable(n, false)
|
||||
// n.enable(false)
|
||||
case widget.Get:
|
||||
// n.setText(a)
|
||||
setText(n, a)
|
||||
case widget.GetText:
|
||||
switch a.WidgetType {
|
||||
case widget.Textbox:
|
||||
a.Value = n.State.Value
|
||||
}
|
||||
case widget.Set:
|
||||
setText(n, a)
|
||||
// n.setText(a)
|
||||
case widget.SetText:
|
||||
setText(n, a)
|
||||
// n.setText(a)
|
||||
case widget.AddText:
|
||||
addText(n, a)
|
||||
// n.addText(a)
|
||||
/*
|
||||
case widget.Margin:
|
||||
n.pad(true)
|
||||
case widget.Unmargin:
|
||||
n.pad(false)
|
||||
case widget.Pad:
|
||||
n.pad(true)
|
||||
case widget.Unpad:
|
||||
n.pad(false)
|
||||
case widget.Delete:
|
||||
n.Delete()
|
||||
case widget.Move:
|
||||
log.Log(NOW, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
|
||||
*/
|
||||
default:
|
||||
log.Log(ERROR, "rawAction() Unknown =", a.ActionType, a.WidgetType)
|
||||
}
|
||||
log.Log(INFO, "rawAction() END =", a.ActionType, a.WidgetType)
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
func add(a *widget.Action) {
|
||||
log.Warn("andlabs add()", a.WidgetId, a.State.ProgName)
|
||||
if a.WidgetType == widget.Root {
|
||||
if me.treeRoot == nil {
|
||||
me.treeRoot = me.myTree.AddNode(a)
|
||||
}
|
||||
return
|
||||
}
|
||||
// n := addNode(a)
|
||||
n := me.myTree.AddNode(a)
|
||||
|
||||
p := n.Parent
|
||||
switch n.WidgetType {
|
||||
case widget.Window:
|
||||
log.Warn("SPEEDY Add window", n.WidgetId, n.GetProgName())
|
||||
newWindow(p, n)
|
||||
return
|
||||
case widget.Group:
|
||||
log.Warn("SPEEDY Add Group", n.WidgetId, n.GetProgName())
|
||||
newGroup(p, n)
|
||||
return
|
||||
case widget.Grid:
|
||||
newGrid(n)
|
||||
return
|
||||
case widget.Box:
|
||||
newBox(n)
|
||||
return
|
||||
/*
|
||||
case widget.Tab:
|
||||
newTab(n)
|
||||
return
|
||||
*/
|
||||
case widget.Label:
|
||||
newLabel(p, n)
|
||||
return
|
||||
case widget.Button:
|
||||
newButton(p, n)
|
||||
return
|
||||
case widget.Checkbox:
|
||||
newCheckbox(p, n)
|
||||
return
|
||||
case widget.Spinner:
|
||||
newSpinner(p, n)
|
||||
return
|
||||
case widget.Slider:
|
||||
newSlider(p, n)
|
||||
return
|
||||
case widget.Dropdown:
|
||||
newDropdown(p, n)
|
||||
return
|
||||
case widget.Combobox:
|
||||
newCombobox(p, n)
|
||||
return
|
||||
case widget.Textbox:
|
||||
newTextbox(p, n)
|
||||
return
|
||||
/*
|
||||
case widget.Image:
|
||||
newImage(p, n)
|
||||
return
|
||||
*/
|
||||
default:
|
||||
log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.State.ProgName)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func compareStrings(n *tree.Node, ss []string) {
|
||||
}
|
||||
|
||||
// func (n *node) addText(a *widget.Action) {
|
||||
func addText(n *tree.Node, a *widget.Action) {
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Warn("andlabs addText() START with a.Value =", a.Value)
|
||||
if tk == nil {
|
||||
log.Log(ERROR, "addText error. tk == nil", n.State.ProgName, n.WidgetId)
|
||||
return
|
||||
}
|
||||
log.Warn("andlabs addText() Attempt on", n.WidgetType, "with", a.Value)
|
||||
|
||||
switch n.WidgetType {
|
||||
case widget.Dropdown:
|
||||
for i, s := range a.State.Strings {
|
||||
log.Warn("andlabs a.State.Strings =", i, s)
|
||||
_, ok := n.Strings[s]
|
||||
// If the key exists
|
||||
if ok {
|
||||
log.Warn("andlabs a.State.Strings is here", i, s)
|
||||
} else {
|
||||
log.Warn("andlabs is not here", i, s)
|
||||
addDropdownName(n, s)
|
||||
// TODO: make numbers
|
||||
n.Strings[s] = 21
|
||||
}
|
||||
}
|
||||
case widget.Combobox:
|
||||
addComboboxName(n, widget.GetString(a.Value))
|
||||
default:
|
||||
log.Log(ERROR, "plugin Send() Don't know how to addText on", n.WidgetType, "yet", a.ActionType)
|
||||
}
|
||||
log.Log(CHANGE, "addText() END with a.Value =", a.Value)
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
// make new Box here
|
||||
func newBox(n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
var box *ui.Box
|
||||
|
||||
if n.State.Direction == widget.Horizontal {
|
||||
box = ui.NewHorizontalBox()
|
||||
} else {
|
||||
box = ui.NewVerticalBox()
|
||||
}
|
||||
box.SetPadded(true)
|
||||
|
||||
newt.uiBox = box
|
||||
newt.uiControl = box
|
||||
newt.boxC = 0
|
||||
n.TK = newt
|
||||
place(n.Parent, n)
|
||||
}
|
||||
|
||||
/*
|
||||
rawBox -- hack to arbitrarily add a box in andlabs to work
|
||||
around the problem that a "group" can not have one entry in it
|
||||
TODO: fix this so that a box is "added on demand" that is,
|
||||
if "go.wit.com/gui/gui" sends you a 2nd thing to add to a group,
|
||||
automatically add a box then. The problem with this, is the macos, windows and linux gtk
|
||||
will panic on a move when an chind object is disasociated from the group
|
||||
I haven't had time to try to debug this, so, instead, it's just probably better to always
|
||||
add a box here. There doesn't seem to be any real issue with forcing a box to be inserted
|
||||
into the toolkits that is "outside" the binary tree of widgets. This only means, that on
|
||||
a destroy of the tree, this box must be checked
|
||||
|
||||
even that is a probably not senario however since clicking on the close box in the toolkit
|
||||
has the operating system destroy everything in the window. it may or may not be possible
|
||||
to control that behavior. at this time, it's "undetermined" and the best course of action
|
||||
is to detect the window is destroyed and then remove all the toolkit information
|
||||
from all the nodes in the binary tree
|
||||
|
||||
TODO: handle user killing/closing a window using the OS
|
||||
*/
|
||||
// func (n *node) rawBox() *ui.Box {
|
||||
func rawBox(n *tree.Node) *ui.Box {
|
||||
var box *ui.Box
|
||||
|
||||
if n.State.Direction == widget.Horizontal {
|
||||
box = ui.NewHorizontalBox()
|
||||
} else {
|
||||
box = ui.NewVerticalBox()
|
||||
}
|
||||
box.SetPadded(true)
|
||||
|
||||
return box
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
// func (p *node) newButton(n *node) {
|
||||
func newButton(p *tree.Node, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
var ptk *guiWidget
|
||||
ptk = p.TK.(*guiWidget)
|
||||
newt := new(guiWidget)
|
||||
|
||||
b := ui.NewButton(n.GetLabel())
|
||||
newt.uiButton = b
|
||||
newt.uiControl = b
|
||||
newt.parent = ptk
|
||||
|
||||
b.OnClicked(func(*ui.Button) {
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newCheckbox(p *tree.Node, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
newt.uiCheckbox = ui.NewCheckbox(n.GetLabel())
|
||||
newt.uiControl = newt.uiCheckbox
|
||||
|
||||
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
|
||||
n.SetValue(newt.checked())
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
||||
|
||||
func (t *guiWidget) checked() bool {
|
||||
return t.uiCheckbox.Checked()
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func newCombobox(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
cb := ui.NewEditableCombobox()
|
||||
newt.uiEditableCombobox = cb
|
||||
newt.uiControl = cb
|
||||
|
||||
// initialize the index
|
||||
newt.c = 0
|
||||
newt.val = make(map[int]string)
|
||||
|
||||
cb.OnChanged(func(spin *ui.EditableCombobox) {
|
||||
n.SetValue(spin.Text())
|
||||
log.Warn("combobox changed =" + spin.Text() + ".")
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
|
||||
log.Warn("add combobox entries on create:", n.State.Strings)
|
||||
log.Warn("add combobox entries on create:", n.State.Strings)
|
||||
log.Warn("add combobox entries on create:", n.State.Strings)
|
||||
// add the initial combobox entries
|
||||
for i, s := range n.State.Strings {
|
||||
log.Warn("add combobox entries on create", n.GetProgName(), i, s)
|
||||
addComboboxName(n, s)
|
||||
}
|
||||
cur := n.String()
|
||||
log.Warn("add combobox: TODO: set default value on create", n.GetProgName(), cur)
|
||||
setComboboxName(n, cur)
|
||||
}
|
||||
|
||||
func addComboboxName(n *tree.Node, s string) {
|
||||
if !ready(n) {
|
||||
return
|
||||
}
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Log(INFO, "addComboboxName()", n.WidgetId, "add:", s)
|
||||
|
||||
tk.uiEditableCombobox.Append(s)
|
||||
if tk.val == nil {
|
||||
log.Log(INFO, "make map didn't work")
|
||||
return
|
||||
}
|
||||
tk.val[tk.c] = s
|
||||
|
||||
// If this is the first menu added, set the dropdown to it
|
||||
if tk.c == 0 {
|
||||
log.Log(INFO, "THIS IS THE FIRST combobox", s)
|
||||
tk.uiEditableCombobox.SetText(s)
|
||||
}
|
||||
tk.c = tk.c + 1
|
||||
}
|
||||
|
||||
func setComboboxName(n *tree.Node, s string) bool {
|
||||
if !ready(n) {
|
||||
return false
|
||||
}
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Log(INFO, "SetComboboxName()", n.WidgetId, ",", s)
|
||||
tk.uiEditableCombobox.SetText(s)
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
)
|
||||
|
||||
type node struct {
|
||||
parent *node
|
||||
children []*node
|
||||
|
||||
WidgetId int // widget ID
|
||||
WidgetType widget.WidgetType
|
||||
ParentId int // parent ID
|
||||
|
||||
state widget.State
|
||||
|
||||
// a reference name for programming and debuggign. Must be unique
|
||||
progname string
|
||||
|
||||
// the text used for button labesl, window titles, checkbox names, etc
|
||||
label string
|
||||
|
||||
// horizontal means layout widgets like books on a bookshelf
|
||||
// vertical means layout widgets like books in a stack
|
||||
// direction widget.Orientation
|
||||
direction widget.Orientation
|
||||
|
||||
// This is how the values are passed back and forth
|
||||
// values from things like checkboxes & dropdown's
|
||||
value any
|
||||
|
||||
strings []string
|
||||
|
||||
// This is used for things like a slider(0,100)
|
||||
X int
|
||||
Y int
|
||||
|
||||
// This is for the grid size & widget position
|
||||
W int
|
||||
H int
|
||||
AtW int
|
||||
AtH int
|
||||
|
||||
vals []string // dropdown menu items
|
||||
|
||||
// horizontal bool `default:false`
|
||||
|
||||
hasTabs bool // does the window have tabs?
|
||||
currentTab bool // the visible tab
|
||||
|
||||
// the internal plugin toolkit structure
|
||||
// in the gtk plugin, it has gtk things like margin & border settings
|
||||
// in the text console one, it has text console things like colors for menus & buttons
|
||||
tk *guiWidget
|
||||
}
|
||||
|
||||
/*
|
||||
func (n *node) doUserEvent() {
|
||||
log.Log(ERROR, "doUserEvent() ERROR")
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,121 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/log"
|
||||
// "go.wit.com/gui/widget"
|
||||
)
|
||||
|
||||
var defaultBehavior bool = 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 = false
|
||||
var debugChange bool = false
|
||||
var debugPlugin bool = false
|
||||
var debugAction bool = false
|
||||
var debugFlags bool = false
|
||||
var debugGrid bool = false
|
||||
var debugNow bool = true
|
||||
var debugError bool = true
|
||||
|
||||
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
||||
func setDefaultBehavior(s bool) {
|
||||
defaultBehavior = s
|
||||
if defaultBehavior {
|
||||
log.Log(NOW, "Setting this toolkit to use the default behavior.")
|
||||
log.Log(NOW, "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
|
||||
} else {
|
||||
log.Log(NOW, "This toolkit is set to ignore the default behavior.")
|
||||
}
|
||||
}
|
||||
|
||||
func (t *guiWidget) Dump(b bool) {
|
||||
if !b {
|
||||
return
|
||||
}
|
||||
log.Log(NOW, "Name = ", t.Width, t.Height)
|
||||
if t.uiBox != nil {
|
||||
log.Log(NOW, "uiBox =", t.uiBox)
|
||||
}
|
||||
if t.uiButton != nil {
|
||||
log.Log(NOW, "uiButton =", t.uiButton)
|
||||
}
|
||||
if t.uiCombobox != nil {
|
||||
log.Log(NOW, "uiCombobox =", t.uiCombobox)
|
||||
}
|
||||
if t.uiWindow != nil {
|
||||
log.Log(NOW, "uiWindow =", t.uiWindow)
|
||||
}
|
||||
if t.uiTab != nil {
|
||||
log.Log(NOW, "uiTab =", t.uiTab)
|
||||
}
|
||||
if t.uiGroup != nil {
|
||||
log.Log(NOW, "uiGroup =", t.uiGroup)
|
||||
}
|
||||
if t.uiEntry != nil {
|
||||
log.Log(NOW, "uiEntry =", t.uiEntry)
|
||||
}
|
||||
if t.uiMultilineEntry != nil {
|
||||
log.Log(NOW, "uiMultilineEntry =", t.uiMultilineEntry)
|
||||
}
|
||||
if t.uiSlider != nil {
|
||||
log.Log(NOW, "uiSlider =", t.uiSlider)
|
||||
}
|
||||
if t.uiCheckbox != nil {
|
||||
log.Log(NOW, "uiCheckbox =", t.uiCheckbox)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
func GetDebugToolkit () bool {
|
||||
return debugToolkit
|
||||
}
|
||||
*/
|
||||
|
||||
func (n *node) dumpWidget(b bool) {
|
||||
var info, d string
|
||||
|
||||
if n == nil {
|
||||
log.Log(ERROR, "dumpWidget() node == nil")
|
||||
return
|
||||
}
|
||||
info = n.WidgetType.String()
|
||||
|
||||
d = string(n.WidgetId) + " " + info + " " + n.progname
|
||||
|
||||
var tabs string
|
||||
for i := 0; i < listChildrenDepth; i++ {
|
||||
tabs = tabs + defaultPadding
|
||||
}
|
||||
log.Log(NOW, tabs+d)
|
||||
}
|
||||
|
||||
var defaultPadding string = " "
|
||||
var listChildrenDepth int = 0
|
||||
|
||||
func (n *node) listChildren(dump bool) {
|
||||
if n == nil {
|
||||
return
|
||||
}
|
||||
|
||||
n.dumpWidget(dump)
|
||||
if len(n.children) == 0 {
|
||||
return
|
||||
}
|
||||
for _, child := range n.children {
|
||||
listChildrenDepth += 1
|
||||
child.listChildren(dump)
|
||||
listChildrenDepth -= 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
// if you include more than just this import
|
||||
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
// delete the child widget from the parent
|
||||
// p = parent, c = child
|
||||
func (n *node) destroy() {
|
||||
pId := n.parent.WidgetId
|
||||
cId := n.WidgetId
|
||||
log.Log(NOW, "delete()", pId, cId)
|
||||
|
||||
pt := n.parent.tk
|
||||
ct := n.tk
|
||||
if ct == nil {
|
||||
log.Log(NOW, "delete FAILED (ct = mapToolkit[c] == nil) for c", pId, cId)
|
||||
// this pukes out a whole universe of shit
|
||||
// listMap()
|
||||
return
|
||||
}
|
||||
|
||||
switch n.WidgetType {
|
||||
case widget.Button:
|
||||
log.Log(NOW, "Should delete Button here:", n.progname)
|
||||
log.Log(NOW, "Parent:")
|
||||
pt.Dump(true)
|
||||
log.Log(NOW, "Child:")
|
||||
ct.Dump(true)
|
||||
if pt.uiBox == nil {
|
||||
log.Log(NOW, "Don't know how to destroy this")
|
||||
} else {
|
||||
log.Log(NOW, "Fuck it, destroy the whole box", n.parent.progname)
|
||||
// pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent.
|
||||
pt.uiBox.SetPadded(false)
|
||||
pt.uiBox.Delete(4)
|
||||
ct.uiButton.Disable()
|
||||
// ct.uiButton.Hide()
|
||||
ct.uiButton.Destroy()
|
||||
}
|
||||
|
||||
case widget.Window:
|
||||
log.Log(NOW, "Should delete Window here:", n.progname)
|
||||
default:
|
||||
log.Log(NOW, "Fuckit, let's destroy a button")
|
||||
if ct.uiButton != nil {
|
||||
pt.uiBox.Delete(4)
|
||||
ct.uiButton.Destroy()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
/*
|
||||
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()
|
||||
hbox.SetPadded(true)
|
||||
w.SetChild(hbox)
|
||||
return hbox
|
||||
}
|
||||
|
||||
func (t *guiWidget) DemoNumbersPage() {
|
||||
var w *ui.Window
|
||||
|
||||
log.Log(NOW, "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")
|
||||
}
|
||||
|
||||
func makeNumbersPage() *ui.Box {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
|
||||
group := ui.NewGroup("Numbers")
|
||||
group.SetMargined(true)
|
||||
hbox.Append(group, true)
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
vbox.SetPadded(true)
|
||||
group.SetChild(vbox)
|
||||
|
||||
spinbox := ui.NewSpinbox(0, 100)
|
||||
slider := ui.NewSlider(0, 100)
|
||||
pbar := ui.NewProgressBar()
|
||||
spinbox.OnChanged(func(*ui.Spinbox) {
|
||||
slider.SetValue(spinbox.Value())
|
||||
pbar.SetValue(spinbox.Value())
|
||||
})
|
||||
slider.OnChanged(func(*ui.Slider) {
|
||||
spinbox.SetValue(slider.Value())
|
||||
pbar.SetValue(slider.Value())
|
||||
})
|
||||
vbox.Append(spinbox, false)
|
||||
vbox.Append(slider, false)
|
||||
vbox.Append(pbar, false)
|
||||
|
||||
ip := ui.NewProgressBar()
|
||||
ip.SetValue(-1)
|
||||
vbox.Append(ip, false)
|
||||
|
||||
group = ui.NewGroup("Lists")
|
||||
group.SetMargined(true)
|
||||
hbox.Append(group, true)
|
||||
|
||||
vbox = ui.NewVerticalBox()
|
||||
vbox.SetPadded(true)
|
||||
group.SetChild(vbox)
|
||||
|
||||
cbox := ui.NewCombobox()
|
||||
cbox.Append("Combobox Item 1")
|
||||
cbox.Append("Combobox Item 2")
|
||||
cbox.Append("Combobox Item 3")
|
||||
vbox.Append(cbox, false)
|
||||
|
||||
ecbox := ui.NewEditableCombobox()
|
||||
ecbox.Append("Editable Item 1")
|
||||
ecbox.Append("Editable Item 2")
|
||||
ecbox.Append("Editable Item 3")
|
||||
vbox.Append(ecbox, false)
|
||||
|
||||
rb := ui.NewRadioButtons()
|
||||
rb.Append("Radio Button 1")
|
||||
rb.Append("Radio Button 2")
|
||||
rb.Append("Radio Button 3")
|
||||
vbox.Append(rb, false)
|
||||
|
||||
return hbox
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func newDropdown(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
log.Log(INFO, "gui.Toolbox.newDropdown() START", n.GetProgName())
|
||||
|
||||
cb := ui.NewCombobox()
|
||||
newt.uiCombobox = cb
|
||||
newt.uiControl = cb
|
||||
|
||||
// initialize the index
|
||||
newt.c = 0
|
||||
newt.val = make(map[int]string)
|
||||
|
||||
cb.OnSelected(func(spin *ui.Combobox) {
|
||||
i := spin.Selected()
|
||||
if newt.val == nil {
|
||||
log.Log(ERROR, "make map didn't work")
|
||||
n.SetValue("map did not work. ui.Combobox error")
|
||||
} else {
|
||||
n.SetValue(newt.val[i])
|
||||
}
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
|
||||
log.Warn("add dropdown entries on create:", n.State.Strings)
|
||||
log.Warn("add dropdown entries on create:", n.State.Strings)
|
||||
log.Warn("add dropdown entries on create:", n.State.Strings)
|
||||
if n.State.Strings == nil {
|
||||
return
|
||||
}
|
||||
// add the initial dropdown entries
|
||||
for i, s := range n.State.Strings {
|
||||
log.Warn("add dropdown: add entries on create", n.GetProgName(), i, s)
|
||||
addDropdownName(n, s)
|
||||
}
|
||||
cur := n.String()
|
||||
log.Warn("add dropdown: set default value on create", n.GetProgName(), cur)
|
||||
setDropdownName(n, cur)
|
||||
}
|
||||
|
||||
func setDropdownInt(n *tree.Node, i int) {
|
||||
if !ready(n) {
|
||||
return
|
||||
}
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
tk.uiCombobox.SetSelected(i)
|
||||
}
|
||||
|
||||
func addDropdownName(n *tree.Node, s string) {
|
||||
if !ready(n) {
|
||||
return
|
||||
}
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Log(INFO, "addDropdownName()", n.WidgetId, "add:", s)
|
||||
|
||||
tk.uiCombobox.Append(s)
|
||||
if tk.val == nil {
|
||||
log.Log(INFO, "make map didn't work")
|
||||
return
|
||||
}
|
||||
tk.val[tk.c] = s
|
||||
|
||||
// If this is the first menu added, set the dropdown to it
|
||||
if tk.c == 0 {
|
||||
log.Log(INFO, "THIS IS THE FIRST Dropdown", s)
|
||||
tk.uiCombobox.SetSelected(0)
|
||||
}
|
||||
tk.c = tk.c + 1
|
||||
}
|
||||
|
||||
func setDropdownName(n *tree.Node, s string) bool {
|
||||
if !ready(n) {
|
||||
return false
|
||||
}
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Log(INFO, "SetDropdownName()", n.WidgetId, ",", s)
|
||||
|
||||
for i, tmp := range tk.val {
|
||||
if s == tmp {
|
||||
n.SetValue(s)
|
||||
setDropdownInt(n, i)
|
||||
log.Warn("SetDropdownInt() worked", tmp, i)
|
||||
return true
|
||||
}
|
||||
}
|
||||
log.Warn("SetDropdownName() failed", s)
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
module go.wit.com/gui/toolkits/andlabs
|
||||
|
||||
go 1.21.4
|
||||
|
||||
require (
|
||||
go.wit.com/dev/andlabs/ui v0.0.1
|
||||
go.wit.com/gui/widget v1.1.3
|
||||
go.wit.com/log v0.5.4
|
||||
)
|
||||
|
||||
require go.wit.com/dev/davecgh/spew v1.1.4 // indirect
|
|
@ -0,0 +1,12 @@
|
|||
go.wit.com/dev/andlabs/ui v0.0.1 h1:SowOybLBu/qUOqp905EZikz5/iPa3GpmnCAPzNOYajM=
|
||||
go.wit.com/dev/andlabs/ui v0.0.1/go.mod h1:mlKEEe05ZJURzjh1LtjzdGMHVbJm9a7BUaVpA9cHxsM=
|
||||
go.wit.com/dev/davecgh/spew v1.1.3 h1:hqnB5qsPgC2cLZaJXqQJspQ5n/Ugry9kyL3tLk0hVzQ=
|
||||
go.wit.com/dev/davecgh/spew v1.1.3/go.mod h1:sihvWmnQ/09FWplnEmozt90CCVqBtGuPXM811tgfhFA=
|
||||
go.wit.com/dev/davecgh/spew v1.1.4 h1:C9hj/rjlUpdK+E6aroyLjCbS5MFcyNUOuP1ICLWdNek=
|
||||
go.wit.com/dev/davecgh/spew v1.1.4/go.mod h1:sihvWmnQ/09FWplnEmozt90CCVqBtGuPXM811tgfhFA=
|
||||
go.wit.com/gui/widget v1.1.3 h1:GvLzGSOF9tfmoh6HNbFdN+NSlBo2qeS/Ba2TnQQ1A1U=
|
||||
go.wit.com/gui/widget v1.1.3/go.mod h1:A6/FaiFQtAHTjgo7c4FrokXe6bXX1Cowo35b2Lgi31E=
|
||||
go.wit.com/log v0.5.3 h1:/zHkniOPusPEuX1R401rMny9uwSO/nSU/QOMx6qoEnE=
|
||||
go.wit.com/log v0.5.3/go.mod h1:LzIzVxc2xJQxWQBtV9VbV605P4TOxmYDCl+BZF38yGE=
|
||||
go.wit.com/log v0.5.4 h1:vijLRPTUgChb8J5tx/7Uma/lGTUxeSXosFbheAmL914=
|
||||
go.wit.com/log v0.5.4/go.mod h1:BaJBfHFqcJSJLXGQ9RHi3XVhPgsStxSMZRlaRxW4kAo=
|
|
@ -0,0 +1,29 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
// Grid numbering by (X,Y)
|
||||
// -----------------------------
|
||||
// -- (1,1) -- (2,1) -- (3,1) --
|
||||
// -- (1,2) -- (2,1) -- (3,1) --
|
||||
// -----------------------------
|
||||
func newGrid(n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
var newt *guiWidget
|
||||
newt = new(guiWidget)
|
||||
|
||||
c := ui.NewGrid()
|
||||
newt.uiGrid = c
|
||||
newt.uiControl = c
|
||||
c.SetPadded(true)
|
||||
|
||||
n.TK = newt
|
||||
place(n.Parent, n)
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
// "go.wit.com/gui/widget"
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newGroup(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
g := ui.NewGroup(n.GetLabel())
|
||||
g.SetMargined(true)
|
||||
newt.uiGroup = g
|
||||
newt.uiControl = g
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
var rawImage = []byte{
|
||||
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
|
||||
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
|
||||
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
|
||||
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
|
||||
0x00, 0xca, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0xa5, 0x93, 0xb1, 0x0d,
|
||||
0xc2, 0x40, 0x0c, 0x45, 0x1d, 0xc4, 0x14, 0x0c, 0x12, 0x41, 0x0f, 0x62,
|
||||
0x12, 0x46, 0x80, 0x8a, 0x2e, 0x15, 0x30, 0x02, 0x93, 0x20, 0x68, 0x11,
|
||||
0x51, 0x06, 0x61, 0x0d, 0x88, 0x2d, 0x7f, 0xdb, 0x07, 0x87, 0x08, 0xdc,
|
||||
0x49, 0x91, 0x7d, 0xf6, 0xf7, 0xf3, 0x4f, 0xa4, 0x54, 0xbb, 0xeb, 0xf6,
|
||||
0x41, 0x05, 0x67, 0xcc, 0xb3, 0x9b, 0xfa, 0xf6, 0x17, 0x62, 0xdf, 0xcd,
|
||||
0x48, 0x00, 0x32, 0xbd, 0xa8, 0x1d, 0x72, 0xee, 0x3c, 0x47, 0x16, 0xfb,
|
||||
0x5c, 0x53, 0x8d, 0x03, 0x30, 0x14, 0x84, 0xf7, 0xd5, 0x89, 0x26, 0xc7,
|
||||
0x25, 0x10, 0x36, 0xe4, 0x05, 0xa2, 0x51, 0xbc, 0xc4, 0x1c, 0xc3, 0x1c,
|
||||
0xed, 0x30, 0x1c, 0x8f, 0x16, 0x3f, 0x02, 0x78, 0x33, 0x20, 0x06, 0x60,
|
||||
0x97, 0x70, 0xaa, 0x45, 0x7f, 0x85, 0x60, 0x5d, 0xb6, 0xf4, 0xc2, 0xc4,
|
||||
0x3e, 0x0f, 0x44, 0xcd, 0x1b, 0x20, 0x90, 0x0f, 0xed, 0x85, 0xa8, 0x55,
|
||||
0x05, 0x42, 0x43, 0xb4, 0x9e, 0xce, 0x71, 0xb3, 0xe8, 0x0e, 0xb4, 0xc4,
|
||||
0xc3, 0x39, 0x21, 0xb7, 0x73, 0xbd, 0xe4, 0x1b, 0xe4, 0x04, 0xb6, 0xaa,
|
||||
0x4f, 0x18, 0x2c, 0xee, 0x42, 0x31, 0x01, 0x84, 0xfa, 0xe0, 0xd4, 0x00,
|
||||
0xdf, 0xb6, 0x83, 0xf8, 0xea, 0xc2, 0x00, 0x10, 0xfc, 0x1a, 0x05, 0x30,
|
||||
0x74, 0x3b, 0xe0, 0xd1, 0x45, 0xb1, 0x83, 0xaa, 0xf4, 0x77, 0x7e, 0x02,
|
||||
0x87, 0x1f, 0x42, 0x7f, 0x9e, 0x2b, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0x00,
|
||||
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
// make new Image using andlabs/ui
|
||||
func (p *node) newImage(n *node) {
|
||||
newt := new(guiWidget)
|
||||
var img *ui.Image
|
||||
|
||||
img = ui.NewImage(16, 16)
|
||||
|
||||
newt.uiImage = img
|
||||
// newt.uiControl = img
|
||||
|
||||
n.tk = newt
|
||||
// p.place(n)
|
||||
}
|
||||
|
||||
/*
|
||||
if (a.Name == "image") {
|
||||
log(true, "NewTextbox() trying to add a new image")
|
||||
i := ui.NewImage(16, 16)
|
||||
img, _, err := image.Decode(bytes.NewReader(rawImage))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
nr, ok := img.(*image.RGBA)
|
||||
if !ok {
|
||||
i2 := image.NewRGBA(img.Bounds())
|
||||
draw.Draw(i2, i2.Bounds(), img, img.Bounds().Min, draw.Src)
|
||||
nr = i2
|
||||
}
|
||||
i.Append(nr)
|
||||
t.uiBox.Append(i, true)
|
||||
|
||||
var img *ui.Image
|
||||
var icon []byte
|
||||
var imgA image.Image
|
||||
|
||||
icon, _ = res.ReadFile("resources/ping6.working.png")
|
||||
// imgA, _, err := image.Decode(bytes.NewReader(b))
|
||||
imgA, _, _ = image.Decode(icon)
|
||||
img.Append(imgA)
|
||||
img.Append(icon)
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,21 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newLabel(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
c := ui.NewLabel(n.GetLabel())
|
||||
newt.uiLabel = c
|
||||
newt.uiControl = c
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
this enables command line options from other packages like 'gui' and 'log'
|
||||
*/
|
||||
|
||||
import (
|
||||
log "go.wit.com/log"
|
||||
)
|
||||
|
||||
var NOW *log.LogFlag
|
||||
var INFO *log.LogFlag
|
||||
|
||||
var SPEW *log.LogFlag
|
||||
var WARN *log.LogFlag
|
||||
|
||||
var ERROR *log.LogFlag
|
||||
var CHANGE *log.LogFlag
|
||||
var TOOLKIT *log.LogFlag
|
||||
|
||||
func init() {
|
||||
full := "toolkit/nocui"
|
||||
short := "nocui"
|
||||
|
||||
NOW = log.NewFlag("NOW", true, full, short, "temp debugging stuff")
|
||||
INFO = log.NewFlag("INFO", false, full, short, "normal debugging stuff")
|
||||
|
||||
WARN = log.NewFlag("WARN", true, full, short, "bad things")
|
||||
SPEW = log.NewFlag("SPEW", false, full, short, "spew stuff")
|
||||
|
||||
ERROR = log.NewFlag("ERROR", false, full, short, "toolkit errors")
|
||||
CHANGE = log.NewFlag("ERROR", false, full, short, "show when the user does things")
|
||||
TOOLKIT = log.NewFlag("ERROR", false, full, short, "andlabs specific stuff")
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"runtime/debug"
|
||||
"sync"
|
||||
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
// the _ means we only need this for the init()
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
var uiMainUndef bool = true
|
||||
var uiMain sync.Once
|
||||
var muAction sync.Mutex
|
||||
|
||||
func queueMain(currentA widget.Action) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("YAHOOOO Recovered in queueMain() application:", r)
|
||||
log.Println("Recovered from panic:", r)
|
||||
log.Println("Stack trace:")
|
||||
debug.PrintStack()
|
||||
me.myTree.DoToolkitPanic()
|
||||
}
|
||||
}()
|
||||
ui.QueueMain(func() {
|
||||
rawAction(¤tA)
|
||||
})
|
||||
}
|
||||
|
||||
func guiMain() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("YAHOOOO Recovered in guiMain application:", r)
|
||||
log.Println("Recovered from panic:", r)
|
||||
log.Println("Stack trace:")
|
||||
debug.PrintStack()
|
||||
me.myTree.DoToolkitPanic()
|
||||
}
|
||||
}()
|
||||
ui.Main(func() {
|
||||
demoUI()
|
||||
})
|
||||
}
|
||||
|
||||
func Init() {
|
||||
log.Warn("Init() TODO: move init() to here")
|
||||
}
|
||||
|
||||
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
||||
func init() {
|
||||
log.Log(INFO, "Init() START")
|
||||
log.Log(INFO, "Init()")
|
||||
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
|
||||
// log.Log(INFO, "init() Setting defaultBehavior = true")
|
||||
setDefaultBehavior(true)
|
||||
|
||||
me.myTree = tree.New()
|
||||
me.myTree.PluginName = "andlabs"
|
||||
me.myTree.ActionFromChannel = queueMain
|
||||
|
||||
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
|
||||
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
|
||||
// actually, this probably breaks the macos build
|
||||
go guiMain()
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
// "os"
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
// This routine is very specific to this toolkit
|
||||
// It's annoying and has to be copied to each widget when there are changes
|
||||
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
|
||||
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
|
||||
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
|
||||
// -- jcarr 2023/03/09
|
||||
|
||||
// Grid numbering examples by (X,Y)
|
||||
// ---------
|
||||
// -- (1) --
|
||||
// -- (2) --
|
||||
// ---------
|
||||
//
|
||||
// -----------------------------
|
||||
// -- (1,1) -- (1,2) -- (1,3) --
|
||||
// -- (2,1) -- (2,2) -- (2,3) --
|
||||
// -----------------------------
|
||||
|
||||
// internally for andlabs/ui
|
||||
// (x&y flipped and start at zero)
|
||||
// -----------------------------
|
||||
// -- (0,0) -- (1,0) -- (1,0) --
|
||||
// -- (0,1) -- (1,1) -- (1,1) --
|
||||
// -----------------------------
|
||||
|
||||
func place(p *tree.Node, n *tree.Node) bool {
|
||||
log.Warn("SPEEDY newplace() 1 START", n.WidgetId, n.GetProgName(), n.GetLabel(), n.String())
|
||||
log.Warn("SPEEDY newplace() n.State.Strings =", n.State.Strings)
|
||||
log.Log(INFO, "place() 1 START", n.WidgetType, n.GetProgName(), n.GetLabel())
|
||||
if !ready(n) {
|
||||
log.Warn("place() 1 START not ready()")
|
||||
return false
|
||||
}
|
||||
log.Log(INFO, "place() 1 START ready()")
|
||||
var tk, ptk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
ptk = p.TK.(*guiWidget)
|
||||
log.Warn("SPEEDY newplace() 2 START", n.WidgetId, n.GetProgName(), n.GetLabel())
|
||||
|
||||
if ptk == nil {
|
||||
log.Log(ERROR, "ptk == nil", p.GetProgName(), p.ParentId, p.WidgetType, ptk)
|
||||
log.Log(ERROR, "n = ", n.GetProgName(), n.ParentId, n.WidgetType, tk)
|
||||
log.Warn("SPEEDY ptk == nil", n.WidgetId, n.GetProgName())
|
||||
log.Sleep(1)
|
||||
panic("ptk == nil")
|
||||
}
|
||||
|
||||
log.Log(INFO, "place() switch", p.WidgetType)
|
||||
log.Warn("SPEEDY newplace() before switch", n.WidgetId, n.GetProgName())
|
||||
switch p.WidgetType {
|
||||
case widget.Grid:
|
||||
tk.gridX = n.State.GridOffset.X - 1
|
||||
tk.gridY = n.State.GridOffset.Y - 1
|
||||
log.Warn("place() on Grid at gridX,gridY", tk.gridX, tk.gridY)
|
||||
ptk.uiGrid.Append(tk.uiControl,
|
||||
tk.gridX, tk.gridY, 1, 1,
|
||||
false, ui.AlignFill, false, ui.AlignFill)
|
||||
return true
|
||||
case widget.Group:
|
||||
if ptk.uiBox == nil {
|
||||
log.Log(WARN, "place() andlabs hack group to use add a box", n.GetProgName(), n.WidgetType)
|
||||
ptk.uiBox = rawBox(n)
|
||||
ptk.uiGroup.SetChild(ptk.uiBox)
|
||||
}
|
||||
ptk.uiBox.Append(tk.uiControl, stretchy)
|
||||
return true
|
||||
case widget.Tab:
|
||||
if ptk.uiTab == nil {
|
||||
log.Log(ERROR, "ptk.uiTab == nil for n.WidgetId =", n.WidgetId, "ptk =", ptk)
|
||||
panic("ptk.uiTab == nil")
|
||||
}
|
||||
if tk.uiControl == nil {
|
||||
log.Log(ERROR, "tk.uiControl == nil for n.WidgetId =", n.WidgetId, "tk =", tk)
|
||||
panic("tk.uiControl == nil")
|
||||
}
|
||||
log.Log(ERROR, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
|
||||
// log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.GetProgName(), n.Text, n.WidgetType)
|
||||
// log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.GetProgName(), p.Text, p.WidgetType)
|
||||
// panic("tk.uiControl == nil")
|
||||
ptk.uiTab.Append(widget.GetString(n.State.Value), tk.uiControl)
|
||||
ptk.boxC += 1
|
||||
return true
|
||||
case widget.Box:
|
||||
log.Warn("SPEEDY Add Something to Box", n.WidgetId, n.GetProgName())
|
||||
log.Log(INFO, "place() uiBox =", ptk.uiBox)
|
||||
log.Log(INFO, "place() uiControl =", tk.uiControl)
|
||||
ptk.uiBox.Append(tk.uiControl, stretchy)
|
||||
ptk.boxC += 1
|
||||
return true
|
||||
case widget.Window:
|
||||
log.Warn("SPEEDY Add Something to Window", n.WidgetId, n.GetProgName())
|
||||
ptk.uiWindow.SetChild(tk.uiControl)
|
||||
return true
|
||||
default:
|
||||
log.Log(ERROR, "place() how? Parent =", p.WidgetId, p.WidgetType)
|
||||
}
|
||||
log.Warn("SPEEDY newplace() return", n.WidgetId, n.GetProgName())
|
||||
return false
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
// func (n *node) setText(a *widget.Action) {
|
||||
func setText(n *tree.Node, a *widget.Action) {
|
||||
name := widget.GetString(a.Value)
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
|
||||
log.Log(CHANGE, "setText() START with text =", name)
|
||||
if tk == nil {
|
||||
log.Log(ERROR, "setText error. tk == nil", n.GetProgName(), n.WidgetId)
|
||||
return
|
||||
}
|
||||
log.Log(CHANGE, "setText() Attempt on", n.WidgetType, "with", name)
|
||||
|
||||
switch n.WidgetType {
|
||||
case widget.Window:
|
||||
log.Warn("setText() Attempt to set the title to", name)
|
||||
tk.uiWindow.SetTitle(name)
|
||||
case widget.Tab:
|
||||
case widget.Group:
|
||||
tk.uiGroup.SetTitle(name)
|
||||
case widget.Checkbox:
|
||||
tk.uiCheckbox.SetText(name)
|
||||
case widget.Textbox:
|
||||
if tk.uiEntry != nil {
|
||||
tk.uiEntry.SetText(name)
|
||||
}
|
||||
if tk.uiMultilineEntry != nil {
|
||||
tk.uiMultilineEntry.SetText(name)
|
||||
}
|
||||
case widget.Label:
|
||||
tk.uiLabel.SetText(name)
|
||||
case widget.Button:
|
||||
tk.uiButton.SetText(name)
|
||||
case widget.Slider:
|
||||
log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.GetProgName())
|
||||
case widget.Spinner:
|
||||
log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.GetProgName())
|
||||
case widget.Dropdown:
|
||||
var orig int
|
||||
var i int = -1
|
||||
var s string
|
||||
orig = tk.uiCombobox.Selected()
|
||||
log.Log(CHANGE, "try to set the Dropdown to", name, "from", orig)
|
||||
// try to find the string
|
||||
for i, s = range tk.val {
|
||||
log.Log(CHANGE, "i, s", i, s)
|
||||
if name == s {
|
||||
tk.uiCombobox.SetSelected(i)
|
||||
log.Log(CHANGE, "setText() Dropdown worked.", name)
|
||||
return
|
||||
}
|
||||
}
|
||||
log.Log(ERROR, "setText() Dropdown did not find:", name)
|
||||
// if i == -1, then there are not any things in the menu to select
|
||||
if i == -1 {
|
||||
return
|
||||
}
|
||||
// if the string was never set, then set the dropdown to the last thing added to the menu
|
||||
if orig == -1 {
|
||||
tk.uiCombobox.SetSelected(i)
|
||||
}
|
||||
case widget.Combobox:
|
||||
tk.uiEditableCombobox.SetText(name)
|
||||
default:
|
||||
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
|
||||
}
|
||||
log.Log(CHANGE, "setText() END with name =")
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newSlider(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
var x, y int
|
||||
x = n.State.Range.Low
|
||||
y = n.State.Range.High
|
||||
|
||||
s := ui.NewSlider(x, y)
|
||||
newt.uiSlider = s
|
||||
newt.uiControl = s
|
||||
|
||||
s.OnChanged(func(spin *ui.Slider) {
|
||||
n.SetValue(newt.uiSlider.Value())
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newSpinner(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
s := ui.NewSpinbox(n.State.Range.Low, n.State.Range.High)
|
||||
newt.uiSpinbox = s
|
||||
newt.uiControl = s
|
||||
|
||||
s.OnChanged(func(s *ui.Spinbox) {
|
||||
n.SetValue(newt.uiSpinbox.Value())
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
// var andlabs map[int]*andlabsT
|
||||
// var callback func(int) bool
|
||||
// var callback chan toolkit.Action
|
||||
|
||||
// It's probably a terrible idea to call this 'me'
|
||||
var me config
|
||||
|
||||
type config struct {
|
||||
rootNode *tree.Node // the base of the binary tree. it should have id == 0
|
||||
treeRoot *tree.Node // the base of the binary tree. it should have id == 0
|
||||
myTree *tree.TreeInfo
|
||||
}
|
||||
|
||||
// stores the raw toolkit internals
|
||||
type guiWidget struct {
|
||||
Width int
|
||||
Height int
|
||||
|
||||
// tw *toolkit.Widget
|
||||
parent *guiWidget
|
||||
children []*guiWidget
|
||||
|
||||
// used to track if a tab has a child widget yet
|
||||
child bool
|
||||
|
||||
uiControl ui.Control
|
||||
|
||||
uiBox *ui.Box
|
||||
uiButton *ui.Button
|
||||
uiCombobox *ui.Combobox
|
||||
uiCheckbox *ui.Checkbox
|
||||
uiEntry *ui.Entry
|
||||
uiGroup *ui.Group
|
||||
uiLabel *ui.Label
|
||||
uiSlider *ui.Slider
|
||||
uiSpinbox *ui.Spinbox
|
||||
uiTab *ui.Tab
|
||||
uiWindow *ui.Window
|
||||
uiMultilineEntry *ui.MultilineEntry
|
||||
uiEditableCombobox *ui.EditableCombobox
|
||||
uiImage *ui.Image
|
||||
|
||||
uiGrid *ui.Grid
|
||||
gridX int
|
||||
gridY int
|
||||
|
||||
// used as a counter to work around limitations of widgets like combobox
|
||||
// this is probably fucked up and in many ways wrong because of unsafe goroutine threading
|
||||
// but it's working for now due to the need for need for a correct interaction layer betten toolkits
|
||||
c int
|
||||
val map[int]string
|
||||
|
||||
// andlabs/ui only accesses widget id numbers
|
||||
boxC int // how many things on in a box or how many tabs
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
/*
|
||||
This adds a tab
|
||||
|
||||
andlabs/ui is goofy in the sense that you have to determine
|
||||
if the ui.Window already has a tab in it. If it does, then
|
||||
you need to add this tab and not run SetChild() on the window
|
||||
or instead it replaces the existing tab with the new one
|
||||
|
||||
I work around this by always sending a Toolkit that is a tab
|
||||
once there is one. If you send a Window here, it will replace
|
||||
any existing tabs rather than adding a new one
|
||||
*/
|
||||
func (p *node) newTab(n *node) {
|
||||
var newt *guiWidget
|
||||
|
||||
if p == nil {
|
||||
log.Log(ERROR, "newTab() p == nil. how the fuck does this happen?", n.WidgetId, n.ParentId)
|
||||
}
|
||||
if p.WidgetType != widget.Window {
|
||||
log.Log(ERROR, "newTab() uiWindow == nil. I can't add a toolbar without window", n.WidgetId, n.ParentId)
|
||||
return
|
||||
}
|
||||
t := p.tk
|
||||
|
||||
log.Log(TOOLKIT, "newTab() START", n.WidgetId, n.ParentId)
|
||||
|
||||
if t.uiTab == nil {
|
||||
// this means you have to make a new tab
|
||||
log.Log(TOOLKIT, "newTab() GOOD. This should be the first tab:", n.WidgetId, n.ParentId)
|
||||
newt = rawTab(t.uiWindow, widget.GetString(n.value))
|
||||
t.uiTab = newt.uiTab
|
||||
} else {
|
||||
// this means you have to append a tab
|
||||
log.Log(TOOLKIT, "newTab() GOOD. This should be an additional tab:", n.WidgetId, n.ParentId)
|
||||
if n.WidgetType == widget.Tab {
|
||||
// andlabs doesn't have multiple tab widgets so make a fake one?
|
||||
// this makes a guiWidget internal structure with the parent values
|
||||
newt = new(guiWidget)
|
||||
newt.uiWindow = t.uiWindow
|
||||
newt.uiTab = t.uiTab
|
||||
} else {
|
||||
newt = t.appendTab(widget.GetString(n.value))
|
||||
}
|
||||
}
|
||||
|
||||
n.tk = newt
|
||||
}
|
||||
|
||||
// This sets _all_ the tabs to Margin = true
|
||||
//
|
||||
// TODO: do proper tab tracking (will be complicated). low priority
|
||||
func tabSetMargined(tab *ui.Tab, b bool) {
|
||||
c := tab.NumPages()
|
||||
for i := 0; i < c; i++ {
|
||||
log.Log(TOOLKIT, "SetMargined", i, b)
|
||||
tab.SetMargined(i, b)
|
||||
}
|
||||
}
|
||||
|
||||
func rawTab(w *ui.Window, name string) *guiWidget {
|
||||
var newt guiWidget
|
||||
log.Log(TOOLKIT, "rawTab() START", name)
|
||||
|
||||
if w == nil {
|
||||
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
|
||||
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
|
||||
log.Log(ERROR, "UiWindow == nil. I can't add a tab without a window")
|
||||
// sleep(1)
|
||||
return nil
|
||||
}
|
||||
|
||||
tab := ui.NewTab()
|
||||
w.SetChild(tab)
|
||||
newt.uiTab = tab
|
||||
newt.uiControl = tab
|
||||
log.Log(TOOLKIT, "rawTab() END", name)
|
||||
return &newt
|
||||
}
|
||||
|
||||
func (t *guiWidget) appendTab(name string) *guiWidget {
|
||||
var newT guiWidget
|
||||
log.Log(TOOLKIT, "appendTab() ADD", name)
|
||||
|
||||
if t.uiTab == nil {
|
||||
log.Log(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.Log(TOOLKIT, "appendTab() START name =", name)
|
||||
|
||||
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)
|
||||
|
||||
newT.uiWindow = t.uiWindow
|
||||
newT.uiTab = t.uiTab
|
||||
newT.uiBox = hbox
|
||||
return &newT
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/toolkits/tree"
|
||||
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func newTextbox(p, n *tree.Node) {
|
||||
if notNew(n) {
|
||||
return
|
||||
}
|
||||
newt := new(guiWidget)
|
||||
|
||||
if n.State.Range.Low == 1 {
|
||||
e := ui.NewEntry()
|
||||
newt.uiEntry = e
|
||||
newt.uiControl = e
|
||||
|
||||
e.OnChanged(func(spin *ui.Entry) {
|
||||
n.SetValue(spin.Text())
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
} else {
|
||||
e := ui.NewNonWrappingMultilineEntry()
|
||||
newt.uiMultilineEntry = e
|
||||
newt.uiControl = e
|
||||
|
||||
e.OnChanged(func(spin *ui.MultilineEntry) {
|
||||
n.SetValue(spin.Text())
|
||||
me.myTree.DoUserEvent(n)
|
||||
})
|
||||
}
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
/*
|
||||
This code should be common to all gui plugins
|
||||
|
||||
There are some helper functions that are probably going to be
|
||||
the same everywhere. Mostly due to handling the binary tree structure
|
||||
and the channel communication
|
||||
|
||||
For now, it's just a symlink to the 'master' version in
|
||||
./toolkit/nocui/common.go
|
||||
*/
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
)
|
||||
|
||||
// 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.)
|
||||
//
|
||||
// this sets the channel to send user events back from the plugin
|
||||
func Callback(guiCallback chan widget.Action) {
|
||||
me.myTree.Callback(guiCallback)
|
||||
}
|
||||
|
||||
func PluginChannel() chan widget.Action {
|
||||
return me.myTree.PluginChannel()
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
)
|
||||
|
||||
// Example showing how to update the UI using the QueueMain function
|
||||
// especially if the update is coming from another goroutine
|
||||
//
|
||||
// see QueueMain in 'main.go' for detailed description
|
||||
|
||||
var count int
|
||||
|
||||
func demoUI() {
|
||||
mainWindow := ui.NewWindow("libui Updating UI", 640, 480, true)
|
||||
mainWindow.OnClosing(func(*ui.Window) bool {
|
||||
ui.Quit()
|
||||
return true
|
||||
})
|
||||
ui.OnShouldQuit(func() bool {
|
||||
mainWindow.Destroy()
|
||||
return true
|
||||
})
|
||||
|
||||
vbContainer := ui.NewVerticalBox()
|
||||
vbContainer.SetPadded(true)
|
||||
|
||||
inputGroup := ui.NewGroup("Input")
|
||||
inputGroup.SetMargined(true)
|
||||
|
||||
vbInput := ui.NewVerticalBox()
|
||||
vbInput.SetPadded(true)
|
||||
|
||||
inputForm := ui.NewForm()
|
||||
inputForm.SetPadded(true)
|
||||
|
||||
message := ui.NewEntry()
|
||||
message.SetText("Hello World")
|
||||
inputForm.Append("What message do you want to show?", message, false)
|
||||
|
||||
showMessageButton := ui.NewButton("Show message")
|
||||
clearMessageButton := ui.NewButton("Clear message")
|
||||
|
||||
vbInput.Append(inputForm, false)
|
||||
vbInput.Append(showMessageButton, false)
|
||||
vbInput.Append(clearMessageButton, false)
|
||||
|
||||
inputGroup.SetChild(vbInput)
|
||||
|
||||
messageGroup := ui.NewGroup("Message")
|
||||
messageGroup.SetMargined(true)
|
||||
|
||||
vbMessage := ui.NewVerticalBox()
|
||||
vbMessage.SetPadded(true)
|
||||
|
||||
messageLabel := ui.NewLabel("")
|
||||
|
||||
vbMessage.Append(messageLabel, false)
|
||||
|
||||
messageGroup.SetChild(vbMessage)
|
||||
|
||||
countGroup := ui.NewGroup("Counter")
|
||||
countGroup.SetMargined(true)
|
||||
|
||||
vbCounter := ui.NewVerticalBox()
|
||||
vbCounter.SetPadded(true)
|
||||
|
||||
countLabel := ui.NewLabel("blah")
|
||||
|
||||
vbCounter.Append(countLabel, false)
|
||||
countGroup.SetChild(vbCounter)
|
||||
|
||||
vbContainer.Append(inputGroup, false)
|
||||
vbContainer.Append(messageGroup, false)
|
||||
vbContainer.Append(countGroup, false)
|
||||
|
||||
mainWindow.SetChild(vbContainer)
|
||||
|
||||
showMessageButton.OnClicked(func(*ui.Button) {
|
||||
// Update the UI directly as it is called from the main thread
|
||||
messageLabel.SetText(message.Text())
|
||||
})
|
||||
|
||||
clearMessageButton.OnClicked(func(*ui.Button) {
|
||||
// Update the UI directly as it is called from the main thread
|
||||
messageLabel.SetText("")
|
||||
})
|
||||
|
||||
// this is messed up.
|
||||
// mainWindow.Show()
|
||||
}
|
||||
|
||||
/*
|
||||
func main() {
|
||||
ui.Main(setupUI)
|
||||
}
|
||||
*/
|
|
@ -0,0 +1,18 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func initWidget(n *tree.Node) *guiWidget {
|
||||
var w *guiWidget
|
||||
w = new(guiWidget)
|
||||
|
||||
if n.WidgetType == widget.Root {
|
||||
n.WidgetId = 0
|
||||
me.treeRoot = n
|
||||
return w
|
||||
}
|
||||
return w
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/dev/andlabs/ui"
|
||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||
|
||||
"go.wit.com/lib/widget"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
|
||||
ui.MsgBox(t.uiWindow, msg1, msg2)
|
||||
}
|
||||
|
||||
func (t *guiWidget) ErrorWindow(msg1 string, msg2 string) {
|
||||
ui.MsgBoxError(t.uiWindow, msg1, msg2)
|
||||
}
|
||||
|
||||
func newWindow(p, n *tree.Node) {
|
||||
var newt *guiWidget
|
||||
newt = new(guiWidget)
|
||||
|
||||
// menubar bool is if the OS defined border on the window should be used
|
||||
win := ui.NewWindow(n.GetProgName(), 640, 480, menubar)
|
||||
win.SetBorderless(canvas)
|
||||
win.SetMargined(margin)
|
||||
win.OnClosing(func(*ui.Window) bool {
|
||||
// show(n, false)
|
||||
me.myTree.DoWindowCloseEvent(n)
|
||||
return false
|
||||
})
|
||||
newt.uiWindow = win
|
||||
newt.uiControl = win
|
||||
|
||||
n.TK = newt
|
||||
place(p, n)
|
||||
win.Show()
|
||||
return
|
||||
}
|
||||
|
||||
func (n *node) SetWindowTitle(title string) {
|
||||
log.Log(CHANGE, "toolkit NewWindow", widget.GetString(n.value), "title", title)
|
||||
win := n.tk.uiWindow
|
||||
if win == nil {
|
||||
log.Log(ERROR, "Error: no window", n.WidgetId)
|
||||
} else {
|
||||
win.SetTitle(title)
|
||||
log.Log(CHANGE, "Setting the window title", title)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue