common tree package for toolkits
This update provides *lots* of toolkit updates. This will allow the next step of debugging the gocui toolkit to make it work again. There are new common routines for handling the plugin channel communication Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
ba95c13799
commit
841e6252c9
|
@ -1,47 +1,99 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"errors"
|
||||||
"go.wit.com/dev/andlabs/ui"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/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 {
|
func (n *node) ready() bool {
|
||||||
if n == nil { return false }
|
if n == nil { return false }
|
||||||
if n.tk == nil { return false }
|
if n.tk == nil { return false }
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) show(b bool) {
|
func show(n *tree.Node, b bool) {
|
||||||
if n.tk == nil {
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
|
// tk = getTK(n)
|
||||||
|
|
||||||
|
if tk == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.tk.uiControl == nil {
|
if tk.uiControl == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
n.tk.uiControl.Show()
|
tk.uiControl.Show()
|
||||||
} else {
|
} else {
|
||||||
n.tk.uiControl.Hide()
|
tk.uiControl.Hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) enable(b bool) {
|
func enable(n *tree.Node, b bool) {
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
if n == nil {
|
if n == nil {
|
||||||
panic("WHAT? enable was passed nil. How does this even happen?")
|
panic("WHAT? enable was passed nil. How does this even happen?")
|
||||||
}
|
}
|
||||||
if n.tk == nil {
|
if tk == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.tk.uiControl == nil {
|
if tk.uiControl == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (b) {
|
if (b) {
|
||||||
n.tk.uiControl.Enable()
|
tk.uiControl.Enable()
|
||||||
} else {
|
} else {
|
||||||
n.tk.uiControl.Disable()
|
tk.uiControl.Disable()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,73 +204,88 @@ func (n *node) Delete() {
|
||||||
func rawAction(a *widget.Action) {
|
func rawAction(a *widget.Action) {
|
||||||
log.Log(INFO, "rawAction() START a.ActionType =", a.ActionType, "a.Value", a.Value)
|
log.Log(INFO, "rawAction() START a.ActionType =", a.ActionType, "a.Value", a.Value)
|
||||||
|
|
||||||
if (a.ActionType == widget.InitToolkit) {
|
if (a.ActionType == widget.ToolkitInit) {
|
||||||
// TODO: make sure to only do this once
|
Init()
|
||||||
// go uiMain.Do(func() {
|
return
|
||||||
// ui.Main(demoUI)
|
}
|
||||||
// go catchActionChannel()
|
switch a.WidgetType {
|
||||||
// })
|
case widget.Root:
|
||||||
// try doing this on toolkit load in init()
|
me.treeRoot = me.myTree.AddNode(a)
|
||||||
|
log.Log(INFO, "doAction() found treeRoot")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Log(INFO, "rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
|
log.Warn("andlabs rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId, a.ActionType)
|
||||||
switch a.WidgetType {
|
switch a.WidgetType {
|
||||||
case widget.Flag:
|
case widget.Flag:
|
||||||
log.Log(ERROR, "rawAction() RE-IMPLEMENT LOG FLAGS")
|
log.Log(ERROR, "rawAction() RE-IMPLEMENT LOG FLAGS")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n := me.rootNode.findWidgetId(a.WidgetId)
|
if me.treeRoot == nil {
|
||||||
|
panic("me.treeRoot == nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
n := me.treeRoot.FindWidgetId(a.WidgetId)
|
||||||
|
|
||||||
if (a.ActionType == widget.Add) {
|
if (a.ActionType == widget.Add) {
|
||||||
ui.QueueMain(func() {
|
me.treeRoot.ListWidgets()
|
||||||
|
// ui.QueueMain(func() {
|
||||||
add(a)
|
add(a)
|
||||||
})
|
// })
|
||||||
// TODO: remove this artificial delay
|
// TODO: remove this artificial delay
|
||||||
// sleep(.001)
|
// sleep(.001)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a.ActionType == widget.Dump) {
|
if (a.ActionType == widget.Dump) {
|
||||||
log.Log(NOW, "rawAction() Dump =", a.ActionType, a.WidgetType, n.progname)
|
log.Log(NOW, "rawAction() Dump =", a.ActionType, a.WidgetType, n.State.ProgName)
|
||||||
me.rootNode.listChildren(true)
|
// me.rootNode.listChildren(true)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
me.rootNode.listChildren(true)
|
log.Error(errors.New("andlabs rawAction() ERROR findWidgetId found nil"), a.ActionType, a.WidgetType)
|
||||||
log.Log(NOW, "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 for id =", a.WidgetId)
|
||||||
log.Log(NOW, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
|
log.Log(NOW, "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 for id =", a.WidgetId)
|
||||||
|
me.treeRoot.ListWidgets()
|
||||||
return
|
return
|
||||||
panic("findWidgetId found nil for id = " + strconv.Itoa(a.WidgetId))
|
panic("findWidgetId found nil for id = " + string(a.WidgetId))
|
||||||
}
|
}
|
||||||
|
|
||||||
switch a.ActionType {
|
switch a.ActionType {
|
||||||
case widget.Show:
|
case widget.Show:
|
||||||
n.show(true)
|
show(n, true)
|
||||||
|
// n.show(true)
|
||||||
case widget.Hide:
|
case widget.Hide:
|
||||||
n.show(false)
|
show(n, false)
|
||||||
|
//n.show(false)
|
||||||
case widget.Enable:
|
case widget.Enable:
|
||||||
n.enable(true)
|
enable(n, true)
|
||||||
|
// n.enable(true)
|
||||||
case widget.Disable:
|
case widget.Disable:
|
||||||
log.Warn("andlabs got disable for", n.WidgetId, n.progname)
|
log.Warn("andlabs got disable for", n.WidgetId, n.State.ProgName)
|
||||||
n.enable(false)
|
enable(n, false)
|
||||||
|
// n.enable(false)
|
||||||
case widget.Get:
|
case widget.Get:
|
||||||
n.setText(a)
|
// n.setText(a)
|
||||||
|
setText(n, a)
|
||||||
case widget.GetText:
|
case widget.GetText:
|
||||||
switch a.WidgetType {
|
switch a.WidgetType {
|
||||||
case widget.Textbox:
|
case widget.Textbox:
|
||||||
a.Value = n.value
|
a.Value = n.State.Value
|
||||||
}
|
}
|
||||||
case widget.Set:
|
case widget.Set:
|
||||||
n.setText(a)
|
setText(n, a)
|
||||||
|
// n.setText(a)
|
||||||
case widget.SetText:
|
case widget.SetText:
|
||||||
n.setText(a)
|
setText(n, a)
|
||||||
|
// n.setText(a)
|
||||||
case widget.AddText:
|
case widget.AddText:
|
||||||
n.addText(a)
|
addText(n, a)
|
||||||
|
// n.addText(a)
|
||||||
|
/*
|
||||||
case widget.Margin:
|
case widget.Margin:
|
||||||
n.pad(true)
|
n.pad(true)
|
||||||
case widget.Unmargin:
|
case widget.Unmargin:
|
||||||
|
@ -231,8 +298,7 @@ func rawAction(a *widget.Action) {
|
||||||
n.Delete()
|
n.Delete()
|
||||||
case widget.Move:
|
case widget.Move:
|
||||||
log.Log(NOW, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
|
log.Log(NOW, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
|
||||||
newParent := me.rootNode.findWidgetId(a.ParentId)
|
*/
|
||||||
n.move(newParent)
|
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "rawAction() Unknown =", a.ActionType, a.WidgetType)
|
log.Log(ERROR, "rawAction() Unknown =", a.ActionType, a.WidgetType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,57 +6,67 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func add(a *widget.Action) {
|
func add(a *widget.Action) {
|
||||||
|
log.Warn("andlabs add()", a.WidgetId, a.State.ProgName)
|
||||||
if (a.WidgetType == widget.Root) {
|
if (a.WidgetType == widget.Root) {
|
||||||
me.rootNode = addNode(a)
|
if me.treeRoot == nil {
|
||||||
|
me.treeRoot = me.myTree.AddNode(a)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n := addNode(a)
|
// n := addNode(a)
|
||||||
|
n := me.myTree.AddNode(a)
|
||||||
|
|
||||||
p := n.parent
|
p := n.Parent
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case widget.Window:
|
case widget.Window:
|
||||||
newWindow(n)
|
log.Warn("SPEEDY Add window", n.WidgetId, n.GetProgName())
|
||||||
return
|
newWindow(p, n)
|
||||||
case widget.Tab:
|
|
||||||
p.newTab(n)
|
|
||||||
return
|
|
||||||
case widget.Label:
|
|
||||||
p.newLabel(n)
|
|
||||||
return
|
|
||||||
case widget.Button:
|
|
||||||
p.newButton(n)
|
|
||||||
return
|
|
||||||
case widget.Grid:
|
|
||||||
p.newGrid(n)
|
|
||||||
return
|
|
||||||
case widget.Checkbox:
|
|
||||||
p.newCheckbox(n)
|
|
||||||
return
|
|
||||||
case widget.Spinner:
|
|
||||||
p.newSpinner(n)
|
|
||||||
return
|
|
||||||
case widget.Slider:
|
|
||||||
p.newSlider(n)
|
|
||||||
return
|
|
||||||
case widget.Dropdown:
|
|
||||||
p.newDropdown(n)
|
|
||||||
return
|
|
||||||
case widget.Combobox:
|
|
||||||
p.newCombobox(n)
|
|
||||||
return
|
|
||||||
case widget.Textbox:
|
|
||||||
p.newTextbox(n)
|
|
||||||
return
|
return
|
||||||
case widget.Group:
|
case widget.Group:
|
||||||
p.newGroup(n)
|
log.Warn("SPEEDY Add Group", n.WidgetId, n.GetProgName())
|
||||||
|
newGroup(p, n)
|
||||||
|
return
|
||||||
|
case widget.Grid:
|
||||||
|
newGrid(n)
|
||||||
return
|
return
|
||||||
case widget.Box:
|
case widget.Box:
|
||||||
p.newBox(n)
|
newBox(n)
|
||||||
return
|
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:
|
case widget.Image:
|
||||||
p.newImage(n)
|
newImage(p, n)
|
||||||
return
|
return
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.progname)
|
log.Log(ERROR, "add() error TODO: ", n.WidgetType, n.State.ProgName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,40 @@ package main
|
||||||
import (
|
import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *node) addText(a *widget.Action) {
|
func compareStrings(n *tree.Node, ss []string) {
|
||||||
log.Log(CHANGE, "addText() START with a.Value =", a.Value)
|
}
|
||||||
t := n.tk
|
|
||||||
if (t == nil) {
|
// func (n *node) addText(a *widget.Action) {
|
||||||
log.Log(ERROR, "addText error. tk == nil", n.progname, n.WidgetId)
|
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
|
return
|
||||||
}
|
}
|
||||||
log.Log(CHANGE, "addText() Attempt on", n.WidgetType, "with", a.Value)
|
log.Warn("andlabs addText() Attempt on", n.WidgetType, "with", a.Value)
|
||||||
|
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case widget.Dropdown:
|
case widget.Dropdown:
|
||||||
n.addDropdownName(widget.GetString(a.Value))
|
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:
|
case widget.Combobox:
|
||||||
n.addComboboxName(widget.GetString(a.Value))
|
addComboboxName(n, widget.GetString(a.Value))
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "plugin Send() Don't know how to addText on", n.WidgetType, "yet", a.ActionType)
|
log.Log(ERROR, "plugin Send() Don't know how to addText on", n.WidgetType, "yet", a.ActionType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,17 +2,19 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
// make new Box here
|
// make new Box here
|
||||||
func (p *node) newBox(n *node) {
|
func newBox(n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
var box *ui.Box
|
var box *ui.Box
|
||||||
|
|
||||||
if n.direction == widget.Horizontal {
|
if n.State.Direction == widget.Horizontal {
|
||||||
box = ui.NewHorizontalBox()
|
box = ui.NewHorizontalBox()
|
||||||
} else {
|
} else {
|
||||||
box = ui.NewVerticalBox()
|
box = ui.NewVerticalBox()
|
||||||
|
@ -22,8 +24,8 @@ func (p *node) newBox(n *node) {
|
||||||
newt.uiBox = box
|
newt.uiBox = box
|
||||||
newt.uiControl = box
|
newt.uiControl = box
|
||||||
newt.boxC = 0
|
newt.boxC = 0
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(n.Parent, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -46,10 +48,11 @@ func (p *node) newBox(n *node) {
|
||||||
|
|
||||||
TODO: handle user killing/closing a window using the OS
|
TODO: handle user killing/closing a window using the OS
|
||||||
*/
|
*/
|
||||||
func (n *node) rawBox() *ui.Box {
|
// func (n *node) rawBox() *ui.Box {
|
||||||
|
func rawBox(n *tree.Node) *ui.Box {
|
||||||
var box *ui.Box
|
var box *ui.Box
|
||||||
|
|
||||||
if n.direction == widget.Horizontal {
|
if n.State.Direction == widget.Horizontal {
|
||||||
box = ui.NewHorizontalBox()
|
box = ui.NewHorizontalBox()
|
||||||
} else {
|
} else {
|
||||||
box = ui.NewVerticalBox()
|
box = ui.NewVerticalBox()
|
||||||
|
|
|
@ -1,25 +1,28 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newButton(n *node) {
|
// func (p *node) newButton(n *node) {
|
||||||
t := p.tk
|
func newButton(p *tree.Node, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
|
var ptk *guiWidget
|
||||||
|
ptk = p.TK.(*guiWidget)
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
b := ui.NewButton(widget.GetString(n.value))
|
b := ui.NewButton(n.GetLabel())
|
||||||
newt.uiButton = b
|
newt.uiButton = b
|
||||||
newt.uiControl = b
|
newt.uiControl = b
|
||||||
newt.parent = t
|
newt.parent = ptk
|
||||||
|
|
||||||
b.OnClicked(func(*ui.Button) {
|
b.OnClicked(func(*ui.Button) {
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,26 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newCheckbox(n *node) {
|
func newCheckbox(p *tree.Node, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
newt.uiCheckbox = ui.NewCheckbox(n.label)
|
newt.uiCheckbox = ui.NewCheckbox(n.GetLabel())
|
||||||
newt.uiControl = newt.uiCheckbox
|
newt.uiControl = newt.uiCheckbox
|
||||||
|
|
||||||
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
|
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
|
||||||
n.value = newt.checked()
|
n.SetValue(newt.checked())
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *guiWidget) checked() bool {
|
func (t *guiWidget) checked() bool {
|
||||||
|
|
|
@ -5,10 +5,11 @@ import (
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newCombobox(n *node) {
|
func newCombobox(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
cb := ui.NewEditableCombobox()
|
cb := ui.NewEditableCombobox()
|
||||||
|
@ -20,46 +21,53 @@ func (p *node) newCombobox(n *node) {
|
||||||
newt.val = make(map[int]string)
|
newt.val = make(map[int]string)
|
||||||
|
|
||||||
cb.OnChanged(func(spin *ui.EditableCombobox) {
|
cb.OnChanged(func(spin *ui.EditableCombobox) {
|
||||||
n.value = spin.Text()
|
n.SetValue(spin.Text())
|
||||||
log.Warn("combobox changed =" + spin.Text() + ".")
|
log.Warn("combobox changed =" + spin.Text() + ".")
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
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
|
// add the initial combobox entries
|
||||||
for i, s := range n.strings {
|
for i, s := range n.State.Strings {
|
||||||
log.Warn("add combobox entries on create", n.progname, i, s)
|
log.Warn("add combobox entries on create", n.GetProgName(), i, s)
|
||||||
n.addComboboxName(s)
|
addComboboxName(n, s)
|
||||||
}
|
}
|
||||||
cur := widget.GetString(n.value)
|
cur := n.String()
|
||||||
log.Warn("add combobox: TODO: set default value on create", n.progname, cur)
|
log.Warn("add combobox: TODO: set default value on create", n.GetProgName(), cur)
|
||||||
n.setComboboxName(cur)
|
setComboboxName(n, cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) addComboboxName(s string) {
|
func addComboboxName(n *tree.Node, s string) {
|
||||||
if ! n.ready() { return }
|
if ! ready(n) { return }
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
log.Log(INFO, "addComboboxName()", n.WidgetId, "add:", s)
|
log.Log(INFO, "addComboboxName()", n.WidgetId, "add:", s)
|
||||||
|
|
||||||
n.tk.uiEditableCombobox.Append(s)
|
tk.uiEditableCombobox.Append(s)
|
||||||
if (n.tk.val == nil) {
|
if (tk.val == nil) {
|
||||||
log.Log(INFO, "make map didn't work")
|
log.Log(INFO, "make map didn't work")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n.tk.val[n.tk.c] = s
|
tk.val[tk.c] = s
|
||||||
|
|
||||||
// If this is the first menu added, set the dropdown to it
|
// If this is the first menu added, set the dropdown to it
|
||||||
if (n.tk.c == 0) {
|
if (tk.c == 0) {
|
||||||
log.Log(INFO, "THIS IS THE FIRST combobox", s)
|
log.Log(INFO, "THIS IS THE FIRST combobox", s)
|
||||||
n.tk.uiEditableCombobox.SetText(s)
|
tk.uiEditableCombobox.SetText(s)
|
||||||
}
|
}
|
||||||
n.tk.c = n.tk.c + 1
|
tk.c = tk.c + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) setComboboxName(s string) bool {
|
func setComboboxName(n *tree.Node, s string) bool {
|
||||||
if ! n.ready() { return false}
|
if ! ready(n) { return false}
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
log.Log(INFO, "SetComboboxName()", n.WidgetId, ",", s)
|
log.Log(INFO, "SetComboboxName()", n.WidgetId, ",", s)
|
||||||
n.tk.uiEditableCombobox.SetText(s)
|
tk.uiEditableCombobox.SetText(s)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
../nocui/common.go
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/gui/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")
|
||||||
|
}
|
||||||
|
*/
|
|
@ -1,8 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
// "go.wit.com/gui/widget"
|
// "go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
@ -94,7 +92,7 @@ func (n *node) dumpWidget(b bool) {
|
||||||
}
|
}
|
||||||
info = n.WidgetType.String()
|
info = n.WidgetType.String()
|
||||||
|
|
||||||
d = strconv.Itoa(n.WidgetId) + " " + info + " " + n.progname
|
d = string(n.WidgetId) + " " + info + " " + n.progname
|
||||||
|
|
||||||
var tabs string
|
var tabs string
|
||||||
for i := 0; i < listChildrenDepth; i++ {
|
for i := 0; i < listChildrenDepth; i++ {
|
||||||
|
|
|
@ -5,12 +5,13 @@ import (
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newDropdown(n *node) {
|
func newDropdown(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
log.Log(INFO, "gui.Toolbox.newDropdown() START", n.progname)
|
log.Log(INFO, "gui.Toolbox.newDropdown() START", n.GetProgName())
|
||||||
|
|
||||||
cb := ui.NewCombobox()
|
cb := ui.NewCombobox()
|
||||||
newt.uiCombobox = cb
|
newt.uiCombobox = cb
|
||||||
|
@ -24,60 +25,69 @@ func (p *node) newDropdown(n *node) {
|
||||||
i := spin.Selected()
|
i := spin.Selected()
|
||||||
if (newt.val == nil) {
|
if (newt.val == nil) {
|
||||||
log.Log(ERROR, "make map didn't work")
|
log.Log(ERROR, "make map didn't work")
|
||||||
n.value = "map did not work. ui.Combobox error"
|
n.SetValue("map did not work. ui.Combobox error")
|
||||||
} else {
|
} else {
|
||||||
n.value = newt.val[i]
|
n.SetValue(newt.val[i])
|
||||||
}
|
}
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
|
|
||||||
if n.strings == nil {return}
|
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
|
// add the initial dropdown entries
|
||||||
for i, s := range n.strings {
|
for i, s := range n.State.Strings {
|
||||||
log.Warn("add dropdown: add entries on create", n.progname, i, s)
|
log.Warn("add dropdown: add entries on create", n.GetProgName(), i, s)
|
||||||
n.addDropdownName(s)
|
addDropdownName(n, s)
|
||||||
}
|
}
|
||||||
cur := widget.GetString(n.value)
|
cur := n.String()
|
||||||
log.Warn("add dropdown: set default value on create", n.progname, cur)
|
log.Warn("add dropdown: set default value on create", n.GetProgName(), cur)
|
||||||
n.setDropdownName(cur)
|
setDropdownName(n, cur)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) SetDropdownInt(i int) {
|
func setDropdownInt(n *tree.Node, i int) {
|
||||||
if ! n.ready() { return }
|
if ! ready(n) { return }
|
||||||
n.tk.uiCombobox.SetSelected(i)
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
|
tk.uiCombobox.SetSelected(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) addDropdownName(s string) {
|
func addDropdownName(n *tree.Node, s string) {
|
||||||
if ! n.ready() { return }
|
if ! ready(n) { return }
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
log.Log(INFO, "addDropdownName()", n.WidgetId, "add:", s)
|
log.Log(INFO, "addDropdownName()", n.WidgetId, "add:", s)
|
||||||
|
|
||||||
n.tk.uiCombobox.Append(s)
|
tk.uiCombobox.Append(s)
|
||||||
if (n.tk.val == nil) {
|
if (tk.val == nil) {
|
||||||
log.Log(INFO, "make map didn't work")
|
log.Log(INFO, "make map didn't work")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
n.tk.val[n.tk.c] = s
|
tk.val[tk.c] = s
|
||||||
|
|
||||||
// If this is the first menu added, set the dropdown to it
|
// If this is the first menu added, set the dropdown to it
|
||||||
if (n.tk.c == 0) {
|
if (tk.c == 0) {
|
||||||
log.Log(INFO, "THIS IS THE FIRST Dropdown", s)
|
log.Log(INFO, "THIS IS THE FIRST Dropdown", s)
|
||||||
n.tk.uiCombobox.SetSelected(0)
|
tk.uiCombobox.SetSelected(0)
|
||||||
}
|
}
|
||||||
n.tk.c = n.tk.c + 1
|
tk.c = tk.c + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) setDropdownName(s string) bool {
|
func setDropdownName(n *tree.Node, s string) bool {
|
||||||
if ! n.ready() { return false}
|
if ! ready(n) { return false}
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
log.Log(INFO, "SetDropdownName()", n.WidgetId, ",", s)
|
log.Log(INFO, "SetDropdownName()", n.WidgetId, ",", s)
|
||||||
|
|
||||||
for i, tmp := range n.tk.val {
|
for i, tmp := range tk.val {
|
||||||
if s == tmp {
|
if s == tmp {
|
||||||
n.value = s
|
n.SetValue(s)
|
||||||
n.SetDropdownInt(i)
|
setDropdownInt(n, i)
|
||||||
log.Warn("SetDropdownInt() worked", tmp, i)
|
log.Warn("SetDropdownInt() worked", tmp, i)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
@ -10,9 +12,9 @@ import (
|
||||||
// -- (1,1) -- (2,1) -- (3,1) --
|
// -- (1,1) -- (2,1) -- (3,1) --
|
||||||
// -- (1,2) -- (2,1) -- (3,1) --
|
// -- (1,2) -- (2,1) -- (3,1) --
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
func (p *node) newGrid(n *node) {
|
func newGrid(n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
var newt *guiWidget
|
var newt *guiWidget
|
||||||
|
|
||||||
newt = new(guiWidget)
|
newt = new(guiWidget)
|
||||||
|
|
||||||
c := ui.NewGrid()
|
c := ui.NewGrid()
|
||||||
|
@ -20,6 +22,6 @@ func (p *node) newGrid(n *node) {
|
||||||
newt.uiControl = c
|
newt.uiControl = c
|
||||||
c.SetPadded(true)
|
c.SetPadded(true)
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(n.Parent, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/widget"
|
// "go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newGroup(n *node) {
|
func newGroup(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
g := ui.NewGroup(widget.GetString(n.value))
|
g := ui.NewGroup(n.GetLabel())
|
||||||
g.SetMargined(true)
|
g.SetMargined(true)
|
||||||
newt.uiGroup = g
|
newt.uiGroup = g
|
||||||
newt.uiControl = g
|
newt.uiControl = g
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ func (p *node) newImage(n *node) {
|
||||||
// newt.uiControl = img
|
// newt.uiControl = img
|
||||||
|
|
||||||
n.tk = newt
|
n.tk = newt
|
||||||
p.place(n)
|
// p.place(n)
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if (a.Name == "image") {
|
if (a.Name == "image") {
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newLabel(n *node) {
|
func newLabel(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
c := ui.NewLabel(widget.GetString(n.value))
|
c := ui.NewLabel(n.GetLabel())
|
||||||
newt.uiLabel = c
|
newt.uiLabel = c
|
||||||
newt.uiControl = c
|
newt.uiControl = c
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,11 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
|
"runtime/debug"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
// the _ means we only need this for the init()
|
// the _ means we only need this for the init()
|
||||||
|
@ -17,7 +20,11 @@ var muAction sync.Mutex
|
||||||
func queueMain(currentA widget.Action) {
|
func queueMain(currentA widget.Action) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Warn("YAHOOOO Recovered in main application:", r)
|
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() {
|
ui.QueueMain( func() {
|
||||||
|
@ -25,29 +32,14 @@ func queueMain(currentA widget.Action) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func catchActionChannel() {
|
|
||||||
log.Log(INFO, "catchActionChannel() START")
|
|
||||||
for {
|
|
||||||
log.Log(INFO, "catchActionChannel() for loop")
|
|
||||||
select {
|
|
||||||
case a := <-pluginChan:
|
|
||||||
log.Log(INFO, "catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
|
|
||||||
log.Log(INFO, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
muAction.Lock()
|
|
||||||
// TODO ui.QueueMain(f)
|
|
||||||
// TODO ui.QueueMain( func() {rawAction(a)} )
|
|
||||||
// rawAction(a)
|
|
||||||
queueMain(a)
|
|
||||||
muAction.Unlock()
|
|
||||||
log.Log(INFO, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func guiMain() {
|
func guiMain() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Warn("YAHOOOO Recovered in main application:", r)
|
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() {
|
ui.Main(func() {
|
||||||
|
@ -55,6 +47,10 @@ func guiMain() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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
|
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
||||||
func init() {
|
func init() {
|
||||||
log.Log(INFO, "Init() START")
|
log.Log(INFO, "Init() START")
|
||||||
|
@ -63,15 +59,12 @@ func init() {
|
||||||
// log.Log(INFO, "init() Setting defaultBehavior = true")
|
// log.Log(INFO, "init() Setting defaultBehavior = true")
|
||||||
setDefaultBehavior(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?
|
// 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
|
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
|
||||||
// actually, this probably breaks the macos build
|
// actually, this probably breaks the macos build
|
||||||
go guiMain()
|
go guiMain()
|
||||||
|
|
||||||
// andlabs = make(map[int]*andlabsT)
|
|
||||||
pluginChan = make(chan widget.Action, 1)
|
|
||||||
|
|
||||||
log.Log(INFO, "Init() start channel reciever")
|
|
||||||
go catchActionChannel()
|
|
||||||
log.Log(INFO, "Init() END")
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
// "os"
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This routine is very specific to this toolkit
|
// This routine is very specific to this toolkit
|
||||||
|
@ -33,62 +36,78 @@ import (
|
||||||
// -- (0,0) -- (1,0) -- (1,0) --
|
// -- (0,0) -- (1,0) -- (1,0) --
|
||||||
// -- (0,1) -- (1,1) -- (1,1) --
|
// -- (0,1) -- (1,1) -- (1,1) --
|
||||||
// -----------------------------
|
// -----------------------------
|
||||||
func (p *node) place(n *node) bool {
|
|
||||||
log.Log(INFO, "place() START", n.WidgetType, n.progname)
|
|
||||||
|
|
||||||
if (p.tk == nil) {
|
func place(p *tree.Node, n *tree.Node) bool {
|
||||||
log.Log(ERROR, "p.tk == nil", p.progname, p.ParentId, p.WidgetType, p.tk)
|
log.Warn("SPEEDY newplace() 1 START", n.WidgetId, n.GetProgName(), n.GetLabel(), n.String())
|
||||||
log.Log(ERROR, "n = ", n.progname, n.ParentId, n.WidgetType, n.tk)
|
log.Warn("SPEEDY newplace() n.State.Strings =", n.State.Strings)
|
||||||
panic("p.tk == nil")
|
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.Log(INFO, "place() switch", p.WidgetType)
|
||||||
|
log.Warn("SPEEDY newplace() before switch", n.WidgetId, n.GetProgName())
|
||||||
switch p.WidgetType {
|
switch p.WidgetType {
|
||||||
case widget.Grid:
|
case widget.Grid:
|
||||||
log.Log(INFO, "place() Grid try at Parent X,Y =", n.X, n.Y)
|
tk.gridX = n.State.GridOffset.X - 1
|
||||||
n.tk.gridX = n.AtW - 1
|
tk.gridY = n.State.GridOffset.Y - 1
|
||||||
n.tk.gridY = n.AtH - 1
|
log.Warn("place() on Grid at gridX,gridY", tk.gridX, tk.gridY)
|
||||||
log.Log(INFO, "place() Grid try at gridX,gridY", n.tk.gridX, n.tk.gridY)
|
ptk.uiGrid.Append(tk.uiControl,
|
||||||
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
|
tk.gridX, tk.gridY, 1, 1,
|
||||||
p.tk.uiGrid.Append(n.tk.uiControl,
|
|
||||||
n.tk.gridX, n.tk.gridY, 1, 1,
|
|
||||||
false, ui.AlignFill, false, ui.AlignFill)
|
false, ui.AlignFill, false, ui.AlignFill)
|
||||||
return true
|
return true
|
||||||
case widget.Group:
|
case widget.Group:
|
||||||
if (p.tk.uiBox == nil) {
|
if (ptk.uiBox == nil) {
|
||||||
log.Log(WARN, "place() andlabs hack group to use add a box", n.progname, n.WidgetType)
|
log.Log(WARN, "place() andlabs hack group to use add a box", n.GetProgName(), n.WidgetType)
|
||||||
p.tk.uiBox = n.rawBox()
|
ptk.uiBox = rawBox(n)
|
||||||
p.tk.uiGroup.SetChild(p.tk.uiBox)
|
ptk.uiGroup.SetChild(ptk.uiBox)
|
||||||
}
|
}
|
||||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
ptk.uiBox.Append(tk.uiControl, stretchy)
|
||||||
return true
|
return true
|
||||||
case widget.Tab:
|
case widget.Tab:
|
||||||
if (p.tk.uiTab == nil) {
|
if (ptk.uiTab == nil) {
|
||||||
log.Log(ERROR, "p.tk.uiTab == nil for n.WidgetId =", n.WidgetId, "p.tk =", p.tk)
|
log.Log(ERROR, "ptk.uiTab == nil for n.WidgetId =", n.WidgetId, "ptk =", ptk)
|
||||||
panic("p.tk.uiTab == nil")
|
panic("ptk.uiTab == nil")
|
||||||
}
|
}
|
||||||
if (n.tk.uiControl == nil) {
|
if (tk.uiControl == nil) {
|
||||||
log.Log(ERROR, "n.tk.uiControl == nil for n.WidgetId =", n.WidgetId, "n.tk =", n.tk)
|
log.Log(ERROR, "tk.uiControl == nil for n.WidgetId =", n.WidgetId, "tk =", tk)
|
||||||
panic("n.tk.uiControl == nil")
|
panic("tk.uiControl == nil")
|
||||||
}
|
}
|
||||||
log.Log(ERROR, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
|
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.progname, n.Text, n.WidgetType)
|
// 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.progname, p.Text, p.WidgetType)
|
// log.Log(ERROR, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.GetProgName(), p.Text, p.WidgetType)
|
||||||
// panic("n.tk.uiControl == nil")
|
// panic("tk.uiControl == nil")
|
||||||
p.tk.uiTab.Append(widget.GetString(n.value), n.tk.uiControl)
|
ptk.uiTab.Append(widget.GetString(n.State.Value), tk.uiControl)
|
||||||
p.tk.boxC += 1
|
ptk.boxC += 1
|
||||||
return true
|
return true
|
||||||
case widget.Box:
|
case widget.Box:
|
||||||
log.Log(INFO, "place() uiBox =", p.tk.uiBox)
|
log.Warn("SPEEDY Add Something to Box", n.WidgetId, n.GetProgName())
|
||||||
log.Log(INFO, "place() uiControl =", n.tk.uiControl)
|
log.Log(INFO, "place() uiBox =", ptk.uiBox)
|
||||||
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
|
log.Log(INFO, "place() uiControl =", tk.uiControl)
|
||||||
p.tk.boxC += 1
|
ptk.uiBox.Append(tk.uiControl, stretchy)
|
||||||
|
ptk.boxC += 1
|
||||||
return true
|
return true
|
||||||
case widget.Window:
|
case widget.Window:
|
||||||
p.tk.uiWindow.SetChild(n.tk.uiControl)
|
log.Warn("SPEEDY Add Something to Window", n.WidgetId, n.GetProgName())
|
||||||
|
ptk.uiWindow.SetChild(tk.uiControl)
|
||||||
return true
|
return true
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "place() how? Parent =", p.WidgetId, p.WidgetType)
|
log.Log(ERROR, "place() how? Parent =", p.WidgetId, p.WidgetType)
|
||||||
}
|
}
|
||||||
|
log.Warn("SPEEDY newplace() return", n.WidgetId, n.GetProgName())
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,18 @@ package main
|
||||||
import (
|
import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *node) setText(a *widget.Action) {
|
// func (n *node) setText(a *widget.Action) {
|
||||||
|
func setText(n *tree.Node, a *widget.Action) {
|
||||||
name := widget.GetString(a.Value)
|
name := widget.GetString(a.Value)
|
||||||
|
var tk *guiWidget
|
||||||
|
tk = n.TK.(*guiWidget)
|
||||||
|
|
||||||
log.Log(CHANGE, "setText() START with text =", name)
|
log.Log(CHANGE, "setText() START with text =", name)
|
||||||
t := n.tk
|
if (tk == nil) {
|
||||||
if (t == nil) {
|
log.Log(ERROR, "setText error. tk == nil", n.GetProgName(), n.WidgetId)
|
||||||
log.Log(ERROR, "setText error. tk == nil", n.progname, n.WidgetId)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Log(CHANGE, "setText() Attempt on", n.WidgetType, "with", name)
|
log.Log(CHANGE, "setText() Attempt on", n.WidgetType, "with", name)
|
||||||
|
@ -19,38 +22,38 @@ func (n *node) setText(a *widget.Action) {
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case widget.Window:
|
case widget.Window:
|
||||||
log.Warn("setText() Attempt to set the title to", name)
|
log.Warn("setText() Attempt to set the title to", name)
|
||||||
t.uiWindow.SetTitle(name)
|
tk.uiWindow.SetTitle(name)
|
||||||
case widget.Tab:
|
case widget.Tab:
|
||||||
case widget.Group:
|
case widget.Group:
|
||||||
t.uiGroup.SetTitle(name)
|
tk.uiGroup.SetTitle(name)
|
||||||
case widget.Checkbox:
|
case widget.Checkbox:
|
||||||
t.uiCheckbox.SetText(name)
|
tk.uiCheckbox.SetText(name)
|
||||||
case widget.Textbox:
|
case widget.Textbox:
|
||||||
if (t.uiEntry != nil) {
|
if (tk.uiEntry != nil) {
|
||||||
t.uiEntry.SetText(name)
|
tk.uiEntry.SetText(name)
|
||||||
}
|
}
|
||||||
if (t.uiMultilineEntry != nil) {
|
if (tk.uiMultilineEntry != nil) {
|
||||||
t.uiMultilineEntry.SetText(name)
|
tk.uiMultilineEntry.SetText(name)
|
||||||
}
|
}
|
||||||
case widget.Label:
|
case widget.Label:
|
||||||
t.uiLabel.SetText(name)
|
tk.uiLabel.SetText(name)
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
t.uiButton.SetText(name)
|
tk.uiButton.SetText(name)
|
||||||
case widget.Slider:
|
case widget.Slider:
|
||||||
log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.progname)
|
log.Log(ERROR, "setText() on slider unknown", a.ActionType, "on checkbox", n.GetProgName())
|
||||||
case widget.Spinner:
|
case widget.Spinner:
|
||||||
log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.progname)
|
log.Log(ERROR, "setText() on spinner unknown", a.ActionType, "on checkbox", n.GetProgName())
|
||||||
case widget.Dropdown:
|
case widget.Dropdown:
|
||||||
var orig int
|
var orig int
|
||||||
var i int = -1
|
var i int = -1
|
||||||
var s string
|
var s string
|
||||||
orig = t.uiCombobox.Selected()
|
orig = tk.uiCombobox.Selected()
|
||||||
log.Log(CHANGE, "try to set the Dropdown to", name, "from", orig)
|
log.Log(CHANGE, "try to set the Dropdown to", name, "from", orig)
|
||||||
// try to find the string
|
// try to find the string
|
||||||
for i, s = range t.val {
|
for i, s = range tk.val {
|
||||||
log.Log(CHANGE, "i, s", i, s)
|
log.Log(CHANGE, "i, s", i, s)
|
||||||
if (name == s) {
|
if (name == s) {
|
||||||
t.uiCombobox.SetSelected(i)
|
tk.uiCombobox.SetSelected(i)
|
||||||
log.Log(CHANGE, "setText() Dropdown worked.", name)
|
log.Log(CHANGE, "setText() Dropdown worked.", name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -62,10 +65,10 @@ func (n *node) setText(a *widget.Action) {
|
||||||
}
|
}
|
||||||
// if the string was never set, then set the dropdown to the last thing added to the menu
|
// if the string was never set, then set the dropdown to the last thing added to the menu
|
||||||
if (orig == -1) {
|
if (orig == -1) {
|
||||||
t.uiCombobox.SetSelected(i)
|
tk.uiCombobox.SetSelected(i)
|
||||||
}
|
}
|
||||||
case widget.Combobox:
|
case widget.Combobox:
|
||||||
t.uiEditableCombobox.SetText(name)
|
tk.uiEditableCombobox.SetText(name)
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
|
log.Log(ERROR, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,29 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newSlider(n *node) {
|
func newSlider(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
s := ui.NewSlider(n.X, n.Y)
|
var x, y int
|
||||||
|
x = n.State.Range.Low
|
||||||
|
y = n.State.Range.High
|
||||||
|
|
||||||
|
s := ui.NewSlider(x, y)
|
||||||
newt.uiSlider = s
|
newt.uiSlider = s
|
||||||
newt.uiControl = s
|
newt.uiControl = s
|
||||||
|
|
||||||
s.OnChanged(func(spin *ui.Slider) {
|
s.OnChanged(func(spin *ui.Slider) {
|
||||||
n.value = newt.uiSlider.Value()
|
n.SetValue(newt.uiSlider.Value())
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,25 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newSpinner(n *node) {
|
func newSpinner(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
s := ui.NewSpinbox(n.X, n.Y)
|
s := ui.NewSpinbox(n.State.Range.Low,n.State.Range.High)
|
||||||
newt.uiSpinbox = s
|
newt.uiSpinbox = s
|
||||||
newt.uiControl = s
|
newt.uiControl = s
|
||||||
|
|
||||||
s.OnChanged(func(s *ui.Spinbox) {
|
s.OnChanged(func(s *ui.Spinbox) {
|
||||||
n.value = newt.uiSpinbox.Value()
|
n.SetValue(newt.uiSpinbox.Value())
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
place(p, n)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import "go.wit.com/dev/andlabs/ui"
|
import (
|
||||||
import _ "go.wit.com/dev/andlabs/ui/winmanifest"
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
|
"go.wit.com/dev/andlabs/ui"
|
||||||
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
|
)
|
||||||
|
|
||||||
// var andlabs map[int]*andlabsT
|
// var andlabs map[int]*andlabsT
|
||||||
// var callback func(int) bool
|
// var callback func(int) bool
|
||||||
|
@ -11,7 +15,9 @@ import _ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
var me config
|
var me config
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
rootNode *node // the base of the binary tree. it should have id == 0
|
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
|
// stores the raw toolkit internals
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
|
||||||
"go.wit.com/dev/andlabs/ui"
|
"go.wit.com/dev/andlabs/ui"
|
||||||
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
_ "go.wit.com/dev/andlabs/ui/winmanifest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (p *node) newTextbox(n *node) {
|
func newTextbox(p, n *tree.Node) {
|
||||||
|
if notNew(n) { return }
|
||||||
newt := new(guiWidget)
|
newt := new(guiWidget)
|
||||||
|
|
||||||
if (n.X == 1) {
|
if (n.State.Range.Low == 1) {
|
||||||
e := ui.NewEntry()
|
e := ui.NewEntry()
|
||||||
newt.uiEntry = e
|
newt.uiEntry = e
|
||||||
newt.uiControl = e
|
newt.uiControl = e
|
||||||
|
|
||||||
e.OnChanged(func(spin *ui.Entry) {
|
e.OnChanged(func(spin *ui.Entry) {
|
||||||
n.value = spin.Text()
|
n.SetValue(spin.Text())
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
e := ui.NewNonWrappingMultilineEntry()
|
e := ui.NewNonWrappingMultilineEntry()
|
||||||
|
@ -23,10 +26,10 @@ func (p *node) newTextbox(n *node) {
|
||||||
newt.uiControl = e
|
newt.uiControl = e
|
||||||
|
|
||||||
e.OnChanged(func(spin *ui.MultilineEntry) {
|
e.OnChanged(func(spin *ui.MultilineEntry) {
|
||||||
n.value = spin.Text()
|
n.SetValue(spin.Text())
|
||||||
n.doUserEvent()
|
me.myTree.DoUserEvent(n)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
p.place(n)
|
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/gui/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()
|
||||||
|
}
|
|
@ -2,16 +2,16 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
// this is specific to the nocui toolkit
|
func initWidget(n *tree.Node) *guiWidget {
|
||||||
func initWidget(n *node) *guiWidget {
|
|
||||||
var w *guiWidget
|
var w *guiWidget
|
||||||
w = new(guiWidget)
|
w = new(guiWidget)
|
||||||
|
|
||||||
if n.WidgetType == widget.Root {
|
if n.WidgetType == widget.Root {
|
||||||
n.WidgetId = 0
|
n.WidgetId = 0
|
||||||
me.rootNode = n
|
me.treeRoot = n
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
return w
|
return w
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
|
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
|
||||||
|
@ -16,23 +17,24 @@ func (t *guiWidget) ErrorWindow(msg1 string, msg2 string) {
|
||||||
ui.MsgBoxError(t.uiWindow, msg1, msg2)
|
ui.MsgBoxError(t.uiWindow, msg1, msg2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newWindow(n *node) {
|
func newWindow(p, n *tree.Node) {
|
||||||
var newt *guiWidget
|
var newt *guiWidget
|
||||||
newt = new(guiWidget)
|
newt = new(guiWidget)
|
||||||
|
|
||||||
// menubar bool is if the OS defined border on the window should be used
|
// menubar bool is if the OS defined border on the window should be used
|
||||||
win := ui.NewWindow(n.progname, n.X, n.Y, menubar)
|
win := ui.NewWindow(n.GetProgName(), 640, 480, menubar)
|
||||||
win.SetBorderless(canvas)
|
win.SetBorderless(canvas)
|
||||||
win.SetMargined(margin)
|
win.SetMargined(margin)
|
||||||
win.OnClosing(func(*ui.Window) bool {
|
win.OnClosing(func(*ui.Window) bool {
|
||||||
n.show(false)
|
// show(n, false)
|
||||||
n.doUserEvent()
|
me.myTree.DoWindowCloseEvent(n)
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
newt.uiWindow = win
|
newt.uiWindow = win
|
||||||
newt.uiControl = win
|
newt.uiControl = win
|
||||||
|
|
||||||
n.tk = newt
|
n.TK = newt
|
||||||
|
place(p, n)
|
||||||
win.Show()
|
win.Show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
/*
|
|
||||||
These 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 (
|
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/widget"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is in common.go, do not move it
|
|
||||||
func addNode(a *widget.Action) *node {
|
|
||||||
n := new(node)
|
|
||||||
n.WidgetType = a.WidgetType
|
|
||||||
n.WidgetId = a.WidgetId
|
|
||||||
n.ParentId = a.ParentId
|
|
||||||
|
|
||||||
n.state = a.State
|
|
||||||
|
|
||||||
// copy the data from the action message
|
|
||||||
n.progname = a.ProgName
|
|
||||||
n.value = a.Value
|
|
||||||
n.direction = a.Direction
|
|
||||||
n.strings = a.Strings
|
|
||||||
|
|
||||||
// TODO: these need to be rethought
|
|
||||||
n.X = a.X
|
|
||||||
n.Y = a.Y
|
|
||||||
n.W = a.W
|
|
||||||
n.H = a.H
|
|
||||||
n.AtW = a.AtW
|
|
||||||
n.AtH = a.AtH
|
|
||||||
|
|
||||||
// store the internal toolkit information
|
|
||||||
n.tk = initWidget(n)
|
|
||||||
// n.tk = new(guiWidget)
|
|
||||||
|
|
||||||
if (a.WidgetType == widget.Root) {
|
|
||||||
log.Log(INFO, "addNode() Root")
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
|
|
||||||
log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
|
|
||||||
return me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add this new widget on the binary tree
|
|
||||||
n.parent = me.rootNode.findWidgetId(a.ParentId)
|
|
||||||
if n.parent != nil {
|
|
||||||
n.parent.children = append(n.parent.children, n)
|
|
||||||
//w := n.tk
|
|
||||||
//w.parent = n.parent.tk
|
|
||||||
//w.parent.children = append(w.parent.children, w)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
|
@ -1 +0,0 @@
|
||||||
../nocui/common.go
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
These 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/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this is the channel we send user events like
|
||||||
|
// mouse clicks or keyboard events back to the program
|
||||||
|
var callback chan widget.Action
|
||||||
|
|
||||||
|
// this is the channel we get requests to make widgets
|
||||||
|
var pluginChan chan widget.Action
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
// searches the binary tree for a WidgetId
|
||||||
|
func (n *node) findWidgetId(id int) *node {
|
||||||
|
if (n == nil) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if n.WidgetId == id {
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, child := range n.children {
|
||||||
|
newN := child.findWidgetId(id)
|
||||||
|
if (newN != nil) {
|
||||||
|
return newN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *node) doUserEvent() {
|
||||||
|
if (callback == nil) {
|
||||||
|
log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.WidgetId = n.WidgetId
|
||||||
|
a.Value = n.value
|
||||||
|
a.ActionType = widget.User
|
||||||
|
log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
|
||||||
|
callback <- a
|
||||||
|
log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
callback = guiCallback
|
||||||
|
}
|
||||||
|
|
||||||
|
func PluginChannel() chan widget.Action {
|
||||||
|
return pluginChan
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func convertString(val any) string {
|
||||||
|
switch v := val.(type) {
|
||||||
|
case bool:
|
||||||
|
n.B = val.(bool)
|
||||||
|
case string:
|
||||||
|
n.label = val.(string)
|
||||||
|
n.S = val.(string)
|
||||||
|
case int:
|
||||||
|
n.I = val.(int)
|
||||||
|
default:
|
||||||
|
log.Error(errors.New("Set() unknown type"), "v =", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// this is in common.go, do not move it
|
||||||
|
func getString(A any) string {
|
||||||
|
if A == nil {
|
||||||
|
log.Warn("getString() got nil")
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
var k reflect.Kind
|
||||||
|
k = reflect.TypeOf(A).Kind()
|
||||||
|
|
||||||
|
switch k {
|
||||||
|
case reflect.Int:
|
||||||
|
var i int
|
||||||
|
i = A.(int)
|
||||||
|
return string(i)
|
||||||
|
case reflect.String:
|
||||||
|
return A.(string)
|
||||||
|
case reflect.Bool:
|
||||||
|
if A.(bool) == true {
|
||||||
|
return "true"
|
||||||
|
} else {
|
||||||
|
return "false"
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
log.Warn("getString uknown kind", k, "value =", A)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// this is in common.go, do not move it
|
||||||
|
func addNode(a *widget.Action) *node {
|
||||||
|
n := new(node)
|
||||||
|
n.WidgetType = a.WidgetType
|
||||||
|
n.WidgetId = a.WidgetId
|
||||||
|
n.ParentId = a.ParentId
|
||||||
|
|
||||||
|
n.state = a.State
|
||||||
|
|
||||||
|
// copy the data from the action message
|
||||||
|
n.progname = a.ProgName
|
||||||
|
n.value = a.Value
|
||||||
|
n.direction = a.Direction
|
||||||
|
n.strings = a.Strings
|
||||||
|
|
||||||
|
// TODO: these need to be rethought
|
||||||
|
n.X = a.X
|
||||||
|
n.Y = a.Y
|
||||||
|
n.W = a.W
|
||||||
|
n.H = a.H
|
||||||
|
n.AtW = a.AtW
|
||||||
|
n.AtH = a.AtH
|
||||||
|
|
||||||
|
// store the internal toolkit information
|
||||||
|
n.tk = initWidget(n)
|
||||||
|
// n.tk = new(guiWidget)
|
||||||
|
|
||||||
|
if (a.WidgetType == widget.Root) {
|
||||||
|
log.Log(INFO, "addNode() Root")
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
|
||||||
|
log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
|
||||||
|
return me.rootNode.findWidgetId(a.WidgetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add this new widget on the binary tree
|
||||||
|
n.parent = me.rootNode.findWidgetId(a.ParentId)
|
||||||
|
if n.parent != nil {
|
||||||
|
n.parent.children = append(n.parent.children, n)
|
||||||
|
//w := n.tk
|
||||||
|
//w.parent = n.parent.tk
|
||||||
|
//w.parent.children = append(w.parent.children, w)
|
||||||
|
}
|
||||||
|
return n
|
||||||
|
}
|
|
@ -50,7 +50,7 @@ func action(a *widget.Action) {
|
||||||
n.AddText(widget.GetString(a.Value))
|
n.AddText(widget.GetString(a.Value))
|
||||||
case widget.Move:
|
case widget.Move:
|
||||||
log.Log(NOW, "attempt to move() =", a.ActionType, a.WidgetType, a.ProgName)
|
log.Log(NOW, "attempt to move() =", a.ActionType, a.WidgetType, a.ProgName)
|
||||||
case widget.CloseToolkit:
|
case widget.ToolkitClose:
|
||||||
log.Log(NOW, "attempting to close the plugin and release stdout and stderr")
|
log.Log(NOW, "attempting to close the plugin and release stdout and stderr")
|
||||||
standardExit()
|
standardExit()
|
||||||
case widget.Enable:
|
case widget.Enable:
|
||||||
|
|
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"errors"
|
"errors"
|
||||||
"strconv"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ func (n *node) showView() {
|
||||||
|
|
||||||
if (w.cuiName == "") {
|
if (w.cuiName == "") {
|
||||||
log.Log(ERROR, "showView() w.cuiName was not set for widget", w)
|
log.Log(ERROR, "showView() w.cuiName was not set for widget", w)
|
||||||
w.cuiName = strconv.Itoa(n.WidgetId)
|
w.cuiName = string(n.WidgetId)
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the gocui element doesn't exist, create it
|
// if the gocui element doesn't exist, create it
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
@ -15,7 +13,7 @@ func initWidget(n *node) *guiWidget {
|
||||||
w.frame = true
|
w.frame = true
|
||||||
|
|
||||||
// set the name used by gocui to the id
|
// set the name used by gocui to the id
|
||||||
w.cuiName = strconv.Itoa(n.WidgetId)
|
w.cuiName = string(n.WidgetId)
|
||||||
|
|
||||||
if n.WidgetType == widget.Root {
|
if n.WidgetType == widget.Root {
|
||||||
log.Log(INFO, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
log.Log(INFO, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
||||||
|
|
171
nocui/action.go
171
nocui/action.go
|
@ -1,152 +1,87 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
a simple function to handle widget actions
|
||||||
|
|
||||||
|
You can tie this into your toolkit here.
|
||||||
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
// "go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *node) show(b bool) {
|
func doAction(a widget.Action) {
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) enable(b bool) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) pad(at widget.ActionType) {
|
|
||||||
switch n.WidgetType {
|
|
||||||
case widget.Group:
|
|
||||||
switch at {
|
|
||||||
case widget.Margin:
|
|
||||||
// SetMargined(true)
|
|
||||||
case widget.Unmargin:
|
|
||||||
// SetMargined(false)
|
|
||||||
case widget.Pad:
|
|
||||||
// SetMargined(true)
|
|
||||||
case widget.Unpad:
|
|
||||||
// SetMargined(false)
|
|
||||||
}
|
|
||||||
case widget.Tab:
|
|
||||||
case widget.Window:
|
|
||||||
case widget.Grid:
|
|
||||||
case widget.Box:
|
|
||||||
case widget.Textbox:
|
|
||||||
log.Log(ERROR, "TODO: implement ActionType =", at)
|
|
||||||
default:
|
|
||||||
log.Log(ERROR, "TODO: implement pad() for", at)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
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)
|
|
||||||
|
|
||||||
switch p.WidgetType {
|
|
||||||
case widget.Group:
|
|
||||||
// tParent.uiGroup.SetMargined(true)
|
|
||||||
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(NOW, "tWidget.boxC =", p.progname)
|
|
||||||
log.Log(NOW, "is there a tParent parent? =", p.parent)
|
|
||||||
// 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 doAction(a *widget.Action) {
|
|
||||||
log.Log(INFO, "doAction() START a.ActionType =", a.ActionType)
|
log.Log(INFO, "doAction() START a.ActionType =", a.ActionType)
|
||||||
log.Log(INFO, "doAction() START a.ProgName =", a.ProgName)
|
log.Log(INFO, "doAction() START a.ProgName =", a.ProgName)
|
||||||
|
|
||||||
if (a.ActionType == widget.InitToolkit) {
|
if (a.ActionType == widget.ToolkitInit) {
|
||||||
// TODO: make sure to only do this once
|
|
||||||
// go uiMain.Do(func() {
|
|
||||||
// ui.Main(demoUI)
|
|
||||||
// go catchActionChannel()
|
|
||||||
// })
|
|
||||||
// try doing this on toolkit load in init()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Log(INFO, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
|
log.Log(INFO, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
|
||||||
switch a.WidgetType {
|
switch a.WidgetType {
|
||||||
case widget.Root:
|
case widget.Root:
|
||||||
me.rootNode = addNode(a)
|
me.treeRoot = me.myTree.AddNode(&a)
|
||||||
log.Log(INFO, "doAction() found rootNode")
|
log.Log(INFO, "doAction() found treeRoot")
|
||||||
return
|
|
||||||
case widget.Flag:
|
|
||||||
// flag(&a)
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
n := me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
|
|
||||||
switch a.ActionType {
|
switch a.ActionType {
|
||||||
case widget.Add:
|
case widget.Add:
|
||||||
addNode(a)
|
me.myTree.AddNode(&a)
|
||||||
case widget.Show:
|
return
|
||||||
n.show(true)
|
|
||||||
case widget.Hide:
|
|
||||||
n.show(false)
|
|
||||||
case widget.Enable:
|
|
||||||
n.enable(true)
|
|
||||||
case widget.Disable:
|
|
||||||
n.enable(false)
|
|
||||||
case widget.Get:
|
|
||||||
// n.setText(a.S)
|
|
||||||
case widget.GetText:
|
|
||||||
switch a.WidgetType {
|
|
||||||
case widget.Textbox:
|
|
||||||
a.Value = n.value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n := me.treeRoot.FindWidgetId(a.WidgetId)
|
||||||
|
if n == nil {
|
||||||
|
log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
|
||||||
|
log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
|
||||||
|
log.Warn("FindId() n == nil", a.WidgetId, a.ActionType)
|
||||||
|
log.Warn("Aaaaa!, return")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch a.ActionType {
|
||||||
|
case widget.Show:
|
||||||
|
n.State.Visable = true
|
||||||
|
case widget.Hide:
|
||||||
|
n.State.Visable = false
|
||||||
|
case widget.Enable:
|
||||||
|
n.State.Visable = true
|
||||||
|
case widget.Disable:
|
||||||
|
n.State.Visable = false
|
||||||
|
case widget.Get:
|
||||||
|
log.Warn("value =", n.State.Value)
|
||||||
|
case widget.GetText:
|
||||||
|
log.Warn("value =", n.String())
|
||||||
case widget.Set:
|
case widget.Set:
|
||||||
// n.setText(a.S)
|
n.State.Value = a.State.Value
|
||||||
case widget.SetText:
|
case widget.SetText:
|
||||||
// n.setText(a.S)
|
log.Warn("GOT TO SetText()", a.WidgetId)
|
||||||
|
log.Warn("GOT TO SetText()", a.WidgetId)
|
||||||
|
log.Warn("GOT TO SetText()", a.WidgetId)
|
||||||
|
log.Warn("GOT TO SetText()", a.WidgetId)
|
||||||
|
if n == nil {
|
||||||
|
log.Warn("HOT DIGGITY. n == nil")
|
||||||
|
}
|
||||||
|
n.State.Value = a.State.Value
|
||||||
case widget.AddText:
|
case widget.AddText:
|
||||||
// n.setText(a.S)
|
n.State.Strings = append(a.State.Strings, widget.GetString(a.State.Value))
|
||||||
case widget.Margin:
|
case widget.Margin:
|
||||||
n.pad(widget.Unmargin)
|
n.State.Pad = true
|
||||||
case widget.Unmargin:
|
case widget.Unmargin:
|
||||||
n.pad(widget.Margin)
|
n.State.Pad = false
|
||||||
case widget.Pad:
|
case widget.Pad:
|
||||||
n.pad(widget.Pad)
|
n.State.Pad = true
|
||||||
case widget.Unpad:
|
case widget.Unpad:
|
||||||
n.pad(widget.Unpad)
|
n.State.Pad = false
|
||||||
case widget.Delete:
|
case widget.Delete:
|
||||||
n.Delete()
|
log.Warn("doAction() TODO: Delete()")
|
||||||
|
// n.Delete()
|
||||||
case widget.Move:
|
case widget.Move:
|
||||||
log.Log(INFO, "doAction() attempt to move() =", a.ActionType, a.WidgetType)
|
log.Warn("doAction() TODO: Move()")
|
||||||
newParent := me.rootNode.findWidgetId(a.ParentId)
|
|
||||||
n.move(newParent)
|
|
||||||
default:
|
default:
|
||||||
log.Log(ERROR, "doAction() Unknown =", a.ActionType, a.WidgetType)
|
log.Log(ERROR, "doAction() Unknown =", a.ActionType, a.WidgetType)
|
||||||
}
|
}
|
||||||
|
|
218
nocui/common.go
218
nocui/common.go
|
@ -1,218 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
/*
|
|
||||||
These 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/log"
|
|
||||||
"go.wit.com/gui/widget"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is the channel we send user events like
|
|
||||||
// mouse clicks or keyboard events back to the program
|
|
||||||
var callback chan widget.Action
|
|
||||||
|
|
||||||
// this is the channel we get requests to make widgets
|
|
||||||
var pluginChan chan widget.Action
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
// searches the binary tree for a WidgetId
|
|
||||||
func (n *node) findWidgetId(id int) *node {
|
|
||||||
if (n == nil) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if n.WidgetId == id {
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
newN := child.findWidgetId(id)
|
|
||||||
if (newN != nil) {
|
|
||||||
return newN
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) doUserEvent() {
|
|
||||||
if (callback == nil) {
|
|
||||||
log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var a widget.Action
|
|
||||||
a.WidgetId = n.WidgetId
|
|
||||||
a.Value = n.value
|
|
||||||
a.ActionType = widget.User
|
|
||||||
log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
|
|
||||||
callback <- a
|
|
||||||
log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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) {
|
|
||||||
callback = guiCallback
|
|
||||||
}
|
|
||||||
|
|
||||||
func PluginChannel() chan widget.Action {
|
|
||||||
return pluginChan
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func convertString(val any) string {
|
|
||||||
switch v := val.(type) {
|
|
||||||
case bool:
|
|
||||||
n.B = val.(bool)
|
|
||||||
case string:
|
|
||||||
n.label = val.(string)
|
|
||||||
n.S = val.(string)
|
|
||||||
case int:
|
|
||||||
n.I = val.(int)
|
|
||||||
default:
|
|
||||||
log.Error(errors.New("Set() unknown type"), "v =", v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
// this is in common.go, do not move it
|
|
||||||
func getString(A any) string {
|
|
||||||
if A == nil {
|
|
||||||
log.Warn("getString() got nil")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
var k reflect.Kind
|
|
||||||
k = reflect.TypeOf(A).Kind()
|
|
||||||
|
|
||||||
switch k {
|
|
||||||
case reflect.Int:
|
|
||||||
var i int
|
|
||||||
i = A.(int)
|
|
||||||
return strconv.Itoa(i)
|
|
||||||
case reflect.String:
|
|
||||||
return A.(string)
|
|
||||||
case reflect.Bool:
|
|
||||||
if A.(bool) == true {
|
|
||||||
return "true"
|
|
||||||
} else {
|
|
||||||
return "false"
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
log.Warn("getString uknown kind", k, "value =", A)
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// this is in common.go, do not move it
|
|
||||||
func addNode(a *widget.Action) *node {
|
|
||||||
n := new(node)
|
|
||||||
n.WidgetType = a.WidgetType
|
|
||||||
n.WidgetId = a.WidgetId
|
|
||||||
n.ParentId = a.ParentId
|
|
||||||
|
|
||||||
n.state = a.State
|
|
||||||
|
|
||||||
// copy the data from the action message
|
|
||||||
n.progname = a.ProgName
|
|
||||||
n.value = a.Value
|
|
||||||
n.direction = a.Direction
|
|
||||||
n.strings = a.Strings
|
|
||||||
|
|
||||||
// TODO: these need to be rethought
|
|
||||||
n.X = a.X
|
|
||||||
n.Y = a.Y
|
|
||||||
n.W = a.W
|
|
||||||
n.H = a.H
|
|
||||||
n.AtW = a.AtW
|
|
||||||
n.AtH = a.AtH
|
|
||||||
|
|
||||||
// store the internal toolkit information
|
|
||||||
n.tk = initWidget(n)
|
|
||||||
// n.tk = new(guiWidget)
|
|
||||||
|
|
||||||
if (a.WidgetType == widget.Root) {
|
|
||||||
log.Log(INFO, "addNode() Root")
|
|
||||||
return n
|
|
||||||
}
|
|
||||||
|
|
||||||
if (me.rootNode.findWidgetId(a.WidgetId) != nil) {
|
|
||||||
log.Log(ERROR, "addNode() WidgetId already exists", a.WidgetId)
|
|
||||||
return me.rootNode.findWidgetId(a.WidgetId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// add this new widget on the binary tree
|
|
||||||
n.parent = me.rootNode.findWidgetId(a.ParentId)
|
|
||||||
if n.parent != nil {
|
|
||||||
n.parent.children = append(n.parent.children, n)
|
|
||||||
//w := n.tk
|
|
||||||
//w.parent = n.parent.tk
|
|
||||||
//w.parent.children = append(w.parent.children, w)
|
|
||||||
}
|
|
||||||
return n
|
|
||||||
}
|
|
|
@ -1,11 +1,13 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
import (
|
import (
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *node) doWidgetClick() {
|
func doWidgetClick(n *tree.Node) {
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case widget.Root:
|
case widget.Root:
|
||||||
// THIS IS THE BEGINING OF THE LAYOUT
|
// THIS IS THE BEGINING OF THE LAYOUT
|
||||||
|
@ -17,32 +19,33 @@ func (n *node) doWidgetClick() {
|
||||||
// rootNode.dumpTree(true)
|
// rootNode.dumpTree(true)
|
||||||
case widget.Window:
|
case widget.Window:
|
||||||
// setCurrentWindow(w)
|
// setCurrentWindow(w)
|
||||||
n.doUserEvent()
|
// n.doUserEvent()
|
||||||
case widget.Tab:
|
case widget.Tab:
|
||||||
// setCurrentTab(w)
|
// setCurrentTab(w)
|
||||||
case widget.Group:
|
case widget.Group:
|
||||||
// n.placeWidgets()
|
// n.placeWidgets()
|
||||||
// n.toggleTree()
|
// n.toggleTree()
|
||||||
case widget.Checkbox:
|
case widget.Checkbox:
|
||||||
if widget.GetBool(n.value) {
|
if n.Bool() {
|
||||||
// n.setCheckbox(false)
|
// n.setCheckbox(false)
|
||||||
} else {
|
} else {
|
||||||
// n.setCheckbox(true)
|
// n.setCheckbox(true)
|
||||||
}
|
}
|
||||||
n.doUserEvent()
|
// n.doUserEvent()
|
||||||
case widget.Grid:
|
case widget.Grid:
|
||||||
// rootNode.hideWidgets()
|
// rootNode.hideWidgets()
|
||||||
// n.placeGrid()
|
// n.placeGrid()
|
||||||
// n.showWidgets()
|
// n.showWidgets()
|
||||||
case widget.Box:
|
case widget.Box:
|
||||||
// n.showWidgetPlacement(logNow, "drawTree()")
|
// n.showWidgetPlacement(logNow, "drawTree()")
|
||||||
if widget.GetBool(n.value) {
|
if n.Bool() {
|
||||||
log.Log(NOW, "BOX IS HORIZONTAL", n.progname)
|
log.Log(NOW, "BOX IS HORIZONTAL", n.GetProgName())
|
||||||
} else {
|
} else {
|
||||||
log.Log(NOW, "BOX IS VERTICAL", n.progname)
|
log.Log(NOW, "BOX IS VERTICAL", n.GetProgName())
|
||||||
}
|
}
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
n.doUserEvent()
|
// n.doUserEvent()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -1,10 +1,3 @@
|
||||||
module go.wit.com/gui/toolkits/nocui
|
module go.wit.com/gui/toolkits/nocui
|
||||||
|
|
||||||
go 1.21.4
|
go 1.21.4
|
||||||
|
|
||||||
require (
|
|
||||||
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
|
|
||||||
|
|
10
nocui/go.sum
10
nocui/go.sum
|
@ -1,10 +0,0 @@
|
||||||
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=
|
|
|
@ -1,55 +1,24 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
|
||||||
"sync"
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/widget"
|
|
||||||
)
|
|
||||||
|
|
||||||
var muAction sync.Mutex
|
|
||||||
|
|
||||||
func catchActionChannel() {
|
|
||||||
log.Log(NOW, "catchActionChannel() START")
|
|
||||||
for {
|
|
||||||
log.Log(NOW, "catchActionChannel() for loop")
|
|
||||||
select {
|
|
||||||
case a := <-pluginChan:
|
|
||||||
log.Log(NOW, "catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
|
|
||||||
log.Log(NOW, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
muAction.Lock()
|
|
||||||
doAction(&a)
|
|
||||||
muAction.Unlock()
|
|
||||||
log.Log(NOW, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Other goroutines must use this to access the GUI
|
This is reference code for toolkit developers
|
||||||
//
|
|
||||||
// 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) {
|
|
||||||
callback = guiCallback
|
|
||||||
}
|
|
||||||
|
|
||||||
func PluginChannel() chan widget.Action {
|
The 'nocui' is a bare minimum toolkit. It's all you need
|
||||||
return pluginChan
|
to interact with the GUI
|
||||||
}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log.Log(INFO, "Init()")
|
log.Log(INFO, "Init()")
|
||||||
|
|
||||||
// andlabs = make(map[int]*andlabsT)
|
me.myTree = tree.New()
|
||||||
pluginChan = make(chan widget.Action, 1)
|
me.myTree.PluginName = "nocui"
|
||||||
|
me.myTree.ActionFromChannel = doAction
|
||||||
|
|
||||||
log.Log(NOW, "Init() start channel reciever")
|
|
||||||
go catchActionChannel()
|
|
||||||
go simpleStdin()
|
go simpleStdin()
|
||||||
log.Log(NOW, "Init() END")
|
log.Log(INFO, "Init() END")
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"fmt"
|
"fmt"
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"runtime/debug"
|
||||||
"strings"
|
"strings"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
@ -12,6 +13,15 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func simpleStdin() {
|
func simpleStdin() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Warn("nocui YAHOOOO Recovered in simpleStdin()", r)
|
||||||
|
log.Println("Recovered from panic:", r)
|
||||||
|
log.Println("Stack trace:")
|
||||||
|
debug.PrintStack()
|
||||||
|
me.myTree.DoToolkitPanic()
|
||||||
|
}
|
||||||
|
}()
|
||||||
scanner := bufio.NewScanner(os.Stdin)
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
s := scanner.Text()
|
s := scanner.Text()
|
||||||
|
@ -19,63 +29,46 @@ func simpleStdin() {
|
||||||
switch s {
|
switch s {
|
||||||
case "l":
|
case "l":
|
||||||
log.Log(NOW, "list widgets")
|
log.Log(NOW, "list widgets")
|
||||||
me.rootNode.listWidgets()
|
me.treeRoot.ListWidgets()
|
||||||
case "b":
|
case "b":
|
||||||
log.Log(NOW, "show buttons")
|
log.Log(NOW, "show buttons")
|
||||||
me.rootNode.showButtons()
|
me.treeRoot.ShowButtons()
|
||||||
|
case "g":
|
||||||
|
me.myTree.DoToolkitLoad("gocui")
|
||||||
|
case "a":
|
||||||
|
me.myTree.DoToolkitLoad("andlabs")
|
||||||
case "d":
|
case "d":
|
||||||
var a widget.Action
|
me.myTree.DoEnableDebugger()
|
||||||
a.ActionType = widget.EnableDebug
|
|
||||||
callback <- a
|
|
||||||
case "":
|
case "":
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
fmt.Println("Enter:")
|
fmt.Println("Enter:")
|
||||||
fmt.Println("'l': list all widgets")
|
fmt.Println("'l': list all widgets")
|
||||||
fmt.Println("'b': for buttons")
|
fmt.Println("'b': for buttons")
|
||||||
|
fmt.Println("'g': load gocui plugin")
|
||||||
|
fmt.Println("'a': load andlabs plugin")
|
||||||
fmt.Println("'d': enable debugging")
|
fmt.Println("'d': enable debugging")
|
||||||
default:
|
default:
|
||||||
i, _ := strconv.Atoi(s)
|
i, _ := strconv.Atoi(s)
|
||||||
log.Log(NOW, "got input:", i)
|
log.Log(NOW, "got input:", i)
|
||||||
n := me.rootNode.findWidgetId(i)
|
n := me.treeRoot.FindWidgetId(i)
|
||||||
if (n != nil) {
|
if (n != nil) {
|
||||||
n.dumpWidget("found node")
|
n.DumpWidget("found node")
|
||||||
n.doUserEvent()
|
for i, s := range n.State.Strings {
|
||||||
|
log.Warn("n.State.Strings =", i, s)
|
||||||
|
}
|
||||||
|
switch n.WidgetType {
|
||||||
|
case widget.Root:
|
||||||
|
log.Warn("this is the root widget")
|
||||||
|
case widget.Dropdown:
|
||||||
|
log.Warn("print out dropdown values here")
|
||||||
|
case widget.Button:
|
||||||
|
me.myTree.DoUserEvent(n)
|
||||||
|
case widget.Checkbox:
|
||||||
|
me.myTree.DoUserEvent(n)
|
||||||
|
default:
|
||||||
|
log.Warn("you haven't defined an event for", n.WidgetType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) showButtons() {
|
|
||||||
if n.WidgetType == widget.Button {
|
|
||||||
n.dumpWidget("Button:")
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
child.showButtons()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *node) dumpWidget(pad string) {
|
|
||||||
log.Log(NOW, "node:", pad, n.WidgetId, ",", n.WidgetType, ",", n.progname)
|
|
||||||
}
|
|
||||||
|
|
||||||
var depth int = 0
|
|
||||||
|
|
||||||
func (n *node) listWidgets() {
|
|
||||||
if (n == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
var pad string
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
pad = pad + " "
|
|
||||||
}
|
|
||||||
n.dumpWidget(pad)
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
depth += 1
|
|
||||||
child.listWidgets()
|
|
||||||
depth -= 1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/gui/toolkits/tree"
|
||||||
|
)
|
||||||
|
|
||||||
// stores the raw toolkit internals
|
// stores the raw toolkit internals
|
||||||
type guiWidget struct {
|
type guiWidget struct {
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
|
|
||||||
c int
|
c int
|
||||||
val map[int]string
|
val map[string]int
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's probably a terrible idea to call this 'me'
|
// It's probably a terrible idea to call this 'me'
|
||||||
var me config
|
var me config
|
||||||
|
|
||||||
type config struct {
|
type config struct {
|
||||||
rootNode *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
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is reference code for toolkit developers
|
||||||
|
*/
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/gui/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()
|
||||||
|
}
|
|
@ -1,30 +0,0 @@
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/widget"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is specific to the nocui toolkit
|
|
||||||
func initWidget(n *node) *guiWidget {
|
|
||||||
var w *guiWidget
|
|
||||||
w = new(guiWidget)
|
|
||||||
// Set(w, "default")
|
|
||||||
|
|
||||||
if n.WidgetType == widget.Root {
|
|
||||||
log.Log(INFO, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
|
|
||||||
n.WidgetId = 0
|
|
||||||
me.rootNode = n
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.WidgetType == widget.Box) {
|
|
||||||
if (n.direction == widget.Horizontal) {
|
|
||||||
// n.horizontal = true
|
|
||||||
} else {
|
|
||||||
// n.horizontal = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return w
|
|
||||||
}
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this is in common.go, do not move it
|
||||||
|
func (me *TreeInfo) AddNode(a *widget.Action) *Node {
|
||||||
|
n := new(Node)
|
||||||
|
n.WidgetType = a.WidgetType
|
||||||
|
n.WidgetId = a.WidgetId
|
||||||
|
n.ParentId = a.ParentId
|
||||||
|
|
||||||
|
n.State = a.State
|
||||||
|
n.Strings = make(map[string]int)
|
||||||
|
|
||||||
|
if (a.WidgetType == widget.Root) {
|
||||||
|
log.Info("AddNode() Root")
|
||||||
|
n.Parent = n
|
||||||
|
me.treeRoot = n
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
|
||||||
|
if (me.treeRoot.FindWidgetId(a.WidgetId) != nil) {
|
||||||
|
log.Warn("AddNode() WidgetId already exists", a.WidgetId)
|
||||||
|
log.Warn("probably this is a Show() / Hide() issue")
|
||||||
|
log.Warn("TODO: figure out what to do here")
|
||||||
|
return me.treeRoot.FindWidgetId(a.WidgetId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add this new widget on the binary tree
|
||||||
|
p := me.treeRoot.FindWidgetId(a.ParentId)
|
||||||
|
n.Parent = p
|
||||||
|
if n.Parent == nil {
|
||||||
|
log.Error(errors.New("tree.AddNode() ERROR n.Parent == nil"), a.WidgetId, a.ParentId, a.ActionType)
|
||||||
|
log.Warn("AddNode() ERROR n.Parent == nil", a.WidgetId, a.ParentId, a.ActionType)
|
||||||
|
log.Warn("AddNode() ERROR n.Parent == nil", a.WidgetId, a.ParentId, a.WidgetType)
|
||||||
|
return n
|
||||||
|
}
|
||||||
|
log.Warn("AddNode() Adding to parent =", p.ParentId, p.WidgetType, p.GetProgName())
|
||||||
|
log.Warn("AddNode() Adding child =", n.ParentId, n.WidgetType, n.GetProgName())
|
||||||
|
p.children = append(p.children, n)
|
||||||
|
return n
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (n *Node) GetProgName() string {
|
||||||
|
return n.State.ProgName
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetValue() any {
|
||||||
|
return n.State.Value
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Bool() bool {
|
||||||
|
return widget.GetBool(n.State.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) String() string {
|
||||||
|
return widget.GetString(n.State.Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* avoid this function name as confusing
|
||||||
|
func (n *Node) GetText() string {
|
||||||
|
return widget.GetString(n.State.Value)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func (n *Node) SetValue(a any) {
|
||||||
|
n.State.Value = a
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetLabel() string {
|
||||||
|
return n.State.Label
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (n *Node) ShowButtons() {
|
||||||
|
if n.WidgetType == widget.Button {
|
||||||
|
n.DumpWidget("Button:")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, child := range n.children {
|
||||||
|
child.ShowButtons()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) DumpWidget(pad string) {
|
||||||
|
log.Warn("node:", pad, n.WidgetId, ",", n.WidgetType, ",", n.GetProgName())
|
||||||
|
}
|
||||||
|
|
||||||
|
var depth int = 0
|
||||||
|
|
||||||
|
func (n *Node) ListWidgets() {
|
||||||
|
if (n == nil) {
|
||||||
|
log.Warn("ERRRORRRR: n == nil in ListWidgets()")
|
||||||
|
log.Warn("ERRRORRRR: n == nil in ListWidgets()")
|
||||||
|
log.Warn("ERRRORRRR: n == nil in ListWidgets()")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var pad string
|
||||||
|
for i := 0; i < depth; i++ {
|
||||||
|
pad = pad + " "
|
||||||
|
}
|
||||||
|
n.DumpWidget(pad)
|
||||||
|
|
||||||
|
for _, child := range n.children {
|
||||||
|
depth += 1
|
||||||
|
child.ListWidgets()
|
||||||
|
depth -= 1
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package tree
|
||||||
|
|
||||||
|
/*
|
||||||
|
These 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/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (me *TreeInfo) DoEnableDebugger() {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log.Warn("DoUserEvent() toolkit panic() callback == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.ActionType = widget.EnableDebug
|
||||||
|
a.ProgName = me.PluginName
|
||||||
|
me.callback <- a
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *TreeInfo) DoToolkitLoad(s string) {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log.Warn("DoUserEvent() toolkit load callback == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.ActionType = widget.ToolkitLoad
|
||||||
|
a.ProgName = me.PluginName
|
||||||
|
a.Value = s
|
||||||
|
log.Warn("DoUserEvent() START: toolkit load", s)
|
||||||
|
me.callback <- a
|
||||||
|
log.Warn("DoUserEvent() END: toolkit load", s)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *TreeInfo) DoToolkitPanic() {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log.Warn("DoUserEvent() toolkit panic() callback == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.ActionType = widget.ToolkitPanic
|
||||||
|
a.ProgName = me.PluginName
|
||||||
|
log.Info("DoUserEvent() START: toolkit panic()")
|
||||||
|
me.callback <- a
|
||||||
|
log.Info("DoUserEvent() END: toolkit panic()")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *TreeInfo) DoWindowCloseEvent(n *Node) {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log.Warn("DoUserEvent() callback == nil", n.WidgetId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.WidgetId = n.WidgetId
|
||||||
|
a.ActionType = widget.CloseWindow
|
||||||
|
log.Info("DoUserEvent() START: user closed the window", n.GetProgName())
|
||||||
|
me.callback <- a
|
||||||
|
log.Info("DoUserEvent() END: user closed the window", n.GetProgName())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other goroutines must use this to access the GUI
|
||||||
|
func (me *TreeInfo) DoUserEvent(n *Node) {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log.Warn("DoUserEvent() callback == nil", n.WidgetId)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a widget.Action
|
||||||
|
a.WidgetId = n.WidgetId
|
||||||
|
a.Value = n.State.Value
|
||||||
|
a.ActionType = widget.User
|
||||||
|
log.Info("DoUserEvent() START: send a user event to the callback channel")
|
||||||
|
me.callback <- a
|
||||||
|
log.Info("DoUserEvent() END: sent a user event to the callback channel")
|
||||||
|
return
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package tree
|
||||||
|
|
||||||
|
import (
|
||||||
|
"sync"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
var muAction sync.Mutex
|
||||||
|
|
||||||
|
func (me *TreeInfo) toolkit(a widget.Action) {
|
||||||
|
if me.ActionFromChannel == nil {
|
||||||
|
log.Error(errors.New("toolkit ActionFromChannel == nil"), a.WidgetId, a.ActionType, a.WidgetType)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
me.ActionFromChannel(a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (me *TreeInfo) catchActionChannel() {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
log.Warn("nocui YAHOOOO Recovered in simpleStdin()", r)
|
||||||
|
me.DoToolkitPanic()
|
||||||
|
panic(-1)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
log.Info("catchActionChannel() START")
|
||||||
|
for {
|
||||||
|
log.Info("catchActionChannel() for loop")
|
||||||
|
select {
|
||||||
|
case a := <-me.pluginChan:
|
||||||
|
log.Info("catchActionChannel() SELECT widget id =", a.WidgetId, a.ProgName)
|
||||||
|
log.Warn("catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
|
||||||
|
if a.WidgetType == widget.Dropdown {
|
||||||
|
log.Warn("Found dropdown", a.WidgetId, a.ActionType, a.WidgetType)
|
||||||
|
for i, s := range a.State.Strings {
|
||||||
|
log.Warn("a.State.Strings =", i, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
muAction.Lock()
|
||||||
|
me.toolkit(a)
|
||||||
|
muAction.Unlock()
|
||||||
|
log.Info("catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func New() *TreeInfo {
|
||||||
|
me := new(TreeInfo)
|
||||||
|
me.pluginChan = make(chan widget.Action, 1)
|
||||||
|
|
||||||
|
log.Info("Init() start channel reciever")
|
||||||
|
go me.catchActionChannel()
|
||||||
|
log.Info("Init() END")
|
||||||
|
return me
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package tree
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These code should be common to all gui plugins
|
These code should be common to all gui plugins
|
||||||
|
@ -12,15 +12,11 @@ package main
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
// searches the binary tree for a WidgetId
|
// searches the binary tree for a WidgetId
|
||||||
func (n *node) findWidgetId(id int) *node {
|
func (n *Node) FindWidgetId(id int) *Node {
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -30,7 +26,7 @@ func (n *node) findWidgetId(id int) *node {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, child := range n.children {
|
for _, child := range n.children {
|
||||||
newN := child.findWidgetId(id)
|
newN := child.FindWidgetId(id)
|
||||||
if (newN != nil) {
|
if (newN != nil) {
|
||||||
return newN
|
return newN
|
||||||
}
|
}
|
||||||
|
@ -38,21 +34,6 @@ func (n *node) findWidgetId(id int) *node {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *node) doUserEvent() {
|
|
||||||
if (callback == nil) {
|
|
||||||
log.Log(ERROR, "doUserEvent() callback == nil", n.WidgetId)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var a widget.Action
|
|
||||||
a.WidgetId = n.WidgetId
|
|
||||||
a.Value = n.value
|
|
||||||
a.ActionType = widget.User
|
|
||||||
log.Log(INFO, "doUserEvent() START: send a user event to the callback channel")
|
|
||||||
callback <- a
|
|
||||||
log.Log(INFO, "doUserEvent() END: sent a user event to the callback channel")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Other goroutines must use this to access the GUI
|
// Other goroutines must use this to access the GUI
|
||||||
//
|
//
|
||||||
// You can not acess / process the GUI thread directly from
|
// You can not acess / process the GUI thread directly from
|
||||||
|
@ -60,10 +41,10 @@ func (n *node) doUserEvent() {
|
||||||
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
||||||
//
|
//
|
||||||
// this sets the channel to send user events back from the plugin
|
// this sets the channel to send user events back from the plugin
|
||||||
func Callback(guiCallback chan widget.Action) {
|
func (me *TreeInfo) Callback(guiCallback chan widget.Action) {
|
||||||
callback = guiCallback
|
me.callback = guiCallback
|
||||||
}
|
}
|
||||||
|
|
||||||
func PluginChannel() chan widget.Action {
|
func (me *TreeInfo) PluginChannel() chan widget.Action {
|
||||||
return pluginChan
|
return me.pluginChan
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package tree
|
||||||
|
|
||||||
/*
|
/*
|
||||||
These code should be common to all gui plugins
|
These code should be common to all gui plugins
|
||||||
|
@ -12,23 +12,29 @@ package main
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
// "go.wit.com/log"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"go.wit.com/log"
|
|
||||||
"go.wit.com/gui/widget"
|
"go.wit.com/gui/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// var me *TreeInfo
|
||||||
|
|
||||||
|
type TreeInfo struct {
|
||||||
// this is the channel we send user events like
|
// this is the channel we send user events like
|
||||||
// mouse clicks or keyboard events back to the program
|
// mouse clicks or keyboard events back to the program
|
||||||
var callback chan widget.Action
|
callback chan widget.Action
|
||||||
|
|
||||||
// this is the channel we get requests to make widgets
|
// this is the channel we get requests to make widgets
|
||||||
var pluginChan chan widget.Action
|
pluginChan chan widget.Action
|
||||||
|
|
||||||
|
treeRoot *Node
|
||||||
|
NodeI interface {}
|
||||||
|
ActionFromChannel func (widget.Action) ()
|
||||||
|
PluginName string
|
||||||
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
parent *node
|
Parent *Node
|
||||||
children []*node
|
children []*Node
|
||||||
|
|
||||||
WidgetId int // widget ID
|
WidgetId int // widget ID
|
||||||
WidgetType widget.WidgetType
|
WidgetType widget.WidgetType
|
||||||
|
@ -36,6 +42,8 @@ type Node struct {
|
||||||
|
|
||||||
State widget.State
|
State widget.State
|
||||||
|
|
||||||
|
Strings map[string]int
|
||||||
|
|
||||||
// the internal plugin toolkit structure
|
// the internal plugin toolkit structure
|
||||||
// in the gtk plugin, it has gtk things like margin & border settings
|
// 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
|
// in the text console one, it has text console things like colors for menus & buttons
|
Loading…
Reference in New Issue