Squashed commit of the following:
all non binary tree structs are gone (almost all) Use names from https://en.wikipedia.org/wiki/Graphical_widget toolkit andlabs/ui is isolated from being accessable all direct references to andlabs are removed working dropdown widgets add debugging more buttons and windows
This commit is contained in:
parent
6286635049
commit
d28f0eb8c1
105
box.go
105
box.go
|
@ -1,105 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import "log"
|
|
||||||
import "os"
|
|
||||||
|
|
||||||
import "github.com/andlabs/ui"
|
|
||||||
import _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
func (n *Node) AddBox(axis int, name string) *Node {
|
|
||||||
newBox := new(GuiBox)
|
|
||||||
newBox.Window = n.window
|
|
||||||
newBox.Name = name
|
|
||||||
|
|
||||||
if (n.box == nil) {
|
|
||||||
n.box = newBox
|
|
||||||
}
|
|
||||||
|
|
||||||
// make a new box & a new node
|
|
||||||
newNode := n.New(name)
|
|
||||||
newNode.box = newBox
|
|
||||||
Config.counter += 1
|
|
||||||
|
|
||||||
var uiBox *ui.Box
|
|
||||||
if (axis == Xaxis) {
|
|
||||||
uiBox = ui.NewHorizontalBox()
|
|
||||||
} else {
|
|
||||||
uiBox = ui.NewVerticalBox()
|
|
||||||
}
|
|
||||||
uiBox.SetPadded(true)
|
|
||||||
newBox.UiBox = uiBox
|
|
||||||
newNode.uiBox = uiBox
|
|
||||||
|
|
||||||
n.Append(newNode)
|
|
||||||
// add(n.box, newBox)
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func HorizontalBreak(box *GuiBox) {
|
|
||||||
log.Println("VerticalSeparator added to box =", box.Name)
|
|
||||||
tmp := ui.NewHorizontalSeparator()
|
|
||||||
if (box == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (box.UiBox == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
box.UiBox.Append(tmp, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func VerticalBreak(box *GuiBox) {
|
|
||||||
log.Println("VerticalSeparator added to box =", box.Name)
|
|
||||||
tmp := ui.NewVerticalSeparator()
|
|
||||||
box.UiBox.Append(tmp, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) AddComboBox(title string, s ...string) *Node {
|
|
||||||
if (n.Toolkit == nil) {
|
|
||||||
log.Println("AddComboBox.Toolkit is nil", title, s)
|
|
||||||
n.Dump()
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
if (n.uiBox == nil) {
|
|
||||||
log.Println("AddComboBox.uiBox is nil", title, s)
|
|
||||||
n.Toolkit.Dump()
|
|
||||||
n.uiBox = n.Toolkit.GetBox()
|
|
||||||
// os.Exit(0)
|
|
||||||
// return n
|
|
||||||
}
|
|
||||||
box := n.uiBox
|
|
||||||
|
|
||||||
newNode := n.New(title)
|
|
||||||
ecbox := ui.NewEditableCombobox()
|
|
||||||
|
|
||||||
for id, name := range s {
|
|
||||||
log.Println("Adding Combobox Entry:", id, name)
|
|
||||||
ecbox.Append(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
ecbox.OnChanged(func(*ui.EditableCombobox) {
|
|
||||||
test := ecbox.Text()
|
|
||||||
log.Println("node.Name = '" + n.Name + "' text for '" + title + "' is now: '" + test + "'")
|
|
||||||
log.Println("need to call node.OnChanged() here")
|
|
||||||
if (newNode.OnChanged == nil) {
|
|
||||||
log.Println("node.OnChanged() is nil")
|
|
||||||
log.Println("need to call node.OnChanged() here", newNode.OnChanged)
|
|
||||||
newNode.Dump()
|
|
||||||
} else {
|
|
||||||
log.Println("need to call node.OnChanged() here", newNode.OnChanged)
|
|
||||||
newNode.OnChanged(newNode)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
box.Append(ecbox, false)
|
|
||||||
|
|
||||||
newNode.uiText = ecbox
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) GetText() string {
|
|
||||||
if (n.uiText == nil) {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
ecbox := n.uiText
|
|
||||||
return ecbox.Text()
|
|
||||||
}
|
|
174
button.go
174
button.go
|
@ -1,184 +1,20 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
// import "reflect"
|
|
||||||
import "github.com/andlabs/ui"
|
|
||||||
import _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
// import "github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
|
|
||||||
// This is the default mouse click handler
|
|
||||||
// Every mouse click that hasn't been assigned to
|
|
||||||
// something specific will fall into this routine
|
|
||||||
// By default, all it runs is the call back to
|
|
||||||
// the main program that is using this library
|
|
||||||
//
|
|
||||||
// This routine MUST be here as this is how the andlabs/ui works
|
|
||||||
// This is the raw routine passed to every button in andlabs libui / ui
|
|
||||||
//
|
|
||||||
// There is a []GuiButton which has all the buttons. We search
|
|
||||||
// for the button and then call the function below
|
|
||||||
//
|
|
||||||
func defaultButtonClick(button *ui.Button) {
|
|
||||||
log.Println("gui.defaultButtonClick() LOOK FOR BUTTON button =", button)
|
|
||||||
for key, foo := range Data.AllButtons {
|
|
||||||
if (Config.Debug) {
|
|
||||||
log.Println("gui.defaultButtonClick() Data.AllButtons =", key, foo)
|
|
||||||
// spew.Dump(foo)
|
|
||||||
}
|
|
||||||
if Data.AllButtons[key].B == button {
|
|
||||||
log.Println("\tgui.defaultButtonClick() BUTTON MATCHED")
|
|
||||||
guiButtonClick(Data.AllButtons[key])
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Println("\tgui.defaultButtonClick() ERROR: BUTTON NOT FOUND")
|
|
||||||
if (Config.Debug) {
|
|
||||||
panic("gui.defaultButtonClick() ERROR: UNMAPPED ui.Button")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func guiButtonClick(button *GuiButton) {
|
|
||||||
log.Println("\tgui.guiButtonClick() button.Name =", button.Name)
|
|
||||||
if button.Custom != nil {
|
|
||||||
log.Println("\tgui.guiButtonClick() DOING CUSTOM FUNCTION")
|
|
||||||
button.Custom(button)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (Data.MouseClick != nil) {
|
|
||||||
Data.MouseClick(button)
|
|
||||||
} else {
|
|
||||||
log.Println("\tgui.guiButtonClick() IGNORING BUTTON. MouseClick() is nil")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) AddButton(name string, custom func(*Node)) *Node {
|
func (n *Node) AddButton(name string, custom func(*Node)) *Node {
|
||||||
if (n.Toolkit == nil) {
|
if (n.toolkit == nil) {
|
||||||
log.Println("gui.Node.AppendButton() filed node.Toolkit == nil")
|
log.Println("gui.Node.AppendButton() filed node.toolkit == nil")
|
||||||
panic("gui.Node.AppendButton() filed node.Toolkit == nil")
|
panic("gui.Node.AppendButton() filed node.toolkit == nil")
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
button := ui.NewButton(name)
|
|
||||||
log.Println("reflect.TypeOF(uiBox) =", reflect.TypeOf(n.uiBox))
|
|
||||||
log.Println("reflect.TypeOF(uiButton) =", reflect.TypeOf(button))
|
|
||||||
n.uiBox.Append(button, false)
|
|
||||||
n.uiButton = button
|
|
||||||
*/
|
|
||||||
|
|
||||||
newNode := n.New(name)
|
newNode := n.New(name)
|
||||||
newNode.Toolkit = n.Toolkit.NewButton(name)
|
newNode.toolkit = n.toolkit.NewButton(name)
|
||||||
newNode.Toolkit.Custom = func() {
|
newNode.toolkit.Custom = func() {
|
||||||
log.Println("gui.AppendButton() Button Clicked. Running custom()")
|
log.Println("gui.AppendButton() Button Clicked. Running custom()")
|
||||||
custom(newNode)
|
custom(newNode)
|
||||||
}
|
}
|
||||||
newNode.custom = custom
|
newNode.custom = custom
|
||||||
|
|
||||||
/*
|
|
||||||
button.OnClicked(func(*ui.Button) {
|
|
||||||
log.Println("gui.AppendButton() Button Clicked. Running custom()")
|
|
||||||
custom(newNode)
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
// panic("AppendButton")
|
|
||||||
// time.Sleep(3 * time.Second)
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) CreateButton(custom func(*GuiButton), name string, values interface {}) *Node {
|
|
||||||
newNode := n.AddBox(Xaxis, "test CreateButton")
|
|
||||||
box := newNode.FindBox()
|
|
||||||
if (box == nil) {
|
|
||||||
panic("node.CreateButton().FindBox() == nil")
|
|
||||||
}
|
|
||||||
newUiB := ui.NewButton(name)
|
|
||||||
newUiB.OnClicked(defaultButtonClick)
|
|
||||||
|
|
||||||
var newB *GuiButton
|
|
||||||
newB = new(GuiButton)
|
|
||||||
newB.B = newUiB
|
|
||||||
if (box.UiBox == nil) {
|
|
||||||
log.Println("CreateButton() box.Window == nil")
|
|
||||||
// ErrorWindow(box.Window, "Login Failed", msg) // can't even do this
|
|
||||||
panic("maybe print an error and return nil? or make a fake button?")
|
|
||||||
} else {
|
|
||||||
// uibox := box.UiBox
|
|
||||||
// uibox.Append(newUiB, true)
|
|
||||||
}
|
|
||||||
newB.Box = box
|
|
||||||
newB.Custom = custom
|
|
||||||
newB.Values = values
|
|
||||||
|
|
||||||
Data.AllButtons = append(Data.AllButtons, newB)
|
|
||||||
|
|
||||||
box.Append(newB.B, false)
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) NewButton(box *GuiBox, custom func(*GuiButton), name string, values interface {}) *GuiButton {
|
|
||||||
return CreateButton(box, custom, name, values)
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateButton(box *GuiBox, custom func(*GuiButton), name string, values interface {}) *GuiButton {
|
|
||||||
newUiB := ui.NewButton(name)
|
|
||||||
newUiB.OnClicked(defaultButtonClick)
|
|
||||||
|
|
||||||
var newB *GuiButton
|
|
||||||
newB = new(GuiButton)
|
|
||||||
newB.B = newUiB
|
|
||||||
if (box.Window == nil) {
|
|
||||||
log.Println("CreateButton() box.Window == nil")
|
|
||||||
// ErrorWindow(box.Window, "Login Failed", msg) // can't even do this
|
|
||||||
panic("maybe print an error and return nil? or make a fake button?")
|
|
||||||
}
|
|
||||||
newB.Box = box
|
|
||||||
newB.Custom = custom
|
|
||||||
newB.Values = values
|
|
||||||
|
|
||||||
Data.AllButtons = append(Data.AllButtons, newB)
|
|
||||||
|
|
||||||
box.Append(newB.B, false)
|
|
||||||
return newB
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateFontButton(box *GuiBox, action string) *GuiButton {
|
|
||||||
// create a 'fake' button entry for the mouse clicks
|
|
||||||
var newGB GuiButton
|
|
||||||
newGB.Name = "FONT"
|
|
||||||
newGB.FB = ui.NewFontButton()
|
|
||||||
newGB.Box = box
|
|
||||||
Data.AllButtons = append(Data.AllButtons, &newGB)
|
|
||||||
|
|
||||||
newGB.FB.OnChanged(func (*ui.FontButton) {
|
|
||||||
log.Println("FontButton.OnChanged() START mouseClick(&newBM)", newGB)
|
|
||||||
if (Data.MouseClick != nil) {
|
|
||||||
Data.MouseClick(&newGB)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return &newGB
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateColorButton(box *GuiBox, custom func(*GuiButton), name string, values interface {}) *GuiButton {
|
|
||||||
// create a 'fake' button entry for the mouse clicks
|
|
||||||
var newCB GuiButton
|
|
||||||
newCB.Name = name
|
|
||||||
newCB.CB = ui.NewColorButton()
|
|
||||||
newCB.Box = box
|
|
||||||
newCB.Custom = custom
|
|
||||||
newCB.Values = values
|
|
||||||
|
|
||||||
Data.AllButtons = append(Data.AllButtons, &newCB)
|
|
||||||
|
|
||||||
newCB.CB.OnChanged(func (*ui.ColorButton) {
|
|
||||||
log.Println("ColorButton.OnChanged() START Color Button Click")
|
|
||||||
r, g, b, a := newCB.CB.Color()
|
|
||||||
log.Println("ColorButton.OnChanged() Color() =", r, g, b, a)
|
|
||||||
if (newCB.Custom != nil) {
|
|
||||||
newCB.Custom(&newCB)
|
|
||||||
} else if (Data.MouseClick != nil) {
|
|
||||||
Data.MouseClick(&newCB)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
box.Append(newCB.CB, false)
|
|
||||||
return &newCB
|
|
||||||
}
|
|
||||||
|
|
|
@ -32,26 +32,17 @@ func initGUI() {
|
||||||
addDemoTab(w, "A Second Tab")
|
addDemoTab(w, "A Second Tab")
|
||||||
}
|
}
|
||||||
|
|
||||||
func addDemoTab(window *gui.Node, title string) {
|
func addDemoTab(w *gui.Node, title string) {
|
||||||
var newNode, g *gui.Node
|
var newNode, g *gui.Node
|
||||||
|
|
||||||
newNode = window.AddTab(title, nil)
|
newNode = w.NewTab(title)
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
|
||||||
newNode.Dump()
|
|
||||||
newNode.Toolkit.Dump()
|
|
||||||
|
|
||||||
g = newNode.NewGroup("group 1")
|
g = newNode.NewGroup("group 1")
|
||||||
log.Println("addDemoTab() g.Dump")
|
|
||||||
log.Println("addDemoTab() g.Dump")
|
dd := g.NewDropdown("demoCombo2")
|
||||||
log.Println("addDemoTab() g.Dump")
|
dd.AddDropdown("more 1")
|
||||||
log.Println("addDemoTab() g.Dump")
|
dd.AddDropdown("less 2")
|
||||||
g.Dump()
|
dd.AddDropdown("foo 3")
|
||||||
g.Toolkit.Dump()
|
|
||||||
// myExit(nil)
|
|
||||||
g.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func myExit(n *gui.Node) {
|
func myExit(n *gui.Node) {
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
|
|
||||||
// This initializes the first window
|
// This initializes the first window
|
||||||
//
|
//
|
||||||
|
// BUG: THIS PROGRAM DOESN'T EXIT PROPERLY (NOT REALLY A BUG)
|
||||||
|
//
|
||||||
// Then starts a goroutine to demonstrate how to
|
// Then starts a goroutine to demonstrate how to
|
||||||
// inject things into the GUI
|
// inject things into the GUI
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
@ -37,13 +37,12 @@ func initGUI() {
|
||||||
func addDemoTab(window *gui.Node, title string) {
|
func addDemoTab(window *gui.Node, title string) {
|
||||||
var newNode, g *gui.Node
|
var newNode, g *gui.Node
|
||||||
|
|
||||||
newNode = window.AddTab(title, nil)
|
newNode = window.NewTab(title)
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
log.Println("addDemoTab() newNode.Dump")
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
log.Println("addDemoTab() newNode.Dump")
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
log.Println("addDemoTab() newNode.Dump")
|
||||||
log.Println("addDemoTab() newNode.Dump")
|
log.Println("addDemoTab() newNode.Dump")
|
||||||
newNode.Dump()
|
newNode.Dump()
|
||||||
newNode.Toolkit.Dump()
|
|
||||||
|
|
||||||
g = newNode.NewGroup("group 1")
|
g = newNode.NewGroup("group 1")
|
||||||
log.Println("addDemoTab() g.Dump")
|
log.Println("addDemoTab() g.Dump")
|
||||||
|
@ -51,9 +50,11 @@ func addDemoTab(window *gui.Node, title string) {
|
||||||
log.Println("addDemoTab() g.Dump")
|
log.Println("addDemoTab() g.Dump")
|
||||||
log.Println("addDemoTab() g.Dump")
|
log.Println("addDemoTab() g.Dump")
|
||||||
g.Dump()
|
g.Dump()
|
||||||
g.Toolkit.Dump()
|
|
||||||
// os.Exit(0)
|
// os.Exit(0)
|
||||||
g.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
dd := g.NewDropdown("demoCombo2")
|
||||||
|
dd.AddDropdown("more 1")
|
||||||
|
dd.AddDropdown("more 2")
|
||||||
|
dd.AddDropdown("more 3")
|
||||||
}
|
}
|
||||||
|
|
||||||
func myDefaultExit(n *gui.Node) {
|
func myDefaultExit(n *gui.Node) {
|
||||||
|
|
357
debug-window.go
357
debug-window.go
|
@ -1,357 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
// "time"
|
|
||||||
// "os"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
var names = make([]string, 100)
|
|
||||||
var nodeNames = make([]string, 100)
|
|
||||||
|
|
||||||
var bugWin *Node
|
|
||||||
/*
|
|
||||||
Creates a window helpful for debugging this package
|
|
||||||
*/
|
|
||||||
func DebugWindow() {
|
|
||||||
Config.Title = "git.wit.org/wit/gui debug fixme"
|
|
||||||
Config.Width = 300
|
|
||||||
Config.Height = 200
|
|
||||||
Config.Exit = StandardClose
|
|
||||||
bugWin = NewWindow()
|
|
||||||
bugWin.DebugTab("does this also work?")
|
|
||||||
// node.DebugTab("WIT GUI Debug Tab")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove this crap
|
|
||||||
// What does this actually do?
|
|
||||||
// It populates the nodeNames in a map. No, not a map, an array.
|
|
||||||
// What is the difference again? (other than one being in order and a predefined length)
|
|
||||||
func addNodeNameBAD(c *ui.Combobox, s string, id string) {
|
|
||||||
c.Append(s)
|
|
||||||
// nodeNames[y] = id
|
|
||||||
// y = y + 1
|
|
||||||
log.Println("addNodeName:", s)
|
|
||||||
// time.Sleep(1 * time.Second)
|
|
||||||
// os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeWindowDebug() *ui.Box {
|
|
||||||
hbox := ui.NewHorizontalBox()
|
|
||||||
hbox.SetPadded(true)
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
vbox := addGroup(hbox, "range Data.WindowMap")
|
|
||||||
cbox := ui.NewCombobox()
|
|
||||||
|
|
||||||
for name, _ := range Data.WindowMap {
|
|
||||||
if (Config.Debug) {
|
|
||||||
log.Println("range Data.WindowMap() name =", name)
|
|
||||||
}
|
|
||||||
addNameBAD(cbox, name)
|
|
||||||
}
|
|
||||||
cbox.SetSelected(0)
|
|
||||||
|
|
||||||
vbox.Append(cbox, false)
|
|
||||||
|
|
||||||
cbox.OnSelected(func(*ui.Combobox) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("names[x] =", names[x])
|
|
||||||
dumpBox(names[x])
|
|
||||||
})
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
vbox = addGroup(hbox, "Debug Window")
|
|
||||||
|
|
||||||
b1 := addButton(vbox, "dumpBox(window)")
|
|
||||||
b1.OnClicked(func(*ui.Button) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("names[x] =", names[x])
|
|
||||||
dumpBox(names[x])
|
|
||||||
})
|
|
||||||
|
|
||||||
b2 := addButton(vbox, "SetMargined(tab)")
|
|
||||||
b2.OnClicked(func(*ui.Button) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("FindWindow; names[x] =", names[x])
|
|
||||||
gw := FindWindow(names[x])
|
|
||||||
if gw == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.UiTab == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.TabNumber == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
|
||||||
scs.Dump(gw)
|
|
||||||
log.Println("gui.dumpBoxes()\tWindow.UiTab =", gw.UiTab)
|
|
||||||
log.Println("gui.dumpBoxes()\tWindow.TabNumber =", *gw.TabNumber)
|
|
||||||
gw.UiTab.SetMargined(*gw.TabNumber, true)
|
|
||||||
})
|
|
||||||
|
|
||||||
b3 := addButton(vbox, "Hide(tab)")
|
|
||||||
b3.OnClicked(func(*ui.Button) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("FindWindow; names[x] =", names[x])
|
|
||||||
gw := FindWindow(names[x])
|
|
||||||
if gw == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.UiTab == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
gw.UiTab.Hide()
|
|
||||||
})
|
|
||||||
|
|
||||||
b4 := addButton(vbox, "Show(tab)")
|
|
||||||
b4.OnClicked(func(*ui.Button) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("FindWindow; names[x] =", names[x])
|
|
||||||
gw := FindWindow(names[x])
|
|
||||||
if gw == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.UiTab == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
gw.UiTab.Show()
|
|
||||||
})
|
|
||||||
|
|
||||||
b5 := addButton(vbox, "Delete(tab)")
|
|
||||||
b5.OnClicked(func(*ui.Button) {
|
|
||||||
x := cbox.Selected()
|
|
||||||
log.Println("x =", x)
|
|
||||||
log.Println("FindWindow; names[x] =", names[x])
|
|
||||||
gw := FindWindow(names[x])
|
|
||||||
if gw == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.UiTab == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if gw.TabNumber == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
gw.UiTab.Delete(*gw.TabNumber)
|
|
||||||
})
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
vbox = addGroup(hbox, "Global Debug")
|
|
||||||
|
|
||||||
dump3 := addButton(vbox, "Dump Windows")
|
|
||||||
dump3.OnClicked(func(*ui.Button) {
|
|
||||||
dumpWindows()
|
|
||||||
})
|
|
||||||
|
|
||||||
dump2 := addButton(vbox, "Dump Boxes")
|
|
||||||
dump2.OnClicked(func(*ui.Button) {
|
|
||||||
dumpBoxes()
|
|
||||||
})
|
|
||||||
|
|
||||||
dump1 := addButton(vbox, "Dump MAP")
|
|
||||||
dump1.OnClicked(func(*ui.Button) {
|
|
||||||
dumpMap()
|
|
||||||
})
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
nodeBox := addGroup(hbox, "Windows:")
|
|
||||||
nodeCombo := ui.NewCombobox()
|
|
||||||
|
|
||||||
for name, node := range Data.NodeMap {
|
|
||||||
// if (Config.Debug) {
|
|
||||||
log.Println("range Data.NodeMap() name =", name)
|
|
||||||
// }
|
|
||||||
tmp := node.id + " (" + name + ")"
|
|
||||||
addNodeNameBAD(nodeCombo, tmp, node.id)
|
|
||||||
}
|
|
||||||
// scs := spew.ConfigState{MaxDepth: 1}
|
|
||||||
// scs.Dump(Data.NodeMap)
|
|
||||||
// os.Exit(0)
|
|
||||||
nodeCombo.SetSelected(0)
|
|
||||||
|
|
||||||
nodeBox.Append(nodeCombo, false)
|
|
||||||
|
|
||||||
nodeCombo.OnSelected(func(*ui.Combobox) {
|
|
||||||
y := nodeCombo.Selected()
|
|
||||||
log.Println("y =", y)
|
|
||||||
log.Println("nodeNames[y] =", nodeNames[y])
|
|
||||||
node := Data.findId(nodeNames[y])
|
|
||||||
if (node != nil) {
|
|
||||||
node.Dump()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////
|
|
||||||
vbox = addGroup(hbox, "Node Debug")
|
|
||||||
|
|
||||||
n1 := addButton(vbox, "Data.DumpNodeMap()")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
Data.DumpNodeMap()
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Data.ListChildren(false)")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
Data.ListChildren(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Data.ListChildren(true)")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
Data.ListChildren(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Node.Dump()")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
y := nodeCombo.Selected()
|
|
||||||
log.Println("y =", y)
|
|
||||||
log.Println("nodeNames[y] =", nodeNames[y])
|
|
||||||
node := Data.findId(nodeNames[y])
|
|
||||||
if (node != nil) {
|
|
||||||
node.Dump()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Node.ListChildren(false)")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
y := nodeCombo.Selected()
|
|
||||||
log.Println("y =", y)
|
|
||||||
log.Println("nodeNames[y] =", nodeNames[y])
|
|
||||||
node := Data.findId(nodeNames[y])
|
|
||||||
if (node != nil) {
|
|
||||||
node.ListChildren(false)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Node.ListChildren(true)")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
y := nodeCombo.Selected()
|
|
||||||
log.Println("y =", y)
|
|
||||||
log.Println("nodeNames[y] =", nodeNames[y])
|
|
||||||
node := Data.findId(nodeNames[y])
|
|
||||||
if (node != nil) {
|
|
||||||
node.ListChildren(true)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
n1 = addButton(vbox, "Node.AddDebugTab")
|
|
||||||
n1.OnClicked(func(*ui.Button) {
|
|
||||||
y := nodeCombo.Selected()
|
|
||||||
log.Println("y =", y)
|
|
||||||
log.Println("nodeNames[y] =", nodeNames[y])
|
|
||||||
node := Data.findId(nodeNames[y])
|
|
||||||
if (node != nil) {
|
|
||||||
node.DebugTab("added this DebugTab")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return hbox
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: remove this crap
|
|
||||||
// var x int = 0
|
|
||||||
// var y int = 0
|
|
||||||
|
|
||||||
// TODO: remove this crap
|
|
||||||
func addNameBAD(c *ui.Combobox, s string) {
|
|
||||||
c.Append(s)
|
|
||||||
// names[x] = s
|
|
||||||
// x = x + 1
|
|
||||||
log.Println("addName:", s)
|
|
||||||
// time.Sleep(1 * time.Second)
|
|
||||||
// os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func addGroup(b *ui.Box, name string) *ui.Box {
|
|
||||||
group := ui.NewGroup(name)
|
|
||||||
group.SetMargined(true)
|
|
||||||
b.Append(group, true)
|
|
||||||
|
|
||||||
vbox := ui.NewVerticalBox()
|
|
||||||
vbox.SetPadded(true)
|
|
||||||
group.SetChild(vbox)
|
|
||||||
|
|
||||||
return vbox
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpBox(s string) {
|
|
||||||
var name string
|
|
||||||
var window *GuiWindow
|
|
||||||
|
|
||||||
for name, window = range Data.WindowMap {
|
|
||||||
if name != s {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Println("gui.DumpBoxes() MAP: ", name)
|
|
||||||
if window.TabNumber == nil {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber = nil")
|
|
||||||
} else {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber =", *window.TabNumber)
|
|
||||||
}
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.name =", window.Name)
|
|
||||||
// log.Println("gui.DumpBoxes()\tWindow.UiWindow type =", reflect.TypeOf(window.UiWindow))
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiWindow =", window.UiWindow)
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiTab =", window.UiTab)
|
|
||||||
log.Println("gui.dumpBox() BoxMap START")
|
|
||||||
for name, abox := range window.BoxMap {
|
|
||||||
log.Printf("gui.DumpBoxes() \tBOX mapname=%-12s abox.Name=%-12s", name, abox.Name)
|
|
||||||
abox.Dump()
|
|
||||||
if name == "MAINBOX" {
|
|
||||||
if Config.Debug {
|
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
|
||||||
scs.Dump(abox.UiBox)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Println("gui.dumpBox() BoxMap END")
|
|
||||||
if window.UiTab != nil {
|
|
||||||
pages := window.UiTab.NumPages()
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiTab.NumPages() =", pages)
|
|
||||||
// fixme: tabSetMargined(window.UiTab)
|
|
||||||
if Config.Debug {
|
|
||||||
scs := spew.ConfigState{MaxDepth: 2}
|
|
||||||
scs.Dump(window.UiTab)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func addButton(box *ui.Box, name string) *ui.Button {
|
|
||||||
button := ui.NewButton(name)
|
|
||||||
|
|
||||||
button.OnClicked(func(*ui.Button) {
|
|
||||||
log.Println("Should do something here")
|
|
||||||
})
|
|
||||||
|
|
||||||
box.Append(button, false)
|
|
||||||
return button
|
|
||||||
}
|
|
||||||
|
|
||||||
func DebugTab() {
|
|
||||||
bugWin.DebugTab("does this work?")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) DebugTab(title string) *Node {
|
|
||||||
var newN *Node
|
|
||||||
var b *ui.Box
|
|
||||||
// var uiBox *ui.Box
|
|
||||||
|
|
||||||
// time.Sleep(1 * time.Second)
|
|
||||||
newN = n.AddTabNew(title + " fix makeWindowDebug")
|
|
||||||
newN.Toolkit.Dump()
|
|
||||||
b = makeWindowDebug()
|
|
||||||
newN.Toolkit.SetTabBox(b)
|
|
||||||
// FIXME: make sure this is getting run to add padding: tabSetMargined(newN.uiTab)
|
|
||||||
// os.Exit(0)
|
|
||||||
|
|
||||||
return newN
|
|
||||||
}
|
|
162
debug.go
162
debug.go
|
@ -1,162 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
// WatchGUI() opens a goroutine
|
|
||||||
//
|
|
||||||
// From that goroutine, it dumps out debugging information every 4 seconds
|
|
||||||
/*
|
|
||||||
TODO: add configuration triggers on what to dump out
|
|
||||||
TODO: allow this to be sent to /var/log, syslogd, systemd's journalctl, etc
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
func watchGUI() {
|
|
||||||
count := 0
|
|
||||||
|
|
||||||
for {
|
|
||||||
if count > 20 {
|
|
||||||
log.Println("Sleep() in watchGUI()")
|
|
||||||
if Config.Debug {
|
|
||||||
dumpBoxes()
|
|
||||||
}
|
|
||||||
count = 0
|
|
||||||
}
|
|
||||||
count += 1
|
|
||||||
time.Sleep(200 * time.Millisecond)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func dumpWindows() {
|
|
||||||
for name, _ := range Data.WindowMap {
|
|
||||||
log.Println("gui.DumpWindows() window =", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpMap() {
|
|
||||||
for name, window := range Data.WindowMap {
|
|
||||||
log.Println("gui.DumpBoxes() MAP: ", name)
|
|
||||||
log.Println("gui.DumpBoxes() BOXES:", name)
|
|
||||||
for name, abox := range window.BoxMap {
|
|
||||||
log.Printf("gui.DumpBoxes() \tBOX mapname=%-12s abox.Name=%-12s", name, abox.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpBoxes() {
|
|
||||||
for name, window := range Data.WindowMap {
|
|
||||||
log.Println("gui.DumpBoxes() MAP: ", name)
|
|
||||||
if window.TabNumber == nil {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber = nil")
|
|
||||||
} else {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber =", *window.TabNumber)
|
|
||||||
}
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.name =", window.Name)
|
|
||||||
// log.Println("gui.DumpBoxes()\tWindow.UiWindow type =", reflect.TypeOf(window.UiWindow))
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiWindow =", window.UiWindow)
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiTab =", window.UiTab)
|
|
||||||
for name, abox := range window.BoxMap {
|
|
||||||
log.Printf("gui.DumpBoxes() \tBOX mapname=%-12s abox.Name=%-12s", name, abox.Name)
|
|
||||||
if name == "MAINBOX" {
|
|
||||||
if Config.Debug {
|
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
|
||||||
scs.Dump(abox.UiBox)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if window.UiTab != nil {
|
|
||||||
// log.Println("gui.DumpBoxes()\tWindow.UiTab type =", reflect.TypeOf(window.UiTab))
|
|
||||||
// log.Println("gui.DumpBoxes()\tWindow.UiTab =", window.UiTab)
|
|
||||||
pages := window.UiTab.NumPages()
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.UiTab.NumPages() =", pages)
|
|
||||||
// for i := 0; i < pages; i++ {
|
|
||||||
// log.Println("gui.DumpBoxes()\t\tWindow.UiTab.Margined(", i, ") =", window.UiTab.Margined(i))
|
|
||||||
// }
|
|
||||||
// tmp := spew.NewDefaultConfig()
|
|
||||||
// tmp.MaxDepth = 2
|
|
||||||
// tmp.Dump(window.UiTab)
|
|
||||||
if Config.Debug {
|
|
||||||
scs := spew.ConfigState{MaxDepth: 2}
|
|
||||||
scs.Dump(window.UiTab)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
for i, window := range Data.Windows {
|
|
||||||
if (window.TabNumber == nil) {
|
|
||||||
log.Println("gui.DumpBoxes() Data.Windows", i, "Name =", window.Name, "TabNumber = nil")
|
|
||||||
} else {
|
|
||||||
log.Println("gui.DumpBoxes() Data.Windows", i, "Name =", window.Name, "TabNumber =", *window.TabNumber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
func addTableTab() {
|
|
||||||
var parts []TableColumnData
|
|
||||||
|
|
||||||
for key, foo := range []string{"BG", "TEXTCOLOR", "BUTTON", "TEXTCOLOR", "TEXTCOLOR", "TEXT", "BUTTON", "TEXT", "BUTTON"} {
|
|
||||||
log.Println(key, foo)
|
|
||||||
|
|
||||||
var b TableColumnData
|
|
||||||
b.CellType = foo
|
|
||||||
b.Heading = fmt.Sprintf("heading%d", key)
|
|
||||||
parts = append(parts, b)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Sleep for 1 second, then try to add new tabs")
|
|
||||||
time.Sleep(1 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dn *GuiData) DumpNodeMap() {
|
|
||||||
log.Println("DebugDataNodeMap():")
|
|
||||||
for name, node := range dn.NodeMap {
|
|
||||||
log.Println("\tNode =", node.id, node.Width, node.Height, name)
|
|
||||||
if (node.children == nil) {
|
|
||||||
log.Println("\t\tNo children")
|
|
||||||
} else {
|
|
||||||
log.Println("\t\tHas children:", node.children)
|
|
||||||
}
|
|
||||||
// node.SetName("yahoo")
|
|
||||||
// log.Println("\tData.NodeMap node =", node)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
func DebugDataNodeChildren() {
|
|
||||||
if Data.NodeMap == nil {
|
|
||||||
log.Println("DebugDataNodeChildren() NodeMap == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Println("DebugDataNodeChildren():")
|
|
||||||
for name, node := range Data.NodeMap {
|
|
||||||
log.Println("\tNode name =", node.Width, node.Height, name)
|
|
||||||
if (node.children == nil) {
|
|
||||||
log.Println("\t\tNo children")
|
|
||||||
break
|
|
||||||
}
|
|
||||||
log.Println("\t\tHas children:", node.children)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func (dn *GuiData) ListChildren(dump bool) {
|
|
||||||
if Data.NodeMap == nil {
|
|
||||||
log.Println("gui.Data.ListChildren() Data.NodeMap == nil")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Println("gui.Data.ListChildren() Data.NodeMap:")
|
|
||||||
for name, node := range Data.NodeMap {
|
|
||||||
log.Println("\tgui.Data.ListChildren() node =", node.id, node.Width, node.Height, name)
|
|
||||||
if (dump == true) {
|
|
||||||
node.Dump()
|
|
||||||
}
|
|
||||||
node.ListChildren(dump)
|
|
||||||
}
|
|
||||||
}
|
|
1
doc.go
1
doc.go
|
@ -17,6 +17,7 @@ Principles:
|
||||||
* It's ok to guess. We will return something close.
|
* It's ok to guess. We will return something close.
|
||||||
* Hide complexity internally here
|
* Hide complexity internally here
|
||||||
* Isolate the GUI toolkit
|
* Isolate the GUI toolkit
|
||||||
|
* Function names should follow https://en.wikipedia.org/wiki/Graphical_widget
|
||||||
|
|
||||||
Quick Start
|
Quick Start
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
|
func (n *Node) NewDropdown(name string) *Node {
|
||||||
|
var newT *toolkit.Toolkit
|
||||||
|
var sNode *Node
|
||||||
|
|
||||||
|
log.Println("toolkit.NewDropdown() START", name)
|
||||||
|
|
||||||
|
// make this generic
|
||||||
|
if (n.toolkit == nil) {
|
||||||
|
log.Println("toolkit.NewSlider() toolkit == nil")
|
||||||
|
panic("toolkit should never be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
sNode = n.New(name + " part1")
|
||||||
|
newT = n.toolkit.NewDropdown(name)
|
||||||
|
newT.Name = name
|
||||||
|
sNode.custom = n.custom
|
||||||
|
newT.Custom = func () {
|
||||||
|
// TODO: make all of this common code to all the widgets
|
||||||
|
if (n.custom == nil) {
|
||||||
|
log.Println("Not Running n.custom(n) == nil")
|
||||||
|
} else {
|
||||||
|
log.Println("Running n.custom(n)")
|
||||||
|
sNode.custom(sNode)
|
||||||
|
}
|
||||||
|
if (sNode.OnChanged == nil) {
|
||||||
|
log.Println("Not Running n.OnChanged(n) == nil")
|
||||||
|
} else {
|
||||||
|
log.Println("Running n.OnChanged(n)")
|
||||||
|
sNode.OnChanged(sNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sNode.toolkit = newT
|
||||||
|
sNode.Dump()
|
||||||
|
sNode.toolkit.Dump()
|
||||||
|
// panic("checking Custom()")
|
||||||
|
|
||||||
|
return sNode
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) AddDropdown(name string) {
|
||||||
|
n.toolkit.AddDropdown(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) SetDropdown(i int) {
|
||||||
|
n.toolkit.SetDropdown(i)
|
||||||
|
}
|
156
find.go
156
find.go
|
@ -1,156 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
// "github.com/davecgh/go-spew/spew"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *Node) FindTab() *ui.Tab {
|
|
||||||
return n.uiTab
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) FindControl() *ui.Control {
|
|
||||||
return n.uiControl
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) FindBox() *GuiBox {
|
|
||||||
if (n.box != nil) {
|
|
||||||
return n.box
|
|
||||||
}
|
|
||||||
if (n.parent != nil) {
|
|
||||||
p := n.parent
|
|
||||||
return p.box
|
|
||||||
}
|
|
||||||
return n.box
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) FindWindowBox() *GuiBox {
|
|
||||||
if (n.box == nil) {
|
|
||||||
panic("SERIOUS ERROR n.box == nil in FindWindowBox()")
|
|
||||||
}
|
|
||||||
return n.box
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *GuiWindow) FindNode() *Node {
|
|
||||||
return w.node
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *GuiBox) FindNode() *Node {
|
|
||||||
log.Println("gui.FindNode() on GuiBox")
|
|
||||||
if b.node != nil {
|
|
||||||
return b.node
|
|
||||||
}
|
|
||||||
Data.ListChildren(true)
|
|
||||||
b.Dump()
|
|
||||||
log.Println("gui.FindNode() on GuiBox is nil")
|
|
||||||
os.Exit(-1)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindWindow(s string) *GuiWindow {
|
|
||||||
for name, window := range Data.WindowMap {
|
|
||||||
if name == s {
|
|
||||||
return window
|
|
||||||
}
|
|
||||||
}
|
|
||||||
log.Printf("COULD NOT FIND WINDOW " + s)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindBox(s string) *GuiBox {
|
|
||||||
for name, window := range Data.WindowMap {
|
|
||||||
if name != s {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for name, abox := range window.BoxMap {
|
|
||||||
log.Printf("gui.DumpBoxes() \tBOX mapname=%-12s abox.Name=%-12s", name, abox.Name)
|
|
||||||
return abox
|
|
||||||
}
|
|
||||||
log.Println("gui.FindBox() NEED TO INIT WINDOW name =", name)
|
|
||||||
}
|
|
||||||
log.Println("gui.FindBox() COULD NOT FIND BOX", s)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func FindNode(name string) *Node {
|
|
||||||
if Data.NodeMap == nil {
|
|
||||||
log.Println("gui.FindNode() gui.Data.NodeMap == nil")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
log.Println("gui.FindNode() searching Data.NodeMap:")
|
|
||||||
for id, node := range Data.NodeMap {
|
|
||||||
log.Println("\tData.NodeMap name =", node.Width, node.Height, id)
|
|
||||||
node.Dump()
|
|
||||||
if (name == node.Name) {
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
newNode := findByName(node, name)
|
|
||||||
if (newNode != nil) {
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
log.Println("gui.FindNode() could not find node name =", name)
|
|
||||||
os.Exit(-1)
|
|
||||||
}
|
|
||||||
log.Println("gui.FindNode() could not find node name =", name)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dn *GuiData) findId(id string) *Node {
|
|
||||||
if Data.NodeMap == nil {
|
|
||||||
log.Println("gui.Data.findId() map == nil")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
// log.Println("Dumping Data.NodeMap:")
|
|
||||||
for name, node := range Data.NodeMap {
|
|
||||||
// log.Println("\tData.NodeMap name =", node.id, node.Width, node.Height, name)
|
|
||||||
if (id == node.id) {
|
|
||||||
log.Println("\tgui.Data.findId() found node =", node.id, node.Width, node.Height, name)
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
// TODO: fix // Oct 9
|
|
||||||
// node.findId(id)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findByIdDFS(node *Node, id string) *Node {
|
|
||||||
log.Println("findByIdDFS()", id, node)
|
|
||||||
node.Dump()
|
|
||||||
if node.id == id {
|
|
||||||
log.Println("Found node id =", id, node)
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(node.children) > 0 {
|
|
||||||
for _, child := range node.children {
|
|
||||||
newNode := findByIdDFS(child, id)
|
|
||||||
if (newNode != nil) {
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findByName(node *Node, name string) *Node {
|
|
||||||
log.Println("findByName()", name, node)
|
|
||||||
node.Dump()
|
|
||||||
if node.Name == name {
|
|
||||||
log.Println("findByName() Found node name =", name, node)
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(node.children) > 0 {
|
|
||||||
for _, child := range node.children {
|
|
||||||
newNode := findByName(child, name)
|
|
||||||
if (newNode != nil) {
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
12
group.go
12
group.go
|
@ -11,15 +11,15 @@ func (n *Node) NewGroup(name string) *Node {
|
||||||
var gNode *Node
|
var gNode *Node
|
||||||
log.Println("toolkit.NewGroup() START", name)
|
log.Println("toolkit.NewGroup() START", name)
|
||||||
|
|
||||||
if (n.Toolkit == nil) {
|
if (n.toolkit == nil) {
|
||||||
log.Println("toolkit.NewGroup() Toolkit == nil")
|
log.Println("toolkit.NewGroup() toolkit == nil")
|
||||||
panic("Toolkit should never be nil")
|
panic("toolkit should never be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a *Node with a *toolkit.Group
|
// make a *Node with a *toolkit.Group
|
||||||
gNode = n.New(name + " part1")
|
gNode = n.New(name + " part1")
|
||||||
newT = n.Toolkit.NewGroup(name)
|
newT = n.toolkit.NewGroup(name)
|
||||||
gNode.Toolkit = newT
|
gNode.toolkit = newT
|
||||||
log.Println("################## gNode ####### ", name)
|
log.Println("################## gNode ####### ", name)
|
||||||
gNode.Dump()
|
gNode.Dump()
|
||||||
|
|
||||||
|
@ -27,5 +27,5 @@ func (n *Node) NewGroup(name string) *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) AddGroup(title string) *Node {
|
func (n *Node) AddGroup(title string) *Node {
|
||||||
return n.NewGroup(title + "deprecated AddGroup")
|
return n.NewGroup(title + " deprecated AddGroup")
|
||||||
}
|
}
|
||||||
|
|
70
gui.go
70
gui.go
|
@ -1,70 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/andlabs/ui" // import "time"
|
|
||||||
"log"
|
|
||||||
"regexp"
|
|
||||||
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
|
||||||
|
|
||||||
// the _ means we only need this for the init()
|
|
||||||
|
|
||||||
const Xaxis = 0 // box that is horizontal
|
|
||||||
const Yaxis = 1 // box that is vertical
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.Println("gui.init() has been run")
|
|
||||||
|
|
||||||
Data.buttonMap = make(map[*ui.Button]*GuiButton)
|
|
||||||
Data.WindowMap = make(map[string]*GuiWindow)
|
|
||||||
Data.NodeMap = make(map[string]*Node)
|
|
||||||
|
|
||||||
Data.NodeSlice = make([]*Node, 0)
|
|
||||||
|
|
||||||
Config.counter = 0
|
|
||||||
Config.prefix = "wit"
|
|
||||||
Config.DebugNode = false
|
|
||||||
Config.DebugTabs = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func GuiInit() {
|
|
||||||
ui.OnShouldQuit(func() bool {
|
|
||||||
ui.Quit()
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
// string handling examples that might be helpful for normalizeInt()
|
|
||||||
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
|
||||||
|
|
||||||
for _, username := range []string{"userone", "user2", "user-three"} {
|
|
||||||
if !isAlpha(username) {
|
|
||||||
fmt.Printf("%q is not valid\n", username)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const alpha = "abcdefghijklmnopqrstuvwxyz"
|
|
||||||
|
|
||||||
func alphaOnly(s string) bool {
|
|
||||||
for _, char := range s {
|
|
||||||
if !strings.Contains(alpha, strings.ToLower(string(char))) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func normalizeInt(s string) string {
|
|
||||||
// reg, err := regexp.Compile("[^a-zA-Z0-9]+")
|
|
||||||
reg, err := regexp.Compile("[^0-9]+")
|
|
||||||
if err != nil {
|
|
||||||
log.Println("normalizeInt() regexp.Compile() ERROR =", err)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
clean := reg.ReplaceAllString(s, "")
|
|
||||||
log.Println("normalizeInt() s =", clean)
|
|
||||||
return clean
|
|
||||||
}
|
|
10
int.go
10
int.go
|
@ -20,12 +20,12 @@ func (n *Node) Int() int {
|
||||||
scs.Dump(n)
|
scs.Dump(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n.Toolkit == nil) {
|
if (n.toolkit == nil) {
|
||||||
log.Println("gui.Node.Int() for toolkit struct = nil")
|
log.Println("gui.Node.Int() for toolkit struct = nil")
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
i := n.Toolkit.Value()
|
i := n.toolkit.Value()
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,11 @@ func (n *Node) Value() int {
|
||||||
|
|
||||||
func (n *Node) SetValue(i int) {
|
func (n *Node) SetValue(i int) {
|
||||||
log.Println("gui.SetValue() START")
|
log.Println("gui.SetValue() START")
|
||||||
if (n.Toolkit == nil) {
|
if (n.toolkit == nil) {
|
||||||
log.Println("gui.Node.SetValue() for toolkit struct = nil")
|
log.Println("gui.Node.SetValue() for toolkit struct = nil")
|
||||||
panic("SetValue failed")
|
panic("SetValue failed")
|
||||||
}
|
}
|
||||||
n.Dump()
|
n.Dump()
|
||||||
n.Toolkit.Dump()
|
n.toolkit.Dump()
|
||||||
n.Toolkit.SetValue(i)
|
n.toolkit.SetValue(i)
|
||||||
}
|
}
|
||||||
|
|
46
main.go
46
main.go
|
@ -2,14 +2,38 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
|
|
||||||
|
// the _ means we only need this for the init()
|
||||||
|
|
||||||
|
const Xaxis = 0 // box that is horizontal
|
||||||
|
const Yaxis = 1 // box that is vertical
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.Println("gui.init() has been run")
|
||||||
|
|
||||||
|
Config.counter = 0
|
||||||
|
Config.prefix = "wit"
|
||||||
|
Config.DebugNode = false
|
||||||
|
Config.DebugTabs = false
|
||||||
|
|
||||||
|
title := "master"
|
||||||
|
w := 640
|
||||||
|
h := 480
|
||||||
|
f := StandardClose
|
||||||
|
|
||||||
|
Config.master = addNode(title, w, h)
|
||||||
|
Config.master.custom = f
|
||||||
|
|
||||||
|
Config.master.Dump()
|
||||||
|
}
|
||||||
|
|
||||||
func Main(f func()) {
|
func Main(f func()) {
|
||||||
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||||
ui.Main(f)
|
toolkit.Main(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Other goroutines must use this to access the GUI
|
// Other goroutines must use this to access the GUI
|
||||||
|
@ -17,18 +41,8 @@ func Main(f func()) {
|
||||||
// You can not acess / process the GUI thread directly from
|
// You can not acess / process the GUI thread directly from
|
||||||
// other goroutines. This is due to the nature of how
|
// other goroutines. This is due to the nature of how
|
||||||
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
||||||
// For example: gui.Queue(addNewTabForColorSelection())
|
// For example: gui.Queue(NewWindow())
|
||||||
func Queue(f func()) {
|
func Queue(f func()) {
|
||||||
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
||||||
ui.QueueMain(f)
|
toolkit.Queue(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
func ExampleWindow() {
|
|
||||||
log.Println("START gui.ExampleWindow()")
|
|
||||||
|
|
||||||
Config.Title = "ExampleWindow"
|
|
||||||
node := NewWindow()
|
|
||||||
node.AddDebugTab("jcarr Debug")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
241
new-structs.go
241
new-structs.go
|
@ -1,241 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
|
|
||||||
// "github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|
||||||
|
|
||||||
type Element int
|
|
||||||
|
|
||||||
// https://ieftimov.com/post/golang-datastructures-trees/
|
|
||||||
const (
|
|
||||||
Unknown Element = iota
|
|
||||||
Window
|
|
||||||
Tab
|
|
||||||
Box
|
|
||||||
Label
|
|
||||||
Combo
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Element) String() string {
|
|
||||||
switch s {
|
|
||||||
case Window:
|
|
||||||
return "window"
|
|
||||||
case Tab:
|
|
||||||
return "tab"
|
|
||||||
case Box:
|
|
||||||
return "box"
|
|
||||||
case Label:
|
|
||||||
return "label"
|
|
||||||
case Combo:
|
|
||||||
return "combo"
|
|
||||||
}
|
|
||||||
return "unknown"
|
|
||||||
}
|
|
||||||
|
|
||||||
// The Node is simply the name and the size of whatever GUI element exists
|
|
||||||
type Node struct {
|
|
||||||
id string
|
|
||||||
|
|
||||||
Name string
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
|
|
||||||
parent *Node
|
|
||||||
children []*Node
|
|
||||||
|
|
||||||
window *GuiWindow
|
|
||||||
box *GuiBox
|
|
||||||
custom func(*Node)
|
|
||||||
OnChanged func(*Node)
|
|
||||||
|
|
||||||
Toolkit *toolkit.Toolkit
|
|
||||||
|
|
||||||
uiControl *ui.Control
|
|
||||||
uiButton *ui.Button
|
|
||||||
uiGroup *ui.Group
|
|
||||||
uiSlider *ui.Slider
|
|
||||||
uiSpinbox *ui.Spinbox
|
|
||||||
uiWindow *ui.Window
|
|
||||||
uiTab *ui.Tab
|
|
||||||
uiBox *ui.Box
|
|
||||||
uiText *ui.EditableCombobox
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Parent() *Node {
|
|
||||||
return n.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Window() *Node {
|
|
||||||
return n.parent
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Dump() {
|
|
||||||
IndentPrintln("id = ", n.id)
|
|
||||||
IndentPrintln("Name = ", n.Name)
|
|
||||||
IndentPrintln("Width = ", n.Width)
|
|
||||||
IndentPrintln("Height = ", n.Height)
|
|
||||||
|
|
||||||
if (n.parent == nil) {
|
|
||||||
IndentPrintln("parent = nil")
|
|
||||||
} else {
|
|
||||||
IndentPrintln("parent =", n.parent.id)
|
|
||||||
}
|
|
||||||
if (n.children != nil) {
|
|
||||||
IndentPrintln("children = ", n.children)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.window != nil) {
|
|
||||||
IndentPrintln("window = ", n.window)
|
|
||||||
}
|
|
||||||
if (n.box != nil) {
|
|
||||||
IndentPrintln("box = ", n.box)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n.uiWindow != nil) {
|
|
||||||
IndentPrintln("uiWindow = ", n.uiWindow)
|
|
||||||
}
|
|
||||||
if (n.uiTab != nil) {
|
|
||||||
IndentPrintln("uiTab = ", n.uiTab)
|
|
||||||
}
|
|
||||||
if (n.uiBox != nil) {
|
|
||||||
IndentPrintln("uiBox = ", n.uiBox)
|
|
||||||
}
|
|
||||||
if (n.Toolkit != nil) {
|
|
||||||
IndentPrintln("Toolkit = ", n.Toolkit)
|
|
||||||
n.Toolkit.Dump()
|
|
||||||
}
|
|
||||||
if (n.uiControl != nil) {
|
|
||||||
IndentPrintln("uiControl = ", n.uiControl)
|
|
||||||
}
|
|
||||||
if (n.uiButton != nil) {
|
|
||||||
IndentPrintln("uiButton = ", n.uiButton)
|
|
||||||
}
|
|
||||||
if (n.custom != nil) {
|
|
||||||
IndentPrintln("custom = ", n.custom)
|
|
||||||
}
|
|
||||||
if (n.OnChanged != nil) {
|
|
||||||
IndentPrintln("OnChanged = ", n.OnChanged)
|
|
||||||
}
|
|
||||||
if (n.id == "") {
|
|
||||||
// Node structs should never have a nil id.
|
|
||||||
// I probably shouldn't panic here, but this is just to check the sanity of
|
|
||||||
// the gui package to make sure it's not exiting
|
|
||||||
panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
func (n *Node) SetBox(box *GuiBox) {
|
|
||||||
n.box = box
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) SetName(name string) {
|
|
||||||
// n.uiType.SetName(name)
|
|
||||||
if (n.uiWindow != nil) {
|
|
||||||
log.Println("node is a window. setting title =", name)
|
|
||||||
n.uiWindow.SetTitle(name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Println("*ui.Control =", n.uiControl)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Append(child *Node) {
|
|
||||||
// if (n.UiBox == nil) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
n.children = append(n.children, child)
|
|
||||||
if (Config.Debug) {
|
|
||||||
log.Println("child node:")
|
|
||||||
child.Dump()
|
|
||||||
log.Println("parent node:")
|
|
||||||
n.Dump()
|
|
||||||
}
|
|
||||||
// time.Sleep(3 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) List() {
|
|
||||||
findByIdDFS(n, "test")
|
|
||||||
}
|
|
||||||
|
|
||||||
var listChildrenParent *Node
|
|
||||||
var listChildrenDepth int = 0
|
|
||||||
var defaultPadding = " "
|
|
||||||
|
|
||||||
func IndentPrintln(a ...interface{}) {
|
|
||||||
indentPrintln(listChildrenDepth, defaultPadding, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func indentPrintln(depth int, format string, a ...interface{}) {
|
|
||||||
var tabs string
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
tabs = tabs + format
|
|
||||||
}
|
|
||||||
|
|
||||||
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
|
||||||
newFormat := tabs + format
|
|
||||||
log.Println(newFormat, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) ListChildren(dump bool) {
|
|
||||||
indentPrintln(listChildrenDepth, defaultPadding, n.id, n.Width, n.Height, n.Name)
|
|
||||||
|
|
||||||
if (dump == true) {
|
|
||||||
n.Dump()
|
|
||||||
}
|
|
||||||
if len(n.children) == 0 {
|
|
||||||
if (n.parent == nil) {
|
|
||||||
} else {
|
|
||||||
if (Config.DebugNode) {
|
|
||||||
log.Println("\t\t\tparent =",n.parent.id)
|
|
||||||
}
|
|
||||||
if (listChildrenParent != nil) {
|
|
||||||
if (Config.DebugNode) {
|
|
||||||
log.Println("\t\t\tlistChildrenParent =",listChildrenParent.id)
|
|
||||||
}
|
|
||||||
if (listChildrenParent.id != n.parent.id) {
|
|
||||||
log.Println("parent.child does not match child.parent")
|
|
||||||
panic("parent.child does not match child.parent")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Config.DebugNode) {
|
|
||||||
log.Println("\t\t", n.id, "has no children")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for _, child := range n.children {
|
|
||||||
// log.Println("\t\t", child.id, child.Width, child.Height, child.Name)
|
|
||||||
if (child.parent != nil) {
|
|
||||||
if (Config.DebugNode) {
|
|
||||||
log.Println("\t\t\tparent =",child.parent.id)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Println("\t\t\tno parent")
|
|
||||||
panic("no parent")
|
|
||||||
}
|
|
||||||
if (dump == true) {
|
|
||||||
child.Dump()
|
|
||||||
}
|
|
||||||
if (Config.DebugNode) {
|
|
||||||
if (child.children == nil) {
|
|
||||||
log.Println("\t\t", child.id, "has no children")
|
|
||||||
} else {
|
|
||||||
log.Println("\t\t\tHas children:", child.children)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
listChildrenParent = n
|
|
||||||
listChildrenDepth += 1
|
|
||||||
child.ListChildren(dump)
|
|
||||||
listChildrenDepth -= 1
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
7
node.go
7
node.go
|
@ -28,13 +28,6 @@ func addNode(title string, w int, h int) *Node {
|
||||||
id := Config.prefix + strconv.Itoa(Config.counter)
|
id := Config.prefix + strconv.Itoa(Config.counter)
|
||||||
Config.counter += 1
|
Config.counter += 1
|
||||||
n.id = id
|
n.id = id
|
||||||
/*
|
|
||||||
if (Data.NodeMap[title] != nil) {
|
|
||||||
panic(fmt.Sprintf("Duplicate window name = %s\n", title))
|
|
||||||
} else {
|
|
||||||
Data.NodeMap[title] = &n
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return &n
|
return &n
|
||||||
}
|
}
|
||||||
|
|
25
slider.go
25
slider.go
|
@ -10,17 +10,34 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
|
||||||
|
|
||||||
log.Println("toolkit.NewSlider() START", name)
|
log.Println("toolkit.NewSlider() START", name)
|
||||||
|
|
||||||
if (n.Toolkit == nil) {
|
if (n.toolkit == nil) {
|
||||||
log.Println("toolkit.NewSlider() Toolkit == nil")
|
log.Println("toolkit.NewSlider() toolkit == nil")
|
||||||
panic("Toolkit should never be nil")
|
panic("Toolkit should never be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
// make a *Node with a *toolkit.Group
|
// make a *Node with a *toolkit.Group
|
||||||
sNode = n.New(name + " part1")
|
sNode = n.New(name + " part1")
|
||||||
newT = n.Toolkit.NewSlider(name, x, y)
|
newT = n.toolkit.NewSlider(name, x, y)
|
||||||
newT.Name = name
|
newT.Name = name
|
||||||
sNode.Toolkit = newT
|
sNode.custom = n.custom
|
||||||
|
newT.Custom = func () {
|
||||||
|
// TODO: make all of this common code to all the widgets
|
||||||
|
if (n.custom == nil) {
|
||||||
|
log.Println("Not Running n.custom(n) == nil")
|
||||||
|
} else {
|
||||||
|
log.Println("Running n.custom(n)")
|
||||||
|
sNode.custom(sNode)
|
||||||
|
}
|
||||||
|
if (sNode.OnChanged == nil) {
|
||||||
|
log.Println("Not Running n.OnChanged(n) == nil")
|
||||||
|
} else {
|
||||||
|
log.Println("Running n.OnChanged(n)")
|
||||||
|
sNode.OnChanged(sNode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sNode.toolkit = newT
|
||||||
sNode.Dump()
|
sNode.Dump()
|
||||||
|
// panic("checking Custom()")
|
||||||
|
|
||||||
return sNode
|
return sNode
|
||||||
}
|
}
|
||||||
|
|
23
spinbox.go
23
spinbox.go
|
@ -1,23 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import "log"
|
|
||||||
|
|
||||||
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|
||||||
|
|
||||||
func (n *Node) NewSpinbox(name string, x int, y int) *Node {
|
|
||||||
// make new node here
|
|
||||||
log.Println("toolkit.NewSpinbox", x, y)
|
|
||||||
|
|
||||||
newNode := n.New(name)
|
|
||||||
|
|
||||||
t := toolkit.NewSpinbox(n.uiBox, name, x, y)
|
|
||||||
t.OnChanged = func(t *toolkit.Toolkit) {
|
|
||||||
log.Println("toolkit.NewSpinbox() value =", t.Value())
|
|
||||||
if (newNode.OnChanged != nil) {
|
|
||||||
newNode.OnChanged(newNode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newNode.Toolkit = t
|
|
||||||
|
|
||||||
return newNode
|
|
||||||
}
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
|
||||||
|
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
|
func (n *Node) NewSpinner(name string, x int, y int) *Node {
|
||||||
|
var newT *toolkit.Toolkit
|
||||||
|
var sNode *Node
|
||||||
|
|
||||||
|
log.Println("toolkit.NewSpinner() START", name)
|
||||||
|
|
||||||
|
if (n.toolkit == nil) {
|
||||||
|
log.Println("toolkit.NewSpinner() toolkit == nil")
|
||||||
|
panic("toolkit should never be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
// make a *Node with a *toolkit.Group
|
||||||
|
sNode = n.New(name + " part1")
|
||||||
|
newT = n.toolkit.NewSpinner(name, x, y)
|
||||||
|
newT.Name = name
|
||||||
|
sNode.toolkit = newT
|
||||||
|
sNode.Dump()
|
||||||
|
|
||||||
|
return sNode
|
||||||
|
}
|
466
structs.go
466
structs.go
|
@ -1,31 +1,38 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"image/color"
|
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
"golang.org/x/image/font"
|
|
||||||
|
|
||||||
// "github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
// _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
//
|
//
|
||||||
// All GUI Data Structures and functions that are external
|
// All GUI Data Structures and functions that are external
|
||||||
// If you need cross platform support, these might only
|
// within the toolkit/ abstraction layer
|
||||||
// be the safe way to interact with the GUI
|
|
||||||
//
|
//
|
||||||
var Data GuiData
|
// More than one Window is not supported in a cross platform
|
||||||
|
// sense & may never be. On many toolkits you have to have 'tabs'
|
||||||
|
// Native Windows and MacOS toolkits work with tabs
|
||||||
|
//
|
||||||
|
// If that is the case, this code should abstract the concept of
|
||||||
|
// windows and make everything 'tabs'
|
||||||
|
//
|
||||||
|
|
||||||
var Config GuiConfig
|
var Config GuiConfig
|
||||||
|
|
||||||
type GuiConfig struct {
|
type GuiConfig struct {
|
||||||
|
// This is the master node. The Binary Tree starts here
|
||||||
|
master *Node
|
||||||
|
|
||||||
|
// These are shortcuts to pass default values to make a new window
|
||||||
Title string
|
Title string
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
Exit func(*Node)
|
Exit func(*Node)
|
||||||
|
|
||||||
|
// These are global debugging settings
|
||||||
|
// TODO: move to a standard logging system
|
||||||
Debug bool
|
Debug bool
|
||||||
DebugNode bool
|
DebugNode bool
|
||||||
DebugTabs bool
|
DebugTabs bool
|
||||||
|
@ -33,295 +40,190 @@ type GuiConfig struct {
|
||||||
DebugWindow bool
|
DebugWindow bool
|
||||||
DebugToolkit bool
|
DebugToolkit bool
|
||||||
|
|
||||||
|
// hacks
|
||||||
depth int
|
depth int
|
||||||
counter int // used to make unique ID's
|
counter int // used to make unique ID's
|
||||||
prefix string
|
prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
type GuiData struct {
|
type Widget int
|
||||||
// a fallback default function to handle mouse events
|
|
||||||
// if nothing else is defined to handle them
|
|
||||||
MouseClick func(*GuiButton)
|
|
||||||
|
|
||||||
// A map of all the entry boxes
|
// https://ieftimov.com/post/golang-datastructures-trees/
|
||||||
AllEntries []*GuiEntry
|
const (
|
||||||
WindowMap map[string]*GuiWindow
|
Unknown Widget = iota
|
||||||
|
Window
|
||||||
|
Tab
|
||||||
|
Frame
|
||||||
|
Dropbox
|
||||||
|
Spinner
|
||||||
|
Label
|
||||||
|
)
|
||||||
|
|
||||||
// Store access to everything via binary tree's
|
func (s Widget) String() string {
|
||||||
NodeMap map[string]*Node
|
switch s {
|
||||||
NodeArray []*Node
|
case Window:
|
||||||
NodeSlice []*Node
|
return "Window"
|
||||||
|
case Tab:
|
||||||
// A map of all buttons everywhere on all
|
return "Tab"
|
||||||
// windows, all tabs, across all goroutines
|
case Frame:
|
||||||
// This is "GLOBAL"
|
return "Frame"
|
||||||
//
|
case Label:
|
||||||
// This has to work this way because of how
|
return "Label"
|
||||||
// andlabs/ui & andlabs/libui work
|
case Dropbox:
|
||||||
AllButtons []*GuiButton
|
return "Dropbox"
|
||||||
buttonMap map[*ui.Button]*GuiButton
|
|
||||||
}
|
|
||||||
|
|
||||||
type GuiTab struct {
|
|
||||||
Name string // field for human readable name
|
|
||||||
Number int // the andlabs/ui tab index
|
|
||||||
Window *GuiWindow // the parent Window
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// stores information on the 'window'
|
|
||||||
//
|
|
||||||
// This merges the concept of andlabs/ui *Window and *Tab
|
|
||||||
//
|
|
||||||
// More than one Window is not supported in a cross platform
|
|
||||||
// sense & may never be. On Windows and MacOS, you have to have
|
|
||||||
// 'tabs'. Even under Linux, more than one Window is currently
|
|
||||||
// unstable
|
|
||||||
//
|
|
||||||
// This code will make a 'GuiWindow' regardless of if it is
|
|
||||||
// a stand alone window (which is more or less working on Linux)
|
|
||||||
// or a 'tab' inside a window (which is all that works on MacOS
|
|
||||||
// and MSWindows.
|
|
||||||
//
|
|
||||||
// This struct keeps track of what is in the window so you
|
|
||||||
// can destroy and replace it with something else
|
|
||||||
//
|
|
||||||
type GuiWindow struct {
|
|
||||||
Name string // field for human readable name
|
|
||||||
Width int
|
|
||||||
Height int
|
|
||||||
Axis int // does it add items to the X or Y axis
|
|
||||||
TabNumber *int // the andlabs/ui tab index
|
|
||||||
|
|
||||||
// the callback function to make the window contents
|
|
||||||
// MakeWindow func(*GuiBox) *GuiBox
|
|
||||||
|
|
||||||
// the components of the window
|
|
||||||
BoxMap map[string]*GuiBox
|
|
||||||
EntryMap map[string]*GuiEntry
|
|
||||||
Area *GuiArea
|
|
||||||
|
|
||||||
node *Node
|
|
||||||
|
|
||||||
// andlabs/ui abstraction mapping
|
|
||||||
UiWindow *ui.Window
|
|
||||||
UiTab *ui.Tab // if this != nil, the window is 'tabbed'
|
|
||||||
}
|
|
||||||
|
|
||||||
func (w *GuiWindow) Dump() {
|
|
||||||
log.Println("gui.GuiWindow.Dump() Name = ", w.Name)
|
|
||||||
log.Println("gui.GuiWindow.Dump() node = ", w.node)
|
|
||||||
log.Println("gui.GuiWindow.Dump() Width = ", w.Width)
|
|
||||||
log.Println("gui.GuiWindow.Dump() Height = ", w.Height)
|
|
||||||
}
|
|
||||||
|
|
||||||
// GuiBox is any type of ui.Hbox or ui.Vbox
|
|
||||||
// There can be lots of these for each GuiWindow
|
|
||||||
type GuiBox struct {
|
|
||||||
Name string // field for human readable name
|
|
||||||
Axis int // does it add items to the X or Y axis
|
|
||||||
Window *GuiWindow // the parent Window
|
|
||||||
|
|
||||||
node *Node
|
|
||||||
|
|
||||||
// andlabs/ui abstraction mapping
|
|
||||||
UiBox *ui.Box
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *GuiBox) Dump() {
|
|
||||||
log.Println("gui.GuiBox.Dump() Name = ", b.Name)
|
|
||||||
log.Println("gui.GuiBox.Dump() Axis = ", b.Axis)
|
|
||||||
log.Println("gui.GuiBox.Dump() GuiWindow = ", b.Window)
|
|
||||||
log.Println("gui.GuiBox.Dump() node = ", b.node)
|
|
||||||
log.Println("gui.GuiBox.Dump() UiBox = ", b.UiBox)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *GuiBox) SetTitle(title string) {
|
|
||||||
log.Println("DID IT!", title)
|
|
||||||
if b.Window == nil {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
if b.Window.UiWindow == nil {
|
return "unknown"
|
||||||
return
|
}
|
||||||
|
|
||||||
|
// The Node is simply the name and the size of whatever GUI element exists
|
||||||
|
type Node struct {
|
||||||
|
id string
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
|
||||||
|
parent *Node
|
||||||
|
children []*Node
|
||||||
|
|
||||||
|
custom func(*Node)
|
||||||
|
OnChanged func(*Node)
|
||||||
|
|
||||||
|
toolkit *toolkit.Toolkit
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Parent() *Node {
|
||||||
|
return n.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Window() *Node {
|
||||||
|
return n.parent
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) Dump() {
|
||||||
|
IndentPrintln("id = ", n.id)
|
||||||
|
IndentPrintln("Name = ", n.Name)
|
||||||
|
IndentPrintln("Width = ", n.Width)
|
||||||
|
IndentPrintln("Height = ", n.Height)
|
||||||
|
|
||||||
|
if (n.parent == nil) {
|
||||||
|
IndentPrintln("parent = nil")
|
||||||
|
} else {
|
||||||
|
IndentPrintln("parent =", n.parent.id)
|
||||||
}
|
}
|
||||||
b.Window.UiWindow.SetTitle(title)
|
if (n.children != nil) {
|
||||||
|
IndentPrintln("children = ", n.children)
|
||||||
|
}
|
||||||
|
if (n.toolkit != nil) {
|
||||||
|
IndentPrintln("toolkit = ", n.toolkit)
|
||||||
|
n.toolkit.Dump()
|
||||||
|
}
|
||||||
|
if (n.custom != nil) {
|
||||||
|
IndentPrintln("custom = ", n.custom)
|
||||||
|
}
|
||||||
|
if (n.OnChanged != nil) {
|
||||||
|
IndentPrintln("OnChanged = ", n.OnChanged)
|
||||||
|
}
|
||||||
|
if (n.id == "") {
|
||||||
|
// Node structs should never have a nil id.
|
||||||
|
// I probably shouldn't panic here, but this is just to check the sanity of
|
||||||
|
// the gui package to make sure it's not exiting
|
||||||
|
panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) SetName(name string) {
|
||||||
|
n.toolkit.SetWindowTitle(name)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *GuiWindow) SetNode(n *Node) {
|
func (n *Node) Append(child *Node) {
|
||||||
if (w.node != nil) {
|
n.children = append(n.children, child)
|
||||||
w.Dump()
|
if (Config.Debug) {
|
||||||
panic("gui.SetNode() Error not nil")
|
log.Println("child node:")
|
||||||
}
|
child.Dump()
|
||||||
w.node = n
|
log.Println("parent node:")
|
||||||
if (w.node == nil) {
|
n.Dump()
|
||||||
w.Dump()
|
|
||||||
panic("gui.SetNode() node == nil")
|
|
||||||
}
|
}
|
||||||
|
// time.Sleep(3 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GuiBox) SetNode(n *Node) {
|
/*
|
||||||
if (b.node != nil) {
|
func (n *Node) List() {
|
||||||
b.Dump()
|
findByIdDFS(n, "test")
|
||||||
panic("gui.SetNode() Error not nil")
|
}
|
||||||
}
|
*/
|
||||||
b.node = n
|
|
||||||
if (b.node == nil) {
|
var listChildrenParent *Node
|
||||||
b.Dump()
|
var listChildrenDepth int = 0
|
||||||
panic("gui.SetNode() node == nil")
|
var defaultPadding = " "
|
||||||
}
|
|
||||||
|
func IndentPrintln(a ...interface{}) {
|
||||||
|
indentPrintln(listChildrenDepth, defaultPadding, a)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *GuiBox) Append(child ui.Control, x bool) {
|
func indentPrintln(depth int, format string, a ...interface{}) {
|
||||||
if b.UiBox == nil {
|
var tabs string
|
||||||
// spew.Dump(b)
|
for i := 0; i < depth; i++ {
|
||||||
b.Dump()
|
tabs = tabs + format
|
||||||
panic("GuiBox.Append() can't work. UiBox == nil")
|
}
|
||||||
|
|
||||||
|
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
||||||
|
newFormat := tabs + format
|
||||||
|
log.Println(newFormat, a)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) ListChildren(dump bool) {
|
||||||
|
indentPrintln(listChildrenDepth, defaultPadding, n.id, n.Width, n.Height, n.Name)
|
||||||
|
|
||||||
|
if (dump == true) {
|
||||||
|
n.Dump()
|
||||||
|
}
|
||||||
|
if len(n.children) == 0 {
|
||||||
|
if (n.parent == nil) {
|
||||||
|
} else {
|
||||||
|
if (Config.DebugNode) {
|
||||||
|
log.Println("\t\t\tparent =",n.parent.id)
|
||||||
|
}
|
||||||
|
if (listChildrenParent != nil) {
|
||||||
|
if (Config.DebugNode) {
|
||||||
|
log.Println("\t\t\tlistChildrenParent =",listChildrenParent.id)
|
||||||
|
}
|
||||||
|
if (listChildrenParent.id != n.parent.id) {
|
||||||
|
log.Println("parent.child does not match child.parent")
|
||||||
|
panic("parent.child does not match child.parent")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Config.DebugNode) {
|
||||||
|
log.Println("\t\t", n.id, "has no children")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.UiBox.Append(child, x)
|
for _, child := range n.children {
|
||||||
|
// log.Println("\t\t", child.id, child.Width, child.Height, child.Name)
|
||||||
|
if (child.parent != nil) {
|
||||||
|
if (Config.DebugNode) {
|
||||||
|
log.Println("\t\t\tparent =",child.parent.id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.Println("\t\t\tno parent")
|
||||||
|
panic("no parent")
|
||||||
|
}
|
||||||
|
if (dump == true) {
|
||||||
|
child.Dump()
|
||||||
|
}
|
||||||
|
if (Config.DebugNode) {
|
||||||
|
if (child.children == nil) {
|
||||||
|
log.Println("\t\t", child.id, "has no children")
|
||||||
|
} else {
|
||||||
|
log.Println("\t\t\tHas children:", child.children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
listChildrenParent = n
|
||||||
|
listChildrenDepth += 1
|
||||||
|
child.ListChildren(dump)
|
||||||
|
listChildrenDepth -= 1
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: every mouse click is handled
|
|
||||||
// as a 'Button' regardless of where
|
|
||||||
// the user clicks it. You could probably
|
|
||||||
// call this 'GuiMouseClick'
|
|
||||||
type GuiButton struct {
|
|
||||||
Name string // field for human readable name
|
|
||||||
Box *GuiBox // what box the button click was in
|
|
||||||
|
|
||||||
// a callback function for the main application
|
|
||||||
Custom func(*GuiButton)
|
|
||||||
Values interface{}
|
|
||||||
Color color.RGBA
|
|
||||||
|
|
||||||
// andlabs/ui abstraction mapping
|
|
||||||
B *ui.Button
|
|
||||||
FB *ui.FontButton
|
|
||||||
CB *ui.ColorButton
|
|
||||||
}
|
|
||||||
|
|
||||||
// text entry fields
|
|
||||||
type GuiEntry struct {
|
|
||||||
Name string // field for human readable name
|
|
||||||
Edit bool
|
|
||||||
Last string // the last value
|
|
||||||
Normalize func(string) string // function to 'normalize' the data
|
|
||||||
|
|
||||||
B *GuiButton
|
|
||||||
Box *GuiBox
|
|
||||||
|
|
||||||
// andlabs/ui abstraction mapping
|
|
||||||
UiEntry *ui.Entry
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// AREA STRUCTURES START
|
|
||||||
// AREA STRUCTURES START
|
|
||||||
// AREA STRUCTURES START
|
|
||||||
//
|
|
||||||
type GuiArea struct {
|
|
||||||
Button *GuiButton // what button handles mouse events
|
|
||||||
Box *GuiBox
|
|
||||||
|
|
||||||
UiAttrstr *ui.AttributedString
|
|
||||||
UiArea *ui.Area
|
|
||||||
}
|
|
||||||
|
|
||||||
type FontString struct {
|
|
||||||
S string
|
|
||||||
Size int
|
|
||||||
F font.Face
|
|
||||||
W font.Weight
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// AREA STRUCTURES END
|
|
||||||
// AREA STRUCTURES END
|
|
||||||
// AREA STRUCTURES END
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// TABLE DATA STRUCTURES START
|
|
||||||
// TABLE DATA STRUCTURES START
|
|
||||||
// TABLE DATA STRUCTURES START
|
|
||||||
//
|
|
||||||
|
|
||||||
//
|
|
||||||
// This is the structure that andlabs/ui uses to pass information
|
|
||||||
// to the GUI. This is the "authoritative" data.
|
|
||||||
//
|
|
||||||
type TableData struct {
|
|
||||||
RowCount int // This is the number of 'rows' which really means data elements not what the human sees
|
|
||||||
RowWidth int // This is how wide each row is
|
|
||||||
Rows []RowData // This is all the table data by row
|
|
||||||
generatedColumnTypes []ui.TableValue // generate this dynamically
|
|
||||||
|
|
||||||
Cells [20]CellData
|
|
||||||
Human [20]HumanMap
|
|
||||||
|
|
||||||
Box *GuiBox
|
|
||||||
|
|
||||||
lastRow int
|
|
||||||
lastColumn int
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// This maps the andlabs/ui & libui components into a "human"
|
|
||||||
// readable cell reference list. The reason is that there
|
|
||||||
// are potentially 3 values for each cell. The Text, the Color
|
|
||||||
// and an image. These are not always needed so the number
|
|
||||||
// of fields varies between 1 and 3. Internally, the toolkit
|
|
||||||
// GUI abstraction needs to list all of them, but it's then
|
|
||||||
// hard to figure out which column goes with the columns that
|
|
||||||
// you see when you visually are looking at it like a spreadsheet
|
|
||||||
//
|
|
||||||
// This makes a map so that we can say "give me the value at
|
|
||||||
// row 4 and column 2" and find the fields that are needed
|
|
||||||
//
|
|
||||||
// TODO: re-add images and the progress bar (works in andlabs/ui)
|
|
||||||
//
|
|
||||||
type HumanCellData struct {
|
|
||||||
Name string // what kind of row is this?
|
|
||||||
Text string
|
|
||||||
TextID int
|
|
||||||
Color color.RGBA
|
|
||||||
ColorID int
|
|
||||||
Button *GuiButton
|
|
||||||
}
|
|
||||||
|
|
||||||
type HumanMap struct {
|
|
||||||
Name string // what kind of row is this?
|
|
||||||
TextID int
|
|
||||||
ColorID int
|
|
||||||
}
|
|
||||||
|
|
||||||
type TableColumnData struct {
|
|
||||||
Index int
|
|
||||||
CellType string
|
|
||||||
Heading string
|
|
||||||
Color string
|
|
||||||
}
|
|
||||||
|
|
||||||
type CellData struct {
|
|
||||||
Index int
|
|
||||||
HumanID int
|
|
||||||
Name string // what type of cell is this?
|
|
||||||
}
|
|
||||||
|
|
||||||
// hmm. will this stand the test of time?
|
|
||||||
type RowData struct {
|
|
||||||
Name string // what kind of row is this?
|
|
||||||
Status string // status of the row?
|
|
||||||
/*
|
|
||||||
// TODO: These may or may not be implementable
|
|
||||||
// depending on if it's possible to detect the bgcolor or what row is selected
|
|
||||||
click func() // what function to call if the user clicks on it
|
|
||||||
doubleclick func() // what function to call if the user double clicks on it
|
|
||||||
*/
|
|
||||||
HumanData [20]HumanCellData
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// TABLE DATA STRUCTURES END
|
|
||||||
//
|
|
||||||
|
|
65
tab.go
65
tab.go
|
@ -2,76 +2,25 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|
||||||
|
|
||||||
// This function should make a new node with the parent and
|
// This function should make a new node with the parent and
|
||||||
// the 'tab' as a child
|
// the 'tab' as a child
|
||||||
|
|
||||||
func (n *Node) NewTab(title string) *Node {
|
func (n *Node) NewTab(title string) *Node {
|
||||||
log.Println("gui.Node.AddTab() START name =", title)
|
log.Println("gui.Node.NewTab() START name =", title)
|
||||||
|
|
||||||
return n.AddTabNew(title)
|
// TODO: standardize these checks somewhere
|
||||||
}
|
if (n.toolkit == nil) {
|
||||||
|
|
||||||
func (n *Node) AddTabNew(title string) *Node {
|
|
||||||
log.Println("gui.Node.AddTab() START name =", title)
|
|
||||||
|
|
||||||
if (n.Toolkit == nil) {
|
|
||||||
log.Println("FUCK TOOLKIT nil uiWindow =", n.uiWindow)
|
|
||||||
log.Println("FUCK TOOLKIT nil uiTab =", n.uiTab)
|
|
||||||
log.Println("FUCK TOOLKIT nil Toolkit =", n.Toolkit)
|
|
||||||
// return n.AddTab(title) // need to make a toolkit here
|
|
||||||
n.Dump()
|
n.Dump()
|
||||||
os.Exit(0)
|
panic("NewTab() failed. toolkit == nil")
|
||||||
}
|
}
|
||||||
log.Println("Make new node")
|
log.Println("Make new node")
|
||||||
newN := n.New(title)
|
newN := n.New(title)
|
||||||
log.Println("Add tab to window")
|
log.Println("New tab to window")
|
||||||
t := n.Toolkit.AddTab(title)
|
t := n.toolkit.AddTab(title)
|
||||||
newN.Toolkit = t
|
newN.toolkit = t
|
||||||
|
|
||||||
n.Append(newN)
|
n.Append(newN)
|
||||||
return newN
|
return newN
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) AddTab(title string, uiC *ui.Box) *Node {
|
|
||||||
return n.AddTabNew(title)
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
func (n *Node) AddTabBAD(title string, uiC *ui.Box) *Node {
|
|
||||||
parent := n
|
|
||||||
log.Println("gui.Node.AddTab() START name =", title)
|
|
||||||
if parent.uiWindow == nil {
|
|
||||||
parent.Dump()
|
|
||||||
log.Println("gui.Node.AddTab() ERROR ui.Window == nil")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if parent.uiTab == nil {
|
|
||||||
inittab := ui.NewTab() // no, not that 'inittab'
|
|
||||||
parent.uiWindow.SetChild(inittab)
|
|
||||||
parent.uiWindow.SetMargined(true)
|
|
||||||
parent.uiTab = inittab
|
|
||||||
}
|
|
||||||
tab := parent.uiTab
|
|
||||||
parent.uiWindow.SetMargined(true)
|
|
||||||
|
|
||||||
if (uiC == nil) {
|
|
||||||
hbox := ui.NewHorizontalBox()
|
|
||||||
hbox.SetPadded(true)
|
|
||||||
uiC = hbox
|
|
||||||
}
|
|
||||||
tab.Append(title, uiC)
|
|
||||||
|
|
||||||
newNode := n.New(title)
|
|
||||||
newNode.uiTab = tab
|
|
||||||
newNode.uiBox = uiC
|
|
||||||
// tabSetMargined(newNode.uiTab)
|
|
||||||
return newNode
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
62
text.go
62
text.go
|
@ -2,8 +2,7 @@ package gui
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "errors"
|
import "errors"
|
||||||
|
import "regexp"
|
||||||
// import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|
||||||
|
|
||||||
// functions for handling text related GUI elements
|
// functions for handling text related GUI elements
|
||||||
|
|
||||||
|
@ -12,29 +11,52 @@ func (n *Node) NewLabel(text string) *Node {
|
||||||
newNode := n.New(text)
|
newNode := n.New(text)
|
||||||
newNode.Dump()
|
newNode.Dump()
|
||||||
|
|
||||||
t := n.Toolkit.NewLabel(text)
|
t := n.toolkit.NewLabel(text)
|
||||||
newNode.Toolkit = t
|
newNode.toolkit = t
|
||||||
|
|
||||||
return newNode
|
return newNode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetText(value string) error {
|
func (n *Node) SetText(value string) error {
|
||||||
log.Println("gui.SetText() value =", value)
|
log.Println("gui.SetText() value =", value)
|
||||||
if (n.Toolkit != nil) {
|
panic("redo SetText()")
|
||||||
n.Toolkit.SetText(value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if (n.uiText != nil) {
|
|
||||||
n.uiText.SetText(value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if (n.uiButton != nil) {
|
|
||||||
n.uiButton.SetText(value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if (n.uiWindow != nil) {
|
|
||||||
n.uiWindow.SetTitle(value)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("nothing found for gui.Node.SetText()")
|
return errors.New("nothing found for gui.Node.SetText()")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
// string handling examples that might be helpful for normalizeInt()
|
||||||
|
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
||||||
|
|
||||||
|
for _, username := range []string{"userone", "user2", "user-three"} {
|
||||||
|
if !isAlpha(username) {
|
||||||
|
fmt.Printf("%q is not valid\n", username)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const alpha = "abcdefghijklmnopqrstuvwxyz"
|
||||||
|
|
||||||
|
func alphaOnly(s string) bool {
|
||||||
|
for _, char := range s {
|
||||||
|
if !strings.Contains(alpha, strings.ToLower(string(char))) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
func normalizeInt(s string) string {
|
||||||
|
// reg, err := regexp.Compile("[^a-zA-Z0-9]+")
|
||||||
|
reg, err := regexp.Compile("[^0-9]+")
|
||||||
|
if err != nil {
|
||||||
|
log.Println("normalizeInt() regexp.Compile() ERROR =", err)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
clean := reg.ReplaceAllString(s, "")
|
||||||
|
log.Println("normalizeInt() s =", clean)
|
||||||
|
return clean
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) GetText() string {
|
||||||
|
return n.toolkit.GetText()
|
||||||
|
}
|
||||||
|
|
|
@ -14,9 +14,10 @@ func BlankWindow(w *ui.Window) *ui.Box {
|
||||||
return hbox
|
return hbox
|
||||||
}
|
}
|
||||||
|
|
||||||
func DemoNumbersPage(w *ui.Window) *Toolkit {
|
func (t *Toolkit) DemoNumbersPage() {
|
||||||
var t Toolkit
|
var w *ui.Window
|
||||||
|
|
||||||
|
w = t.uiWindow
|
||||||
t.uiBox = makeNumbersPage()
|
t.uiBox = makeNumbersPage()
|
||||||
t.uiBox.SetPadded(true)
|
t.uiBox.SetPadded(true)
|
||||||
w.SetChild(t.uiBox)
|
w.SetChild(t.uiBox)
|
||||||
|
@ -27,8 +28,6 @@ func DemoNumbersPage(w *ui.Window) *Toolkit {
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
scs := spew.ConfigState{MaxDepth: 1}
|
||||||
scs.Dump(t)
|
scs.Dump(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &t
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package toolkit
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
import "os"
|
||||||
|
// import "time"
|
||||||
|
|
||||||
|
import "github.com/andlabs/ui"
|
||||||
|
import _ "github.com/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
|
import "github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
func (pt *Toolkit) NewDropdown(title string) *Toolkit {
|
||||||
|
// make new node here
|
||||||
|
log.Println("gui.Toolbox.NewDropdownCombobox()")
|
||||||
|
var newt Toolkit
|
||||||
|
|
||||||
|
if (pt.uiBox == nil) {
|
||||||
|
log.Println("gui.ToolboxNode.NewDropdown() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||||
|
os.Exit(0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s := ui.NewCombobox()
|
||||||
|
newt.uiCombobox = s
|
||||||
|
newt.uiBox = pt.uiBox
|
||||||
|
pt.uiBox.Append(s, false)
|
||||||
|
|
||||||
|
// initialize the index
|
||||||
|
newt.c = 0
|
||||||
|
newt.val = make(map[int]string)
|
||||||
|
|
||||||
|
s.OnSelected(func(spin *ui.Combobox) {
|
||||||
|
i := spin.Selected()
|
||||||
|
if (newt.val == nil) {
|
||||||
|
log.Println("make map didn't work")
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
newt.text = newt.val[i]
|
||||||
|
val := newt.text
|
||||||
|
log.Println("gui.Toolbox.ui.Dropdown.OnChanged() val =", i, val)
|
||||||
|
if (DebugToolkit) {
|
||||||
|
log.Println("gui.Toolbox.ui.OnChanged() val =", i, val)
|
||||||
|
scs := spew.ConfigState{MaxDepth: 1}
|
||||||
|
scs.Dump(newt)
|
||||||
|
}
|
||||||
|
if (newt.OnChanged != nil) {
|
||||||
|
log.Println("gui.Toolbox.OnChanged() trying to run toolkit.OnChanged() entered val =", i, val)
|
||||||
|
newt.OnChanged(&newt)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (newt.Custom != nil) {
|
||||||
|
log.Println("gui.Toolbox.OnChanged() Running toolkit.Custom()", i, val)
|
||||||
|
newt.Custom()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("gui.Toolbox.Dropdown.OnChanged() ENDED without finding any callback", i, val)
|
||||||
|
})
|
||||||
|
|
||||||
|
return &newt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Toolkit) AddDropdown(title string) {
|
||||||
|
t.uiCombobox.Append(title)
|
||||||
|
if (t.val == nil) {
|
||||||
|
log.Println("make map didn't work")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.val[t.c] = title
|
||||||
|
t.c = t.c + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t Toolkit) SetDropdown(i int) {
|
||||||
|
t.uiCombobox.SetSelected(i)
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package toolkit
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
|
||||||
|
"github.com/andlabs/ui"
|
||||||
|
_ "github.com/andlabs/ui/winmanifest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Main(f func()) {
|
||||||
|
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||||
|
ui.Main(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Other goroutines must use this to access the GUI
|
||||||
|
//
|
||||||
|
// You can not acess / process the GUI thread directly from
|
||||||
|
// other goroutines. This is due to the nature of how
|
||||||
|
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
||||||
|
//
|
||||||
|
// For example: Queue(NewWindow())
|
||||||
|
//
|
||||||
|
func Queue(f func()) {
|
||||||
|
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
||||||
|
ui.QueueMain(f)
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
import "github.com/andlabs/ui"
|
||||||
|
import _ "github.com/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
|
func HorizontalBreak(box *GuiBox) {
|
||||||
|
log.Println("VerticalSeparator added to box =", box.Name)
|
||||||
|
tmp := ui.NewHorizontalSeparator()
|
||||||
|
if (box == nil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (box.UiBox == nil) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
box.UiBox.Append(tmp, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
func VerticalBreak(box *GuiBox) {
|
||||||
|
log.Println("VerticalSeparator added to box =", box.Name)
|
||||||
|
tmp := ui.NewVerticalSeparator()
|
||||||
|
box.UiBox.Append(tmp, false)
|
||||||
|
}
|
|
@ -0,0 +1,273 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
|
||||||
|
"github.com/andlabs/ui"
|
||||||
|
// "golang.org/x/image/font"
|
||||||
|
|
||||||
|
// "github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
// _ "github.com/andlabs/ui/winmanifest"
|
||||||
|
)
|
||||||
|
|
||||||
|
//
|
||||||
|
// All GUI Data Structures and functions that are external
|
||||||
|
// If you need cross platform support, these might only
|
||||||
|
// be the safe way to interact with the GUI
|
||||||
|
//
|
||||||
|
var Data GuiData
|
||||||
|
var Config GuiConfig
|
||||||
|
|
||||||
|
type GuiConfig struct {
|
||||||
|
Title string
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
Exit func(*Node)
|
||||||
|
|
||||||
|
Debug bool
|
||||||
|
DebugNode bool
|
||||||
|
DebugTabs bool
|
||||||
|
DebugTable bool
|
||||||
|
DebugWindow bool
|
||||||
|
DebugToolkit bool
|
||||||
|
|
||||||
|
depth int
|
||||||
|
counter int // used to make unique ID's
|
||||||
|
prefix string
|
||||||
|
}
|
||||||
|
|
||||||
|
type GuiData struct {
|
||||||
|
// a fallback default function to handle mouse events
|
||||||
|
// if nothing else is defined to handle them
|
||||||
|
MouseClick func(*GuiButton)
|
||||||
|
|
||||||
|
// A map of all the entry boxes
|
||||||
|
// AllEntries []*GuiEntry
|
||||||
|
WindowMap map[string]*GuiWindow
|
||||||
|
|
||||||
|
// Store access to everything via binary tree's
|
||||||
|
NodeMap map[string]*Node
|
||||||
|
NodeArray []*Node
|
||||||
|
NodeSlice []*Node
|
||||||
|
|
||||||
|
// A map of all buttons everywhere on all
|
||||||
|
// windows, all tabs, across all goroutines
|
||||||
|
// This is "GLOBAL"
|
||||||
|
//
|
||||||
|
// This has to work this way because of how
|
||||||
|
// andlabs/ui & andlabs/libui work
|
||||||
|
AllButtons []*GuiButton
|
||||||
|
// buttonMap map[*ui.Button]*GuiButton
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
type GuiTab struct {
|
||||||
|
Name string // field for human readable name
|
||||||
|
Number int // the andlabs/ui tab index
|
||||||
|
Window *GuiWindow // the parent Window
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// stores information on the 'window'
|
||||||
|
//
|
||||||
|
// This merges the concept of andlabs/ui *Window and *Tab
|
||||||
|
//
|
||||||
|
// More than one Window is not supported in a cross platform
|
||||||
|
// sense & may never be. On Windows and MacOS, you have to have
|
||||||
|
// 'tabs'. Even under Linux, more than one Window is currently
|
||||||
|
// unstable
|
||||||
|
//
|
||||||
|
// This code will make a 'GuiWindow' regardless of if it is
|
||||||
|
// a stand alone window (which is more or less working on Linux)
|
||||||
|
// or a 'tab' inside a window (which is all that works on MacOS
|
||||||
|
// and MSWindows.
|
||||||
|
//
|
||||||
|
// This struct keeps track of what is in the window so you
|
||||||
|
// can destroy and replace it with something else
|
||||||
|
//
|
||||||
|
type GuiWindow struct {
|
||||||
|
Name string // field for human readable name
|
||||||
|
Width int
|
||||||
|
Height int
|
||||||
|
Axis int // does it add items to the X or Y axis
|
||||||
|
TabNumber *int // the andlabs/ui tab index
|
||||||
|
|
||||||
|
// the callback function to make the window contents
|
||||||
|
// MakeWindow func(*GuiBox) *GuiBox
|
||||||
|
|
||||||
|
// the components of the window
|
||||||
|
BoxMap map[string]*GuiBox
|
||||||
|
// EntryMap map[string]*GuiEntry
|
||||||
|
|
||||||
|
node *Node
|
||||||
|
|
||||||
|
// andlabs/ui abstraction mapping
|
||||||
|
UiWindow *ui.Window
|
||||||
|
UiTab *ui.Tab // if this != nil, the window is 'tabbed'
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
func (w *GuiWindow) Dump() {
|
||||||
|
log.Println("gui.GuiWindow.Dump() Name = ", w.Name)
|
||||||
|
log.Println("gui.GuiWindow.Dump() node = ", w.node)
|
||||||
|
log.Println("gui.GuiWindow.Dump() Width = ", w.Width)
|
||||||
|
log.Println("gui.GuiWindow.Dump() Height = ", w.Height)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// GuiBox is any type of ui.Hbox or ui.Vbox
|
||||||
|
// There can be lots of these for each GuiWindow
|
||||||
|
type GuiBox struct {
|
||||||
|
Name string // field for human readable name
|
||||||
|
Axis int // does it add items to the X or Y axis
|
||||||
|
Window *GuiWindow // the parent Window
|
||||||
|
|
||||||
|
node *Node
|
||||||
|
|
||||||
|
// andlabs/ui abstraction mapping
|
||||||
|
UiBox *ui.Box
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *GuiBox) Append(child ui.Control, x bool) {
|
||||||
|
if b.UiBox == nil {
|
||||||
|
// spew.Dump(b)
|
||||||
|
// b.Dump()
|
||||||
|
panic("GuiBox.Append() can't work. UiBox == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.UiBox.Append(child, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: every mouse click is handled
|
||||||
|
// as a 'Button' regardless of where
|
||||||
|
// the user clicks it. You could probably
|
||||||
|
// call this 'GuiMouseClick'
|
||||||
|
type GuiButton struct {
|
||||||
|
Name string // field for human readable name
|
||||||
|
Box *GuiBox // what box the button click was in
|
||||||
|
|
||||||
|
// a callback function for the main application
|
||||||
|
Custom func(*GuiButton)
|
||||||
|
Values interface{}
|
||||||
|
Color color.RGBA
|
||||||
|
|
||||||
|
// andlabs/ui abstraction mapping
|
||||||
|
B *ui.Button
|
||||||
|
FB *ui.FontButton
|
||||||
|
CB *ui.ColorButton
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
//
|
||||||
|
// AREA STRUCTURES START
|
||||||
|
// AREA STRUCTURES START
|
||||||
|
// AREA STRUCTURES START
|
||||||
|
//
|
||||||
|
type GuiArea struct {
|
||||||
|
Button *GuiButton // what button handles mouse events
|
||||||
|
Box *GuiBox
|
||||||
|
|
||||||
|
UiAttrstr *ui.AttributedString
|
||||||
|
UiArea *ui.Area
|
||||||
|
}
|
||||||
|
|
||||||
|
type FontString struct {
|
||||||
|
S string
|
||||||
|
Size int
|
||||||
|
F font.Face
|
||||||
|
W font.Weight
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// AREA STRUCTURES END
|
||||||
|
// AREA STRUCTURES END
|
||||||
|
// AREA STRUCTURES END
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// TABLE DATA STRUCTURES START
|
||||||
|
// TABLE DATA STRUCTURES START
|
||||||
|
// TABLE DATA STRUCTURES START
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// This is the structure that andlabs/ui uses to pass information
|
||||||
|
// to the GUI. This is the "authoritative" data.
|
||||||
|
//
|
||||||
|
type TableData struct {
|
||||||
|
RowCount int // This is the number of 'rows' which really means data elements not what the human sees
|
||||||
|
RowWidth int // This is how wide each row is
|
||||||
|
Rows []RowData // This is all the table data by row
|
||||||
|
generatedColumnTypes []ui.TableValue // generate this dynamically
|
||||||
|
|
||||||
|
Cells [20]CellData
|
||||||
|
Human [20]HumanMap
|
||||||
|
|
||||||
|
Box *GuiBox
|
||||||
|
|
||||||
|
lastRow int
|
||||||
|
lastColumn int
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// This maps the andlabs/ui & libui components into a "human"
|
||||||
|
// readable cell reference list. The reason is that there
|
||||||
|
// are potentially 3 values for each cell. The Text, the Color
|
||||||
|
// and an image. These are not always needed so the number
|
||||||
|
// of fields varies between 1 and 3. Internally, the toolkit
|
||||||
|
// GUI abstraction needs to list all of them, but it's then
|
||||||
|
// hard to figure out which column goes with the columns that
|
||||||
|
// you see when you visually are looking at it like a spreadsheet
|
||||||
|
//
|
||||||
|
// This makes a map so that we can say "give me the value at
|
||||||
|
// row 4 and column 2" and find the fields that are needed
|
||||||
|
//
|
||||||
|
// TODO: re-add images and the progress bar (works in andlabs/ui)
|
||||||
|
//
|
||||||
|
type HumanCellData struct {
|
||||||
|
Name string // what kind of row is this?
|
||||||
|
Text string
|
||||||
|
TextID int
|
||||||
|
Color color.RGBA
|
||||||
|
ColorID int
|
||||||
|
Button *GuiButton
|
||||||
|
}
|
||||||
|
|
||||||
|
type HumanMap struct {
|
||||||
|
Name string // what kind of row is this?
|
||||||
|
TextID int
|
||||||
|
ColorID int
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableColumnData struct {
|
||||||
|
Index int
|
||||||
|
CellType string
|
||||||
|
Heading string
|
||||||
|
Color string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CellData struct {
|
||||||
|
Index int
|
||||||
|
HumanID int
|
||||||
|
Name string // what type of cell is this?
|
||||||
|
}
|
||||||
|
|
||||||
|
// hmm. will this stand the test of time?
|
||||||
|
type RowData struct {
|
||||||
|
Name string // what kind of row is this?
|
||||||
|
Status string // status of the row?
|
||||||
|
//
|
||||||
|
// TODO: These may or may not be implementable
|
||||||
|
// depending on if it's possible to detect the bgcolor or what row is selected
|
||||||
|
// click func() // what function to call if the user clicks on it
|
||||||
|
// doubleclick func() // what function to call if the user double clicks on it
|
||||||
|
//
|
||||||
|
HumanData [20]HumanCellData
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// TABLE DATA STRUCTURES END
|
||||||
|
//
|
|
@ -11,11 +11,11 @@ import "github.com/davecgh/go-spew/spew"
|
||||||
// func NewSlider(b *ui.Box, name string *Toolkit {
|
// func NewSlider(b *ui.Box, name string *Toolkit {
|
||||||
func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit {
|
func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit {
|
||||||
// make new node here
|
// make new node here
|
||||||
log.Println("gui.Toolbox.NewSpinbox()", x, y)
|
log.Println("gui.Toolkit.NewSpinbox()", x, y)
|
||||||
var newt Toolkit
|
var newt Toolkit
|
||||||
|
|
||||||
if (t.uiBox == nil) {
|
if (t.uiBox == nil) {
|
||||||
log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
log.Println("gui.ToolkitNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||||
log.Println("probably could just make a box here?")
|
log.Println("probably could just make a box here?")
|
||||||
os.Exit(0)
|
os.Exit(0)
|
||||||
return nil
|
return nil
|
||||||
|
@ -28,16 +28,23 @@ func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit {
|
||||||
|
|
||||||
s.OnChanged(func(spin *ui.Slider) {
|
s.OnChanged(func(spin *ui.Slider) {
|
||||||
i := spin.Value()
|
i := spin.Value()
|
||||||
log.Println("gui.Toolbox.ui.Slider.OnChanged() val =", i)
|
log.Println("gui.Toolkit.ui.Slider.OnChanged() val =", i)
|
||||||
if (DebugToolkit) {
|
if (DebugToolkit) {
|
||||||
log.Println("gui.Toolbox.ui.OnChanged() val =", i)
|
log.Println("gui.Toolkit.ui.OnChanged() val =", i)
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
scs := spew.ConfigState{MaxDepth: 1}
|
||||||
scs.Dump(newt)
|
scs.Dump(newt)
|
||||||
}
|
}
|
||||||
if (t.OnChanged != nil) {
|
if (newt.OnChanged != nil) {
|
||||||
log.Println("gui.Toolbox.OnChanged() entered val =", i)
|
log.Println("gui.Toolkit.OnChanged() trying to run toolkit.OnChanged() entered val =", i)
|
||||||
newt.OnChanged(&newt)
|
newt.OnChanged(&newt)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
if (newt.Custom != nil) {
|
||||||
|
log.Println("gui.Toolkit.OnChanged() Running toolkit.Custom()")
|
||||||
|
newt.Custom()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
log.Println("gui.Toolkit.OnChanged() ENDED without finding any callback")
|
||||||
})
|
})
|
||||||
|
|
||||||
return &newt
|
return &newt
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
package toolkit
|
|
||||||
|
|
||||||
import "log"
|
|
||||||
|
|
||||||
import "github.com/andlabs/ui"
|
|
||||||
import _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
|
|
||||||
import "github.com/davecgh/go-spew/spew"
|
|
||||||
|
|
||||||
func NewSpinbox(b *ui.Box, name string, x int, y int) *Toolkit {
|
|
||||||
// make new node here
|
|
||||||
log.Println("gui.Toolbox.NewSpinbox()", x, y)
|
|
||||||
var t Toolkit
|
|
||||||
|
|
||||||
if (b == nil) {
|
|
||||||
log.Println("gui.ToolboxNode.NewSpinbox() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
spin := ui.NewSpinbox(x, y)
|
|
||||||
t.uiSpinbox = spin
|
|
||||||
t.uiBox = b
|
|
||||||
t.uiBox.Append(spin, false)
|
|
||||||
|
|
||||||
spin.OnChanged(func(spin *ui.Spinbox) {
|
|
||||||
i := spin.Value()
|
|
||||||
if (DebugToolkit) {
|
|
||||||
log.Println("gui.Toolbox.ui.OnChanged() val =", i)
|
|
||||||
scs := spew.ConfigState{MaxDepth: 1}
|
|
||||||
scs.Dump(t)
|
|
||||||
}
|
|
||||||
if (t.OnChanged != nil) {
|
|
||||||
log.Println("gui.Toolbox.OnChanged() entered val =", i)
|
|
||||||
t.OnChanged(&t)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return &t
|
|
||||||
}
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package toolkit
|
||||||
|
|
||||||
|
import "log"
|
||||||
|
import "os"
|
||||||
|
|
||||||
|
import "github.com/andlabs/ui"
|
||||||
|
import _ "github.com/andlabs/ui/winmanifest"
|
||||||
|
|
||||||
|
import "github.com/davecgh/go-spew/spew"
|
||||||
|
|
||||||
|
// func NewSlider(b *ui.Box, name string *Toolkit {
|
||||||
|
func (t Toolkit) NewSpinner(title string, x int, y int) *Toolkit {
|
||||||
|
// make new node here
|
||||||
|
log.Println("gui.Toolkit.NewSpinner()", x, y)
|
||||||
|
var newt Toolkit
|
||||||
|
|
||||||
|
if (t.uiBox == nil) {
|
||||||
|
log.Println("gui.ToolkitNode.NewSpinner() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||||
|
os.Exit(0)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
s := ui.NewSpinbox(x, y)
|
||||||
|
newt.uiSpinbox = s
|
||||||
|
newt.uiBox = t.uiBox
|
||||||
|
t.uiBox.Append(s, false)
|
||||||
|
|
||||||
|
s.OnChanged(func(s *ui.Spinbox) {
|
||||||
|
i := s.Value()
|
||||||
|
if (DebugToolkit) {
|
||||||
|
log.Println("gui.Toolkit.ui.OnChanged() val =", i)
|
||||||
|
scs := spew.ConfigState{MaxDepth: 1}
|
||||||
|
scs.Dump(newt)
|
||||||
|
}
|
||||||
|
if (t.OnChanged != nil) {
|
||||||
|
log.Println("gui.Toolkit.OnChanged() entered val =", i)
|
||||||
|
newt.OnChanged(&newt)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return &newt
|
||||||
|
}
|
|
@ -30,6 +30,7 @@ type Toolkit struct {
|
||||||
uiBox2 *ui.Box // temporary hack while implementing tabs
|
uiBox2 *ui.Box // temporary hack while implementing tabs
|
||||||
uiButton *ui.Button
|
uiButton *ui.Button
|
||||||
uiControl *ui.Control
|
uiControl *ui.Control
|
||||||
|
uiCombobox *ui.Combobox
|
||||||
uiEntry *ui.Entry
|
uiEntry *ui.Entry
|
||||||
uiGroup *ui.Group
|
uiGroup *ui.Group
|
||||||
uiLabel *ui.Label
|
uiLabel *ui.Label
|
||||||
|
@ -39,6 +40,13 @@ type Toolkit struct {
|
||||||
uiText *ui.EditableCombobox
|
uiText *ui.EditableCombobox
|
||||||
uiWindow *ui.Window
|
uiWindow *ui.Window
|
||||||
UiWindowBad *ui.Window
|
UiWindowBad *ui.Window
|
||||||
|
|
||||||
|
// used as a counter to work around limitations of widgets like combobox
|
||||||
|
// this is probably fucked up and in many ways wrong because of unsafe goroutine threading
|
||||||
|
// but it's working for now due to the need for need for a correct interaction layer betten toolkits
|
||||||
|
c int
|
||||||
|
val map[int]string
|
||||||
|
text string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Toolkit) GetText() string {
|
func (t *Toolkit) GetText() string {
|
||||||
|
@ -53,6 +61,12 @@ func (t *Toolkit) GetText() string {
|
||||||
}
|
}
|
||||||
return t.uiEntry.Text()
|
return t.uiEntry.Text()
|
||||||
}
|
}
|
||||||
|
if (t.uiCombobox != nil) {
|
||||||
|
if (DebugToolkit) {
|
||||||
|
log.Println("gui.Toolkit.GetText() =", t.text)
|
||||||
|
}
|
||||||
|
return t.text
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,6 +145,9 @@ func (t *Toolkit) Dump() {
|
||||||
if (t.uiButton != nil) {
|
if (t.uiButton != nil) {
|
||||||
log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton)
|
log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton)
|
||||||
}
|
}
|
||||||
|
if (t.uiCombobox != nil) {
|
||||||
|
log.Println("gui.Toolkit.Dump() uiCombobox =", t.uiCombobox)
|
||||||
|
}
|
||||||
if (t.uiWindow != nil) {
|
if (t.uiWindow != nil) {
|
||||||
log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow)
|
log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow)
|
||||||
}
|
}
|
||||||
|
@ -144,6 +161,11 @@ func (t *Toolkit) Dump() {
|
||||||
log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider)
|
log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider)
|
||||||
}
|
}
|
||||||
if (t.OnExit != nil) {
|
if (t.OnExit != nil) {
|
||||||
log.Println("gui.Toolkit.Dump() uiExit =", t.OnExit)
|
log.Println("gui.Toolkit.Dump() OnExit =", t.OnExit)
|
||||||
}
|
}
|
||||||
|
if (t.Custom != nil) {
|
||||||
|
log.Println("gui.Toolkit.Dump() Custom =", t.Custom)
|
||||||
|
}
|
||||||
|
log.Println("gui.Toolkit.Dump() c =", t.c)
|
||||||
|
log.Println("gui.Toolkit.Dump() val =", t.val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,21 +25,21 @@ func (t *Toolkit) AddTab(name string) *Toolkit {
|
||||||
var w *ui.Window
|
var w *ui.Window
|
||||||
var newt *Toolkit
|
var newt *Toolkit
|
||||||
|
|
||||||
log.Println("gui.Toolbox.AddTab() sleep 3")
|
log.Println("gui.toolkit.AddTab() sleep 3")
|
||||||
|
|
||||||
w = t.uiWindow
|
w = t.uiWindow
|
||||||
if (w == nil) {
|
if (w == nil) {
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t.uiTab == nil) {
|
if (t.uiTab == nil) {
|
||||||
// this means you have to make a new tab
|
// this means you have to make a new tab
|
||||||
log.Println("gui.Toolbox.NewTab() GOOD. This should be the first tab:", name)
|
log.Println("gui.toolkit.NewTab() GOOD. This should be the first tab:", name)
|
||||||
newt = newTab(w, name)
|
newt = newTab(w, name)
|
||||||
t.uiTab = newt.uiTab
|
t.uiTab = newt.uiTab
|
||||||
} else {
|
} else {
|
||||||
log.Println("gui.Toolbox.NewTab() GOOD. This should be an additional tab:", name)
|
log.Println("gui.toolkit.NewTab() GOOD. This should be an additional tab:", name)
|
||||||
newt = t.appendTab(name)
|
newt = t.appendTab(name)
|
||||||
// this means you have to append a tab
|
// this means you have to append a tab
|
||||||
}
|
}
|
||||||
|
@ -88,17 +88,17 @@ func tabSetMargined(tab *ui.Tab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTab(w *ui.Window, name string) *Toolkit {
|
func newTab(w *ui.Window, name string) *Toolkit {
|
||||||
log.Println("gui.Toolbox.NewTab() ADD", name)
|
log.Println("gui.toolkit.NewTab() ADD", name)
|
||||||
var t Toolkit
|
var t Toolkit
|
||||||
|
|
||||||
if (w == nil) {
|
if (w == nil) {
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Println("gui.Toolbox.AddTab() START name =", name)
|
log.Println("gui.toolkit.AddTab() START name =", name)
|
||||||
// time.Sleep(2 * time.Second)
|
// time.Sleep(2 * time.Second)
|
||||||
tab := ui.NewTab()
|
tab := ui.NewTab()
|
||||||
w.SetMargined(true)
|
w.SetMargined(true)
|
||||||
|
@ -117,17 +117,17 @@ func newTab(w *ui.Window, name string) *Toolkit {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Toolkit) appendTab(name string) *Toolkit {
|
func (t *Toolkit) appendTab(name string) *Toolkit {
|
||||||
log.Println("gui.Toolbox.NewTab() ADD", name)
|
log.Println("gui.toolkit.NewTab() ADD", name)
|
||||||
var newT Toolkit
|
var newT Toolkit
|
||||||
|
|
||||||
if (t.uiWindow == nil) {
|
if (t.uiWindow == nil) {
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
log.Println("gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log.Println("gui.Toolbox.AddTab() START name =", name)
|
log.Println("gui.toolkit.AddTab() START name =", name)
|
||||||
|
|
||||||
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
|
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
|
||||||
// hbox := ui.NewVerticalBox()
|
// hbox := ui.NewVerticalBox()
|
||||||
|
|
|
@ -2,7 +2,6 @@ package toolkit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/andlabs/ui"
|
"github.com/andlabs/ui"
|
||||||
_ "github.com/andlabs/ui/winmanifest"
|
_ "github.com/andlabs/ui/winmanifest"
|
||||||
|
@ -33,8 +32,6 @@ func NewWindow(title string, x int, y int) *Toolkit {
|
||||||
t.Custom()
|
t.Custom()
|
||||||
}
|
}
|
||||||
log.Println("ui.Window().OnExit() Toolkit.OnExit is nil")
|
log.Println("ui.Window().OnExit() Toolkit.OnExit is nil")
|
||||||
t.Dump()
|
|
||||||
os.Exit(0)
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
w.SetMargined(true)
|
w.SetMargined(true)
|
||||||
|
@ -43,3 +40,13 @@ func NewWindow(title string, x int, y int) *Toolkit {
|
||||||
t.UiWindowBad = w // deprecate this as soon as possible
|
t.UiWindowBad = w // deprecate this as soon as possible
|
||||||
return &t
|
return &t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Toolkit) SetWindowTitle(title string) {
|
||||||
|
log.Println("toolkit NewWindow", t.Name, "title", title)
|
||||||
|
win := t.uiWindow
|
||||||
|
if (win != nil) {
|
||||||
|
win.SetTitle(title)
|
||||||
|
} else {
|
||||||
|
log.Println("Setting the window title", title)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,119 @@
|
||||||
|
package gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
var names = make([]string, 100)
|
||||||
|
var nodeNames = make([]string, 100)
|
||||||
|
|
||||||
|
var bugWin *Node
|
||||||
|
/*
|
||||||
|
Creates a window helpful for debugging this package
|
||||||
|
*/
|
||||||
|
func DebugWindow() {
|
||||||
|
Config.Title = "git.wit.org/wit/gui debug fixme"
|
||||||
|
Config.Width = 300
|
||||||
|
Config.Height = 200
|
||||||
|
Config.Exit = StandardClose
|
||||||
|
bugWin = NewWindow()
|
||||||
|
bugWin.DebugTab("WIT GUI Debug Tab")
|
||||||
|
}
|
||||||
|
|
||||||
|
// this function is used by the examples to add a tab
|
||||||
|
// dynamically to the bugWin node
|
||||||
|
// TODO: make this smarter once this uses toolkit/
|
||||||
|
func DebugTab() {
|
||||||
|
if (bugWin == nil) {
|
||||||
|
log.Println("Not sure what window to add this to? Use node.DebugTab() instead")
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bugWin.DebugTab("does this work?")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (n *Node) DebugTab(title string) *Node {
|
||||||
|
var newN, gog, g1, g2, g3, dd *Node
|
||||||
|
|
||||||
|
// time.Sleep(1 * time.Second)
|
||||||
|
newN = n.NewTab(title)
|
||||||
|
newN.Dump()
|
||||||
|
|
||||||
|
gog = newN.NewGroup("GOLANG")
|
||||||
|
gog.NewLabel("go language")
|
||||||
|
gog.AddButton("GO Language Debug", func (*Node) {
|
||||||
|
GolangDebugWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
gog.NewLabel("wit/gui package")
|
||||||
|
gog.AddButton("WIT/GUI Package Debug", func (*Node) {
|
||||||
|
Config.Width = 640
|
||||||
|
Config.Height = 480
|
||||||
|
Queue(DebugWindow)
|
||||||
|
})
|
||||||
|
gog.AddButton("Demo wit/gui", func (*Node) {
|
||||||
|
DemoWindow()
|
||||||
|
})
|
||||||
|
gog.AddButton("Demo toolkit andlabs/ui", func (*Node) {
|
||||||
|
DemoToolkitWindow()
|
||||||
|
})
|
||||||
|
|
||||||
|
g1 = newN.NewGroup("Current Windows")
|
||||||
|
dd = g1.NewDropdown("Window Dropdown")
|
||||||
|
log.Println("dd =", dd)
|
||||||
|
|
||||||
|
var dump = false
|
||||||
|
for _, child := range Config.master.children {
|
||||||
|
log.Println("\t\t", child.id, child.Width, child.Height, child.Name)
|
||||||
|
if (child.parent != nil) {
|
||||||
|
log.Println("\t\t\tparent =",child.parent.id)
|
||||||
|
} else {
|
||||||
|
log.Println("\t\t\tno parent")
|
||||||
|
panic("no parent")
|
||||||
|
}
|
||||||
|
if (dump == true) {
|
||||||
|
child.Dump()
|
||||||
|
}
|
||||||
|
dd.AddDropdown(child.Name)
|
||||||
|
}
|
||||||
|
dd.SetDropdown(0)
|
||||||
|
|
||||||
|
g2 = newN.NewGroup("Debug Window")
|
||||||
|
g2.AddButton("SetMargined(tab)", func (*Node) {
|
||||||
|
log.Println("\tSTART")
|
||||||
|
name := dd.GetText()
|
||||||
|
log.Println("\tENDed with", name)
|
||||||
|
// gw.UiTab.SetMargined(*gw.TabNumber, true)
|
||||||
|
})
|
||||||
|
g2.AddButton("Hide(tab)", func (*Node) {
|
||||||
|
// gw.UiTab.Hide()
|
||||||
|
})
|
||||||
|
g2.AddButton("Show(tab)", func (*Node) {
|
||||||
|
// gw.UiTab.Show()
|
||||||
|
})
|
||||||
|
g2.AddButton("Delete(tab)", func (*Node) {
|
||||||
|
// gw.UiTab.Delete(*gw.TabNumber)
|
||||||
|
})
|
||||||
|
g2.AddButton("change Title", func (*Node) {
|
||||||
|
// mainWindow.SetText("hello world")
|
||||||
|
})
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////
|
||||||
|
g3 = newN.NewGroup("Node Debug")
|
||||||
|
|
||||||
|
g3.AddButton("Node.Dump()", func (n *Node) {
|
||||||
|
n.Dump()
|
||||||
|
})
|
||||||
|
g3.AddButton("Node.ListChildren(false)", func (n *Node) {
|
||||||
|
n.ListChildren(false)
|
||||||
|
})
|
||||||
|
g3.AddButton("Node.ListChildren(true)", func (n *Node) {
|
||||||
|
n.ListChildren(true)
|
||||||
|
})
|
||||||
|
g3.AddButton("AddDebugTab()", func (n *Node) {
|
||||||
|
if (bugWin != nil) {
|
||||||
|
bugWin.DebugTab("added this DebugTab")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return newN
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package gui
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
// import "time"
|
// import "time"
|
||||||
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
// import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
func NewStandardWindow(title string) *Node {
|
func NewStandardWindow(title string) *Node {
|
||||||
log.Println("NewStandardWindow() creating", title)
|
log.Println("NewStandardWindow() creating", title)
|
||||||
|
@ -22,14 +22,15 @@ func NewStandardWindow(title string) *Node {
|
||||||
// right now it shows the andlabs/ui/DemoNumbersPage()
|
// right now it shows the andlabs/ui/DemoNumbersPage()
|
||||||
//
|
//
|
||||||
func DemoToolkitWindow() {
|
func DemoToolkitWindow() {
|
||||||
var w, d *Node
|
var w *Node
|
||||||
var tk *toolkit.Toolkit
|
|
||||||
|
|
||||||
w = NewStandardWindow("Demo of the GUI Toolkit")
|
w = NewStandardWindow("Demo of the GUI Toolkit")
|
||||||
|
|
||||||
d = w.New("demo")
|
// d = w.New("demo")
|
||||||
|
|
||||||
tk = toolkit.DemoNumbersPage(w.uiWindow)
|
w.toolkit.DemoNumbersPage()
|
||||||
|
/*
|
||||||
|
tk = w.Toolkit.DemoNumbersPage()
|
||||||
tk.OnChanged = func(t *toolkit.Toolkit) {
|
tk.OnChanged = func(t *toolkit.Toolkit) {
|
||||||
log.Println("toolkit.NewSlider() value =", t.Value())
|
log.Println("toolkit.NewSlider() value =", t.Value())
|
||||||
if (d.OnChanged != nil) {
|
if (d.OnChanged != nil) {
|
||||||
|
@ -38,6 +39,7 @@ func DemoToolkitWindow() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.Toolkit = tk
|
d.Toolkit = tk
|
||||||
|
*/
|
||||||
|
|
||||||
log.Println("ToolkitDemoWindow() END")
|
log.Println("ToolkitDemoWindow() END")
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@ func StandardClose(n *Node) {
|
||||||
// origlog.Println("Should Exit Here")
|
// origlog.Println("Should Exit Here")
|
||||||
// closed = true
|
// closed = true
|
||||||
log.Println("")
|
log.Println("")
|
||||||
log.Println("STANDARD WINDOW CLOSE")
|
log.Println("STANDARD WINDOW CLOSE. Should not exit app.")
|
||||||
log.Println("")
|
log.Println("")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
126
window.go
126
window.go
|
@ -2,103 +2,10 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
// "github.com/andlabs/ui"
|
|
||||||
// _ "github.com/andlabs/ui/winmanifest"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||||
|
|
||||||
/*
|
|
||||||
func MessageWindow(gw *GuiWindow, msg1 string, msg2 string) {
|
|
||||||
ui.MsgBox(gw.UiWindow, msg1, msg2)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ErrorWindow(gw *GuiWindow, msg1 string, msg2 string) {
|
|
||||||
ui.MsgBoxError(gw.UiWindow, msg1, msg2)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func DeleteWindow(name string) {
|
|
||||||
log.Println("gui.DeleteWindow() START name =", name)
|
|
||||||
window := Data.WindowMap[name]
|
|
||||||
if window == nil {
|
|
||||||
log.Println("gui.DeleteWindow() NO WINDOW WITH name =", name)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("gui.DumpBoxes() MAP: ", name)
|
|
||||||
log.Println("gui.DumpBoxes()\tWindow.name =", window.Name)
|
|
||||||
if window.TabNumber == nil {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber = nil")
|
|
||||||
}
|
|
||||||
tab := *window.TabNumber
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber =", tab)
|
|
||||||
log.Println("gui.DumpBoxes() \tSHOULD DELETE TAB", tab, "HERE")
|
|
||||||
log.Println("gui.DeleteWindow() \tSHOULD DELETE TAB", tab, "HERE")
|
|
||||||
log.Println("gui.DumpBoxes() \tUiTab =", window.UiTab)
|
|
||||||
tabnum := window.UiTab.NumPages()
|
|
||||||
log.Println("gui.DumpBoxes() \tUiTab.NumPages() =", tabnum)
|
|
||||||
if (tabnum > 0) {
|
|
||||||
window.UiTab.Delete(tab)
|
|
||||||
}
|
|
||||||
delete(Data.WindowMap, name)
|
|
||||||
|
|
||||||
// renumber tabs here
|
|
||||||
for name, window := range Data.WindowMap {
|
|
||||||
log.Println("gui.DumpBoxes() MAP: ", name)
|
|
||||||
if window.TabNumber == nil {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber = nil")
|
|
||||||
} else {
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber =", *window.TabNumber)
|
|
||||||
if tab < *window.TabNumber {
|
|
||||||
log.Println("gui.DumpBoxes() \tSubtracting 1 from TabNumber")
|
|
||||||
*window.TabNumber -= 1
|
|
||||||
log.Println("gui.DumpBoxes() \tWindows.TabNumber is now =", *window.TabNumber)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// func mapWindowOld(parent *Node, window *ui.Window, title string, x int, y int) *Node {
|
|
||||||
func mapWindow(title string, w int, h int) *Node {
|
|
||||||
log.Println("gui.WindowMap START title =", title)
|
|
||||||
if Data.WindowMap[title] != nil {
|
|
||||||
log.Println("Data.WindowMap[title] already exists title =", title)
|
|
||||||
title = title + Config.prefix + strconv.Itoa(Config.counter)
|
|
||||||
Config.counter += 1
|
|
||||||
}
|
|
||||||
if Data.WindowMap[title] != nil {
|
|
||||||
log.Println("Data.WindowMap[title] already exists title =", title)
|
|
||||||
panic("Data.WindowMap[newGuiWindow.Name] already exists")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var newGuiWindow GuiWindow
|
|
||||||
newGuiWindow.Width = w
|
|
||||||
newGuiWindow.Height = h
|
|
||||||
newGuiWindow.Name = title
|
|
||||||
// newGuiWindow.UiWindow = window
|
|
||||||
|
|
||||||
newGuiWindow.BoxMap = make(map[string]*GuiBox)
|
|
||||||
newGuiWindow.EntryMap = make(map[string]*GuiEntry)
|
|
||||||
|
|
||||||
Data.WindowMap[newGuiWindow.Name] = &newGuiWindow
|
|
||||||
|
|
||||||
var box GuiBox
|
|
||||||
box.Window = &newGuiWindow
|
|
||||||
box.Name = title
|
|
||||||
|
|
||||||
node := addNode(title, w, h)
|
|
||||||
node.box = &box
|
|
||||||
box.node = node
|
|
||||||
|
|
||||||
newGuiWindow.BoxMap["jcarrInitTest"] = &box
|
|
||||||
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
// This routine creates a blank window with a Title and size (W x H)
|
// This routine creates a blank window with a Title and size (W x H)
|
||||||
//
|
//
|
||||||
// This routine can not have any arguements due to the nature of how
|
// This routine can not have any arguements due to the nature of how
|
||||||
|
@ -114,34 +21,21 @@ func NewWindow() *Node {
|
||||||
h := Config.Height
|
h := Config.Height
|
||||||
f := Config.Exit
|
f := Config.Exit
|
||||||
|
|
||||||
n = mapWindow(title, w, h)
|
// Windows are created off of the master node of the Binary Tree
|
||||||
|
n = Config.master.New(title)
|
||||||
n.custom = f
|
n.custom = f
|
||||||
box := n.box
|
|
||||||
log.Println("gui.NewWindow() title = box.Name =", box.Name)
|
|
||||||
|
|
||||||
t = toolkit.NewWindow(title, w, h)
|
t = toolkit.NewWindow(title, w, h)
|
||||||
t.Custom = func () {
|
t.Custom = func () {
|
||||||
log.Println("GOT TO MY CUSTOM EXIT!!!! for window name:", box.Name)
|
log.Println("Got to wit/gui Window Close for window:", title)
|
||||||
f(n)
|
if (n.custom == nil) {
|
||||||
}
|
log.Println("Got to wit/gui Window Close custom() == nil")
|
||||||
n.Toolkit = t
|
|
||||||
n.uiWindow = t.UiWindowBad // this is temporary
|
|
||||||
|
|
||||||
window := n.uiWindow
|
|
||||||
|
|
||||||
/*
|
|
||||||
ui.OnShouldQuit(func() bool {
|
|
||||||
log.Println("createWindow().Destroy() on node.Name =", n.Name)
|
|
||||||
if (f != nil) {
|
|
||||||
f(n)
|
|
||||||
}
|
}
|
||||||
return true
|
log.Println("Got to wit/gui Window Close START custom()")
|
||||||
})
|
n.custom(n)
|
||||||
*/
|
log.Println("Got to wit/gui Window Close END custom()")
|
||||||
|
|
||||||
box.Window.UiWindow = window
|
|
||||||
if(n.uiWindow == nil) {
|
|
||||||
panic("node.uiWindow == nil. This should never happen")
|
|
||||||
}
|
}
|
||||||
|
n.toolkit = t
|
||||||
|
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue