REFACTOR: refactor everything to gui.Node struct
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
2ccc1b518d
commit
f7ead697d3
|
@ -1,2 +1,3 @@
|
|||
*.swp
|
||||
gui-example/gui-example
|
||||
cmds/gui-example/gui-example
|
||||
cmds/gui-demo/gui-demo
|
||||
|
|
10
area.go
10
area.go
|
@ -107,10 +107,10 @@ func (ah GuiArea) KeyEvent(a *ui.Area, ke *ui.AreaKeyEvent) (handled bool) {
|
|||
return false
|
||||
}
|
||||
|
||||
func ShowTextBox(box *GuiBox, newText *ui.AttributedString, custom func(*GuiButton), name string) {
|
||||
func (b *GuiBox) ShowTextBox(newText *ui.AttributedString, custom func(*GuiButton), name string) {
|
||||
log.Println("ShowTextBox() START")
|
||||
|
||||
gw := box.Window
|
||||
gw := b.Window
|
||||
if (gw == nil) {
|
||||
log.Println("ShowTextBox() ERROR gw = nil")
|
||||
return
|
||||
|
@ -127,10 +127,10 @@ func ShowTextBox(box *GuiBox, newText *ui.AttributedString, custom func(*GuiButt
|
|||
*/
|
||||
|
||||
// TODO: allow padded & axis here
|
||||
box.UiBox.SetPadded(true)
|
||||
b.UiBox.SetPadded(true)
|
||||
|
||||
// add(gw.BoxMap["MAINBOX"], newbox)
|
||||
|
||||
makeGenericArea(box, newText, custom)
|
||||
box.UiBox.Append(box.Window.Area.UiArea, true)
|
||||
makeGenericArea(b, newText, custom)
|
||||
b.UiBox.Append(b.Window.Area.UiArea, true)
|
||||
}
|
||||
|
|
110
box.go
110
box.go
|
@ -1,6 +1,7 @@
|
|||
package gui
|
||||
|
||||
import "log"
|
||||
import "os"
|
||||
// import "reflect"
|
||||
|
||||
import "github.com/andlabs/ui"
|
||||
|
@ -34,6 +35,7 @@ func add(box *GuiBox, newbox *GuiBox) {
|
|||
|
||||
newbox.Window.BoxMap["MAINBOX"] = newbox
|
||||
log.Println("gui.add() END")
|
||||
panic("gui.add() MAINBOX gui.add() END")
|
||||
return
|
||||
} else {
|
||||
log.Println("\tgui.add() ERROR DONT KNOW HOW TO ADD TO A RAW WINDOW YET")
|
||||
|
@ -41,33 +43,77 @@ func add(box *GuiBox, newbox *GuiBox) {
|
|||
}
|
||||
log.Println("\tgui.add() ERROR DON'T KNOW HOW TO add to Window as MAINBOX DONE")
|
||||
log.Println("gui.add() END")
|
||||
panic("gui.add() gui.add() END")
|
||||
return
|
||||
}
|
||||
log.Println("\tgui.add() adding", newbox.Name, "to", box.Name)
|
||||
// copy the box settings over
|
||||
newbox.Window = box.Window
|
||||
if (box.UiBox == nil) {
|
||||
log.Println("\tgui.add() ERROR box.UiBox == nil")
|
||||
panic("crap")
|
||||
if (box.node == nil) {
|
||||
box.Dump()
|
||||
panic("gui.add() ERROR box.node == nil")
|
||||
}
|
||||
|
||||
if (newbox.UiBox == nil) {
|
||||
log.Println("\tgui.add() ERROR newbox.UiBox == nil")
|
||||
panic("crap")
|
||||
panic("gui.add() ERROR newbox.UiBox == nil")
|
||||
}
|
||||
|
||||
if (box.UiBox == nil) {
|
||||
box.Dump()
|
||||
// panic("gui.add() ERROR box.UiBox == nil")
|
||||
return
|
||||
// TODO: fix this whole add() function // Oct 9
|
||||
}
|
||||
// log.Println("\tgui.add() newbox.UiBox == ", newbox.UiBox.GetParent())
|
||||
// spew.Dump(newbox.UiBox)
|
||||
box.UiBox.Append(newbox.UiBox, false)
|
||||
box.Dump()
|
||||
panic("gui.add()")
|
||||
|
||||
// add the newbox to the Window.BoxMap[]
|
||||
box.Window.BoxMap[newbox.Name] = newbox
|
||||
log.Println("gui.add() END")
|
||||
}
|
||||
|
||||
func NewBox(box *GuiBox, axis int, name string) *GuiBox {
|
||||
log.Println("VerticalBox START")
|
||||
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.makeNode(name, 111, 100 + Config.counter)
|
||||
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 (b *GuiBox) NewBox(axis int, name string) *GuiBox {
|
||||
log.Println("gui.NewBox() START")
|
||||
n := b.FindNode()
|
||||
if (n == nil) {
|
||||
log.Println("gui.NewBox() SERIOUS ERROR. CAN NOT FIND NODE")
|
||||
os.Exit(0)
|
||||
} else {
|
||||
log.Println("gui.NewBox() node =", n.Name)
|
||||
}
|
||||
var newbox *GuiBox
|
||||
newbox = new(GuiBox)
|
||||
newbox.Window = box.Window
|
||||
newbox.Window = b.Window
|
||||
newbox.Name = name
|
||||
|
||||
var uiBox *ui.Box
|
||||
|
@ -78,13 +124,18 @@ func NewBox(box *GuiBox, axis int, name string) *GuiBox {
|
|||
}
|
||||
uiBox.SetPadded(true)
|
||||
newbox.UiBox = uiBox
|
||||
add(box, newbox)
|
||||
add(b, newbox)
|
||||
// panic("gui.NewBox")
|
||||
return newbox
|
||||
}
|
||||
|
||||
func HardBox(gw *GuiWindow, axis int, name string) *GuiBox {
|
||||
log.Println("HardBox() START axis =", axis)
|
||||
|
||||
if (gw.node == nil) {
|
||||
gw.Dump()
|
||||
panic("gui.HardBox() gw.node == nil")
|
||||
}
|
||||
// add a Vertical Seperator if there is already a box
|
||||
// Is this right?
|
||||
box := gw.BoxMap["MAINBOX"]
|
||||
|
@ -134,3 +185,40 @@ func VerticalBreak(box *GuiBox) {
|
|||
tmp := ui.NewVerticalSeparator()
|
||||
box.UiBox.Append(tmp, false)
|
||||
}
|
||||
|
||||
func (n *Node) AddComboBox(title string, s ...string) *Node {
|
||||
box := n.uiBox
|
||||
if (box == nil) {
|
||||
return n
|
||||
}
|
||||
|
||||
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 + "'")
|
||||
})
|
||||
|
||||
box.Append(ecbox, false)
|
||||
|
||||
newNode := n.AddNode(title)
|
||||
newNode.uiText = ecbox
|
||||
return newNode
|
||||
}
|
||||
|
||||
func (n *Node) OnChanged(f func()) {
|
||||
f()
|
||||
}
|
||||
|
||||
func (n *Node) GetText() string {
|
||||
if (n.uiText == nil) {
|
||||
return ""
|
||||
}
|
||||
ecbox := n.uiText
|
||||
return ecbox.Text()
|
||||
}
|
||||
|
|
56
button.go
56
button.go
|
@ -1,10 +1,12 @@
|
|||
package gui
|
||||
|
||||
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
|
||||
|
@ -50,6 +52,60 @@ func guiButtonClick(button *GuiButton) {
|
|||
}
|
||||
}
|
||||
|
||||
func (n *Node) AddButton(name string, custom func(*Node)) *Node {
|
||||
if (n.uiBox == nil) {
|
||||
log.Println("gui.Node.AppendButton() filed node.UiBox == nil")
|
||||
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.makeNode(name, 888, 888 + Config.counter)
|
||||
newNode.uiButton = button
|
||||
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
|
||||
}
|
||||
|
||||
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 CreateButton(box *GuiBox, custom func(*GuiButton), name string, values interface {}) *GuiButton {
|
||||
newUiB := ui.NewButton(name)
|
||||
newUiB.OnClicked(defaultButtonClick)
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
run: build
|
||||
./gui-demo
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go build
|
|
@ -0,0 +1,33 @@
|
|||
package main
|
||||
|
||||
import "log"
|
||||
|
||||
import "git.wit.org/wit/gui"
|
||||
|
||||
func demoClick (n *gui.Node) {
|
||||
log.Println("demoClick() Dumping node:")
|
||||
n.Dump()
|
||||
}
|
||||
|
||||
func addDemoTab(n *gui.Node, title string) {
|
||||
newNode := n.AddTab(title, nil)
|
||||
if (gui.Config.Debug) {
|
||||
newNode.Dump()
|
||||
}
|
||||
newNode.ListChildren(false)
|
||||
|
||||
groupNode1 := newNode.AddGroup("group 1")
|
||||
groupNode1.AddComboBox("demoCombo1", "foo", "bar", "stuff")
|
||||
groupNode1.AddComboBox("demoCombo3", "foo 3", "bar", "stuff")
|
||||
|
||||
groupNode1.Dump()
|
||||
|
||||
butNode1 := groupNode1.AddButton("button1", demoClick)
|
||||
butNode1.Dump()
|
||||
|
||||
butNode2 := groupNode1.AddButton("button2", demoClick)
|
||||
butNode2.Dump()
|
||||
|
||||
groupNode2 := newNode.AddGroup("group 2")
|
||||
groupNode2.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
// This initializes the first window
|
||||
//
|
||||
// Then starts a goroutine to demonstrate how to
|
||||
// inject things into the GUI
|
||||
func main() {
|
||||
log.Println("Starting my Control Panel")
|
||||
|
||||
go gui.Main(initGUI)
|
||||
|
||||
watchGUI()
|
||||
}
|
||||
|
||||
// This initializes the first window
|
||||
func initGUI() {
|
||||
gui.Config.Title = "WIT GUI Window Demo 1"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
gui.Config.Exit = myExit
|
||||
node1 := gui.NewWindow()
|
||||
addDemoTab(node1, "A Simple Tab Demo")
|
||||
|
||||
gui.Config.Title = "WIT GUI Window Demo 2"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 240
|
||||
gui.Config.Exit = myExit
|
||||
node2 := gui.NewWindow()
|
||||
node2.DemoAndlabsUiTab("A Simple andlabs/ui Tab Demo")
|
||||
}
|
||||
|
||||
// This demonstrates how to properly interact with the GUI
|
||||
// You can not involke the GUI from external goroutines in most cases.
|
||||
func watchGUI() {
|
||||
var i = 1
|
||||
for {
|
||||
log.Println("Waiting", i, "seconds")
|
||||
i += 1
|
||||
time.Sleep(1 * time.Second)
|
||||
if i == 4 {
|
||||
log.Println("Opening a Debug Window via the gui.Queue()")
|
||||
gui.Config.Width = 800
|
||||
gui.Config.Height = 300
|
||||
gui.Config.Exit = myDebugExit
|
||||
gui.Queue(gui.DebugWindow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func myExit(n *gui.Node) {
|
||||
log.Println()
|
||||
log.Println("Entered myExit() on node.Name =", n.Name)
|
||||
log.Println()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func myDebugExit(n *gui.Node) {
|
||||
log.Println("Entered myDebugExit() on node.Name =", n.Name)
|
||||
log.Println("Don't actually os.Exit()")
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
package main
|
||||
|
||||
import "log"
|
||||
import "reflect"
|
||||
|
||||
import "git.wit.org/wit/gui"
|
||||
|
||||
import "github.com/davecgh/go-spew/spew"
|
||||
|
||||
func demoClick (n *gui.Node) {
|
||||
log.Println("demoClick() Dumping node:")
|
||||
n.Dump()
|
||||
}
|
||||
|
||||
var username = "jcarr"
|
||||
var hostname = "fire"
|
||||
|
||||
func newClick (n *gui.Node) {
|
||||
var tmp []string
|
||||
junk := "ssh -v " + username + "@" + hostname
|
||||
log.Println("junk = " , junk)
|
||||
xterm(junk)
|
||||
log.Println("tmp = " , reflect.ValueOf(tmp).Kind())
|
||||
// spew.Dump(tmp)
|
||||
}
|
||||
|
||||
func addDemoTab(n *gui.Node, title string) {
|
||||
newNode := n.AddTab(title, nil)
|
||||
if (gui.Config.Debug) {
|
||||
newNode.Dump()
|
||||
}
|
||||
newNode.ListChildren(false)
|
||||
|
||||
groupNode1 := newNode.AddGroup("group 1")
|
||||
cbNode := groupNode1.AddComboBox("username", "root", "jcarr", "hugo")
|
||||
cbNode.OnChanged(func () {
|
||||
username = cbNode.GetText()
|
||||
})
|
||||
groupNode1.AddComboBox("demoCombo3", "foo 3", "bar", "stuff")
|
||||
|
||||
groupNode1.Dump()
|
||||
|
||||
butNode1 := groupNode1.AddButton("button1", demoClick)
|
||||
butNode1.Dump()
|
||||
|
||||
butNode2 := groupNode1.AddButton("button2", newClick)
|
||||
butNode2.Dump()
|
||||
|
||||
groupNode2 := newNode.AddGroup("group 2")
|
||||
groupNode2.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
||||
|
||||
gNode := newNode.AddGroup("domU")
|
||||
makeSSHbutton(gNode, "hugo@www", "www.wit.org")
|
||||
makeSSHbutton(gNode, "check.lab", "check.lab.wit.org")
|
||||
makeSSHbutton(gNode, "gobuild.lab", "gobuild.lab.wit.org")
|
||||
makeSSHbutton(gNode, "gobuild2.lab", "gobuild2.lab.wit.org")
|
||||
|
||||
/////////////////////////////// Column DNS ////////////////////////////////
|
||||
gNode = newNode.AddGroup("dns")
|
||||
makeSSHbutton(gNode, "bind.wit.org", "bind.wit.org")
|
||||
makeSSHbutton(gNode, "ns1.wit.com", "ns1.wit.com")
|
||||
makeSSHbutton(gNode, "ns2.wit.com", "ns2.wit.com")
|
||||
makeSSHbutton(gNode, "coredns", "coredns.lab.wit.org")
|
||||
|
||||
/////////////////////////////// PHYS 530 //////////////////////////////////
|
||||
gNode = newNode.AddGroup("phys 530")
|
||||
// makeXtermButton(gNode, "openwrt", "SUBDOMAIN", "ssh -4 -v root@openwrt")
|
||||
gNode.AddButton("openwrt", func (*gui.Node) {
|
||||
stuff := "ssh -4 -v root@openwrt"
|
||||
xterm(stuff)
|
||||
})
|
||||
makeSSHbutton (gNode, "mirrors", "mirrors.wit.org")
|
||||
makeSSHbutton (gNode, "node004", "node004.lab.wit.org")
|
||||
makeSSHbutton (gNode, "lenovo-z70", "lenovo-z70.lab.wit.org")
|
||||
|
||||
/////////////////////////////// PHYS 522 //////////////////////////////////
|
||||
gNode = newNode.AddGroup("phys 522")
|
||||
// makeXtermButton(gNode, "openwrt2", "SUBDOMAIN", "ssh -4 -v root@openwrt2")
|
||||
gNode.AddButton("openwrt2", func (*gui.Node) {
|
||||
stuff := "ssh -4 -v root@openwrt2"
|
||||
xterm(stuff)
|
||||
})
|
||||
makeSSHbutton (gNode, "fire.lab", "fire.lab.wit.org")
|
||||
makeSSHbutton (gNode, "predator", "predator.lab.wit.org")
|
||||
|
||||
/////////////////////////////// FLOAT /////////////////////////////////////
|
||||
gNode = newNode.AddGroup("float")
|
||||
makeSSHbutton(gNode, "root@asus-n501vw", "asus-n501vw.lab.wit.org")
|
||||
}
|
||||
|
||||
func makeSSHbutton (n *gui.Node, name string, hostname string) {
|
||||
bNode := n.AddButton(name, func (*gui.Node) {
|
||||
var tmp []string
|
||||
if (username == "") {
|
||||
username = "root"
|
||||
}
|
||||
junk := "ssh -v " + username + "@" + hostname
|
||||
log.Println("junk = " , junk)
|
||||
log.Println("username = '" + username + "'")
|
||||
xterm(junk)
|
||||
log.Println("tmp = " , reflect.ValueOf(tmp).Kind())
|
||||
spew.Dump(tmp)
|
||||
})
|
||||
bNode.Dump()
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
// This initializes the first window
|
||||
//
|
||||
// Then starts a goroutine to demonstrate how to
|
||||
// inject things into the GUI
|
||||
func main() {
|
||||
log.Println("Starting my Control Panel")
|
||||
|
||||
go gui.Main(initGUI)
|
||||
|
||||
watchGUI()
|
||||
}
|
||||
|
||||
// This initializes the first window
|
||||
func initGUI() {
|
||||
gui.Config.Title = "WIT GUI Window Demo 1"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
gui.Config.Exit = myExit
|
||||
node1 := gui.NewWindow()
|
||||
addDemoTab(node1, "A Simple Tab Demo")
|
||||
|
||||
gui.Config.Title = "WIT GUI Window Demo 2"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 240
|
||||
gui.Config.Exit = myExit
|
||||
node2 := gui.NewWindow()
|
||||
node2.DemoAndlabsUiTab("A Simple andlabs/ui Tab Demo")
|
||||
}
|
||||
|
||||
// This demonstrates how to properly interact with the GUI
|
||||
// You can not involke the GUI from external goroutines in most cases.
|
||||
func watchGUI() {
|
||||
var i = 1
|
||||
for {
|
||||
log.Println("Waiting", i, "seconds")
|
||||
i += 1
|
||||
time.Sleep(1 * time.Second)
|
||||
if i == 4 {
|
||||
log.Println("Opening a Debug Window via the gui.Queue()")
|
||||
gui.Config.Width = 800
|
||||
gui.Config.Height = 300
|
||||
gui.Config.Exit = myDebugExit
|
||||
gui.Queue(gui.DebugWindow)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func myExit(n *gui.Node) {
|
||||
log.Println()
|
||||
log.Println("Entered myExit() on node.Name =", n.Name)
|
||||
log.Println()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func myDebugExit(n *gui.Node) {
|
||||
log.Println("Entered myDebugExit() on node.Name =", n.Name)
|
||||
log.Println("Don't actually os.Exit()")
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
package main
|
||||
|
||||
import "log"
|
||||
import "strings"
|
||||
import "os"
|
||||
import "os/exec"
|
||||
import "io/ioutil"
|
||||
import "errors"
|
||||
// import "bufio"
|
||||
|
||||
// import "github.com/davecgh/go-spew/spew"
|
||||
|
||||
/*
|
||||
import "time"
|
||||
import "runtime"
|
||||
import "runtime/debug"
|
||||
import "runtime/pprof"
|
||||
|
||||
import "git.wit.org/wit/gui"
|
||||
import "git.wit.org/wit/shell"
|
||||
import "github.com/gobuffalo/packr"
|
||||
*/
|
||||
|
||||
func runSimpleCommand(s string) {
|
||||
cmd := strings.TrimSpace(s) // this is like 'chomp' in perl
|
||||
cmd = strings.TrimSuffix(cmd, "\n") // this is like 'chomp' in perl
|
||||
cmdArgs := strings.Fields(cmd)
|
||||
runLinuxCommand(cmdArgs)
|
||||
}
|
||||
|
||||
var geom string = "120x30+500+500"
|
||||
|
||||
func xterm(cmd string) {
|
||||
var tmp []string
|
||||
var argsXterm = []string{"nohup", "xterm", "-geometry", geom}
|
||||
tmp = append(argsXterm, "-hold", "-e", cmd)
|
||||
log.Println("xterm cmd=", cmd)
|
||||
go runCommand(tmp)
|
||||
}
|
||||
|
||||
func runCommand(cmdArgs []string) {
|
||||
log.Println("runCommand() START", cmdArgs)
|
||||
process := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
|
||||
// process := exec.Command("xterm", "-e", "ping localhost")
|
||||
log.Println("runCommand() process.Start()")
|
||||
process.Start()
|
||||
log.Println("runCommand() process.Wait()")
|
||||
err := process.Wait()
|
||||
lookupError(err)
|
||||
log.Println("runCommand() NEED TO CHECK THE TIME HERE TO SEE IF THIS WORKED")
|
||||
log.Println("runCommand() OTHERWISE INFORM THE USER")
|
||||
log.Println("runCommand() END", cmdArgs)
|
||||
}
|
||||
|
||||
func lookupError(err error) {
|
||||
var (
|
||||
ee *exec.ExitError
|
||||
pe *os.PathError
|
||||
)
|
||||
|
||||
if errors.As(err, &ee) {
|
||||
log.Println("ran, but non-zero exit code =", ee.ExitCode()) // ran, but non-zero exit code
|
||||
} else if errors.As(err, &pe) {
|
||||
log.Printf("os.PathError = %v", pe) // "no such file ...", "permission denied" etc.
|
||||
} else if err != nil {
|
||||
log.Printf("something really bad happened general err = %v", err) // something really bad happened!
|
||||
if exitError, ok := err.(*exec.ExitError); ok {
|
||||
log.Printf("exitError.ExitCode() is %d\n", exitError.ExitCode())
|
||||
}
|
||||
} else {
|
||||
log.Println("success! // ran without error (exit code zero)")
|
||||
}
|
||||
}
|
||||
|
||||
func runLinuxCommand(cmdArgs []string) (string, error) {
|
||||
process := exec.Command(cmdArgs[0], cmdArgs[1:len(cmdArgs)]...)
|
||||
|
||||
process.Stdin = os.Stdin
|
||||
process.Stderr = os.Stderr
|
||||
|
||||
stdOut, err := process.StdoutPipe()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err := process.Start(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
bytes, err := ioutil.ReadAll(stdOut)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = process.Wait()
|
||||
lookupError(err)
|
||||
|
||||
log.Println(string(bytes))
|
||||
return string(bytes), err
|
||||
}
|
|
@ -2,6 +2,8 @@ package gui
|
|||
|
||||
import (
|
||||
"log"
|
||||
// "fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/andlabs/ui"
|
||||
_ "github.com/andlabs/ui/winmanifest"
|
||||
|
@ -9,22 +11,36 @@ import (
|
|||
)
|
||||
|
||||
var names = make([]string, 100)
|
||||
var nodeNames = make([]string, 100)
|
||||
|
||||
func makeWindowDebug() ui.Control {
|
||||
func DebugWindow() {
|
||||
Config.Title = "DebugWindow()"
|
||||
node := NewWindow()
|
||||
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 addNodeName(c *ui.Combobox, s string, id string) {
|
||||
c.Append(s)
|
||||
nodeNames[y] = id
|
||||
y = y + 1
|
||||
}
|
||||
|
||||
func makeWindowDebug() *ui.Box {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
vbox := addGroup(hbox, "Numbers")
|
||||
pbar := ui.NewProgressBar()
|
||||
vbox.Append(pbar, false)
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
vbox = addGroup(hbox, "Window")
|
||||
vbox := addGroup(hbox, "range Data.WindowMap")
|
||||
cbox := ui.NewCombobox()
|
||||
|
||||
for name, _ := range Data.WindowMap {
|
||||
log.Println("range Data.WindowMap() name =", name)
|
||||
if (Config.Debug) {
|
||||
log.Println("range Data.WindowMap() name =", name)
|
||||
}
|
||||
addName(cbox, name)
|
||||
}
|
||||
cbox.SetSelected(0)
|
||||
|
@ -122,6 +138,11 @@ func makeWindowDebug() ui.Control {
|
|||
/////////////////////////////////////////////////////
|
||||
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()
|
||||
|
@ -132,11 +153,112 @@ func makeWindowDebug() ui.Control {
|
|||
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 + ")"
|
||||
addNodeName(nodeCombo, tmp, node.id)
|
||||
}
|
||||
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")
|
||||
}
|
||||
})
|
||||
|
||||
n1 = addButton(vbox, "Node.DemoAndlabsUiTab")
|
||||
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.DemoAndlabsUiTab("ran gui.AddDemoAndlabsUiTab() " + strconv.Itoa(Config.counter))
|
||||
}
|
||||
})
|
||||
|
||||
return hbox
|
||||
}
|
||||
|
||||
// TODO: remove this crap
|
||||
var x int = 0
|
||||
var y int = 0
|
||||
|
||||
// TODO: remove this crap
|
||||
func addName(c *ui.Combobox, s string) {
|
||||
c.Append(s)
|
||||
names[x] = s
|
||||
|
@ -155,33 +277,11 @@ func addGroup(b *ui.Box, name string) *ui.Box {
|
|||
return vbox
|
||||
}
|
||||
|
||||
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 dumpBox(s string) {
|
||||
for name, window := range Data.WindowMap {
|
||||
var name string
|
||||
var window *GuiWindow
|
||||
|
||||
for name, window = range Data.WindowMap {
|
||||
if name != s {
|
||||
continue
|
||||
}
|
||||
|
@ -198,6 +298,7 @@ func dumpBox(s string) {
|
|||
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}
|
||||
|
@ -228,3 +329,27 @@ func addButton(box *ui.Box, name string) *ui.Button {
|
|||
box.Append(button, false)
|
||||
return button
|
||||
}
|
||||
|
||||
func (n *Node) DebugTab(title string) {
|
||||
newNode := n.AddTab(title, makeWindowDebug())
|
||||
if (Config.DebugNode) {
|
||||
newNode.Dump()
|
||||
}
|
||||
tabSetMargined(newNode.uiTab)
|
||||
}
|
||||
|
||||
// This sets _all_ the tabs to Margin = true
|
||||
//
|
||||
// TODO: do proper tab tracking (will be complicated). low priority
|
||||
func tabSetMargined(tab *ui.Tab) {
|
||||
if (Config.DebugTabs) {
|
||||
log.Println("tabSetMargined() IGNORE THIS")
|
||||
}
|
||||
c := tab.NumPages()
|
||||
for i := 0; i < c; i++ {
|
||||
if (Config.DebugTabs) {
|
||||
log.Println("tabSetMargined() i =", i)
|
||||
}
|
||||
tab.SetMargined(i, true)
|
||||
}
|
||||
}
|
66
debug.go
66
debug.go
|
@ -8,14 +8,13 @@ import (
|
|||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
// import "reflect"
|
||||
|
||||
// import "github.com/andlabs/ui"
|
||||
// import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
//
|
||||
// Dump out debugging information every 4 seconds
|
||||
// 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
|
||||
|
||||
|
@ -32,6 +31,12 @@ func WatchGUI() {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -106,3 +111,50 @@ func addTableTab() {
|
|||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,19 @@ import "log"
|
|||
import "github.com/andlabs/ui"
|
||||
import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
func makeWindowTemplate() ui.Control {
|
||||
// This will create a tab in a window using direct
|
||||
// calls to andlabs/ui. This can be used to bypass
|
||||
// the obvuscation added in this package if it is desired
|
||||
// or needed.
|
||||
func (n *Node) DemoAndlabsUiTab(title string) {
|
||||
newNode := n.AddTab(title, makeAndlabsUiTab())
|
||||
if (Config.DebugNode) {
|
||||
newNode.Dump()
|
||||
}
|
||||
tabSetMargined(newNode.uiTab)
|
||||
}
|
||||
|
||||
func makeAndlabsUiTab() *ui.Box {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package gui
|
||||
|
||||
// import "log"
|
||||
import "github.com/andlabs/ui"
|
||||
import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
var mybox *ui.Box
|
||||
|
||||
func (n *Node) AddGroup(title string) *Node {
|
||||
if (n == nil) {
|
||||
return nil
|
||||
}
|
||||
hbox := n.uiBox
|
||||
if (hbox == nil) {
|
||||
return n
|
||||
}
|
||||
group := ui.NewGroup(title)
|
||||
group.SetMargined(true)
|
||||
hbox.Append(group, true)
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
vbox.SetPadded(true)
|
||||
group.SetChild(vbox)
|
||||
|
||||
newNode := n.AddNode(title)
|
||||
newNode.uiBox = vbox
|
||||
return newNode
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Package wit/gui implements a abstraction layer for Go visual elements in
|
||||
a cross platform way. Right now, this abstraction is built on top of
|
||||
the GUI toolkit 'andlabs/ui' which does the cross platform support.
|
||||
|
||||
A quick overview of the features, some general design guidelines
|
||||
and principles for how this package should generally work:
|
||||
|
||||
* GUI elements are stored in a tree of nodes
|
||||
* When in doubt, it's ok to guess. We will return something close.
|
||||
* It tries to make your code simple
|
||||
|
||||
Quick Start
|
||||
|
||||
This section demonstrates how to quickly get started with spew. See the
|
||||
sections below for further details on formatting and configuration options.
|
||||
|
||||
To dump a variable with full newlines, indentation, type, and pointer
|
||||
information use Dump, Fdump, or Sdump:
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gui.Main(initGUI)
|
||||
}
|
||||
|
||||
// This initializes the first window
|
||||
func initGUI() {
|
||||
gui.Config.Title = "WIT GUI Window 1"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
node1 := gui.NewWindow()
|
||||
addDemoTab(node1, "A Simple Tab Demo")
|
||||
}
|
||||
|
||||
func addDemoTab(n *gui.Node, title string) {
|
||||
newNode := n.AddTab(title, nil)
|
||||
|
||||
groupNode1 := newNode.AddGroup("group 1")
|
||||
groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
|
||||
}
|
||||
|
||||
Configuration Options
|
||||
|
||||
Configuration of the GUI is handled by fields in the ConfigType type. For
|
||||
convenience, all of the top-level functions use a global state available
|
||||
via the gui.Config global.
|
||||
|
||||
The following configuration options are available:
|
||||
* Width
|
||||
When creating a new window, this is the width
|
||||
|
||||
* Height
|
||||
When creating a new window, this is the height
|
||||
|
||||
* Debug
|
||||
When 'true' log more output
|
||||
|
||||
GUI Usage
|
||||
|
||||
Errors
|
||||
|
||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||
detects them and handles them internally by printing the panic information
|
||||
inline with the output. Since spew is intended to provide deep pretty printing
|
||||
capabilities on structures, it intentionally does not return any errors.
|
||||
*/
|
||||
package gui
|
40
entry.go
40
entry.go
|
@ -13,26 +13,46 @@ func NewLabel(box *GuiBox, text string) {
|
|||
box.Append(ui.NewLabel(text), false)
|
||||
}
|
||||
|
||||
func GetText(box *GuiBox, name string) string {
|
||||
if (box == nil) {
|
||||
log.Println("gui.GetText() ERROR box == nil")
|
||||
return ""
|
||||
}
|
||||
if (box.Window.EntryMap == nil) {
|
||||
func (n *Node) NewLabel(text string) *Node {
|
||||
// make new node here
|
||||
// n.Append(ui.NewLabel(text), false)
|
||||
newNode := makeNode(n, text, 333, 334)
|
||||
newNode.Dump()
|
||||
// panic("node.NewLabel()")
|
||||
|
||||
n.Append(newNode)
|
||||
return newNode
|
||||
}
|
||||
|
||||
func (b *GuiBox) GetText(name string) string {
|
||||
if (b.Window.EntryMap == nil) {
|
||||
log.Println("gui.GetText() ERROR b.Box.Window.EntryMap == nil")
|
||||
return ""
|
||||
}
|
||||
spew.Dump(box.Window.EntryMap)
|
||||
if (box.Window.EntryMap[name] == nil) {
|
||||
spew.Dump(b.Window.EntryMap)
|
||||
if (b.Window.EntryMap[name] == nil) {
|
||||
log.Println("gui.GetText() ERROR box.Window.EntryMap[", name, "] == nil ")
|
||||
return ""
|
||||
}
|
||||
e := box.Window.EntryMap[name]
|
||||
e := b.Window.EntryMap[name]
|
||||
log.Println("gui.GetText() box.Window.EntryMap[", name, "] = ", e.UiEntry.Text())
|
||||
log.Println("gui.GetText() END")
|
||||
return e.UiEntry.Text()
|
||||
}
|
||||
|
||||
func (n *Node) SetText(value string) error {
|
||||
log.Println("gui.SetText() value =", value)
|
||||
if (n.uiText != nil) {
|
||||
n.uiText.SetText(value)
|
||||
return nil
|
||||
}
|
||||
if (n.uiButton != nil) {
|
||||
n.uiButton.SetText(value)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetText(box *GuiBox, name string, value string) error {
|
||||
if (box == nil) {
|
||||
return fmt.Errorf("gui.SetText() ERROR box == nil")
|
||||
|
@ -42,7 +62,7 @@ func SetText(box *GuiBox, name string, value string) error {
|
|||
}
|
||||
spew.Dump(box.Window.EntryMap)
|
||||
if (box.Window.EntryMap[name] == nil) {
|
||||
return fmt.Errorf("gui.SetText() ERROR box.Window.EntryMap[", name, "] == nil ")
|
||||
return fmt.Errorf("gui.SetText() ERROR box.Window.EntryMap[" + name + "] == nil ")
|
||||
}
|
||||
e := box.Window.EntryMap[name]
|
||||
log.Println("gui.SetText() box.Window.EntryMap[", name, "] = ", e.UiEntry.Text())
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package gui_test
|
||||
|
||||
import (
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
// This example demonstrates how to create a NewWindow()
|
||||
//
|
||||
// Interacting with a GUI in a cross platform fashion adds some
|
||||
// unusual problems. To obvuscate those, andlabs/ui starts a
|
||||
// goroutine that interacts with the native gui toolkits
|
||||
// on the Linux, MacOS, Windows, etc.
|
||||
//
|
||||
// Because of this oddity, to initialize a new window, the
|
||||
// function is not passed any arguements and instead passes
|
||||
// the information via the Config type.
|
||||
//
|
||||
func ExampleNewWindow() {
|
||||
// Define the name and size
|
||||
gui.Config.Title = "WIT GUI Window 1"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
|
||||
// Create the Window
|
||||
gui.NewWindow()
|
||||
|
||||
// Output:
|
||||
// You get a window
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
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
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
func customExit(gw *gui.GuiWindow) {
|
||||
log.Println("Should Exit Here")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
func main() {
|
||||
log.Println("starting my Control Panel")
|
||||
|
||||
gui.Config.Width = 800
|
||||
gui.Config.Height = 300
|
||||
gui.Config.Exit = customExit
|
||||
|
||||
go gui.Main(initGUI)
|
||||
|
||||
watchGUI()
|
||||
}
|
||||
|
||||
func initGUI() {
|
||||
gui.NewWindow("jcarr start", 640, 480)
|
||||
}
|
||||
|
||||
func watchGUI() {
|
||||
var i = 1
|
||||
for {
|
||||
log.Println("Waiting for customExit()", i)
|
||||
i += 1
|
||||
time.Sleep(time.Second)
|
||||
if i == 3 {
|
||||
log.Println("Sending ExampleWindow to gui.Queue()")
|
||||
gui.Queue(gui.DebugWindow)
|
||||
}
|
||||
}
|
||||
}
|
8
gui.go
8
gui.go
|
@ -18,6 +18,14 @@ func init() {
|
|||
|
||||
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() {
|
||||
|
|
28
main.go
28
main.go
|
@ -12,7 +12,7 @@ func Main(f func()) {
|
|||
ui.Main(f)
|
||||
}
|
||||
|
||||
// Other goroutines must use this
|
||||
// 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
|
||||
|
@ -23,28 +23,12 @@ func Queue(f func()) {
|
|||
ui.QueueMain(f)
|
||||
}
|
||||
|
||||
/*
|
||||
func ExampleWindow() {
|
||||
log.Println("START gui.ExampleWindow()")
|
||||
|
||||
title := "Test Window"
|
||||
box := InitWindow(nil, title, 0)
|
||||
window := box.Window
|
||||
log.Println("box =", box)
|
||||
log.Println("window =", window)
|
||||
box.AddDebugTab("jcarr Debug")
|
||||
|
||||
window.UiWindow.Show()
|
||||
}
|
||||
|
||||
func DebugWindow() {
|
||||
log.Println("START gui.ExampleWindow()")
|
||||
|
||||
title := "Debug Window"
|
||||
box := InitWindow(nil, title, 0)
|
||||
window := box.Window
|
||||
log.Println("box =", box)
|
||||
log.Println("window =", window)
|
||||
box.AddDebugTab("jcarr Debug")
|
||||
|
||||
window.UiWindow.Show()
|
||||
Config.Title = "ExampleWindow"
|
||||
node := NewWindow()
|
||||
node.AddDebugTab("jcarr Debug")
|
||||
}
|
||||
*/
|
||||
|
|
249
new-structs.go
249
new-structs.go
|
@ -2,12 +2,42 @@ package gui
|
|||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
// "reflect"
|
||||
|
||||
// "github.com/davecgh/go-spew/spew"
|
||||
|
||||
"github.com/andlabs/ui"
|
||||
_ "github.com/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
id string
|
||||
|
@ -15,32 +45,227 @@ type Node struct {
|
|||
Width int
|
||||
Height int
|
||||
|
||||
uiType *ui.Control
|
||||
parent *Node
|
||||
children []*Node
|
||||
|
||||
window *GuiWindow
|
||||
box *GuiBox
|
||||
custom func(*Node)
|
||||
|
||||
uiControl *ui.Control
|
||||
uiButton *ui.Button
|
||||
uiWindow *ui.Window
|
||||
uiTab *ui.Tab
|
||||
uiBox *ui.Box
|
||||
uiText *ui.EditableCombobox
|
||||
}
|
||||
|
||||
func (n Node) SetName(name string) {
|
||||
func (n *Node) Parent() *Node {
|
||||
return n.parent
|
||||
}
|
||||
|
||||
func (n *Node) Window() *Node {
|
||||
return n.parent
|
||||
}
|
||||
|
||||
func (n *Node) Dump() {
|
||||
log.Println("gui.Node.Dump() id = ", n.id)
|
||||
log.Println("gui.Node.Dump() Name = ", n.Name)
|
||||
log.Println("gui.Node.Dump() Width = ", n.Width)
|
||||
log.Println("gui.Node.Dump() Height = ", n.Height)
|
||||
|
||||
if (n.parent == nil) {
|
||||
log.Println("gui.Node.Dump() parent = nil")
|
||||
} else {
|
||||
log.Println("gui.Node.Dump() parent = ", n.parent.id)
|
||||
}
|
||||
log.Println("gui.Node.Dump() children = ", n.children)
|
||||
|
||||
log.Println("gui.Node.Dump() window = ", n.window)
|
||||
log.Println("gui.Node.Dump() box = ", n.box)
|
||||
|
||||
log.Println("gui.Node.Dump() uiWindow = ", n.uiWindow)
|
||||
log.Println("gui.Node.Dump() uiTab = ", n.uiTab)
|
||||
log.Println("gui.Node.Dump() uiBox = ", n.uiBox)
|
||||
log.Println("gui.Node.Dump() uiControl = ", n.uiControl)
|
||||
log.Println("gui.Node.Dump() uiButton = ", n.uiButton)
|
||||
if (n.id == "") {
|
||||
panic("gui.Node.Dump() id == nil")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func (n *Node) SetBox(box *GuiBox) {
|
||||
n.box = box
|
||||
}
|
||||
|
||||
func (n *Node) SetName(name string) {
|
||||
// n.uiType.SetName(name)
|
||||
log.Println("n.uiType =", n.uiType)
|
||||
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) {
|
||||
func (n *Node) Append(child *Node) {
|
||||
// if (n.UiBox == nil) {
|
||||
// return
|
||||
// }
|
||||
// n.uiType.Append(child, x)
|
||||
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 findByIdDFS(node *Node, id string) *Node {
|
||||
if node.id == id {
|
||||
return node
|
||||
func (n *Node) List() {
|
||||
findByIdDFS(n, "test")
|
||||
}
|
||||
|
||||
var listChildrenParent *Node
|
||||
var listChildrenDepth int = 0
|
||||
|
||||
func indentPrintln(depth int, format string, a ...interface{}) {
|
||||
var tabs string
|
||||
for i := 0; i < depth; i++ {
|
||||
tabs = tabs + "\t"
|
||||
}
|
||||
|
||||
if len(node.children) > 0 {
|
||||
for _, child := range node.children {
|
||||
findByIdDFS(child, id)
|
||||
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
||||
newFormat := tabs + format
|
||||
log.Println(newFormat, a)
|
||||
}
|
||||
|
||||
func (n *Node) ListChildren(dump bool) {
|
||||
indentPrintln(listChildrenDepth, "\t", 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 nil
|
||||
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
|
||||
}
|
||||
|
||||
// The parent Node needs to be the raw Window
|
||||
// The 'stuff' Node needs to be the contents of the tab
|
||||
//
|
||||
// This function should make a new node with the parent and
|
||||
// the 'stuff' Node as a child
|
||||
func (n *Node) AddTabNode(title string, b *GuiBox) *Node {
|
||||
var newNode *Node
|
||||
parent := n
|
||||
|
||||
newNode = parent.makeNode(title, 444, 400 + Config.counter)
|
||||
newNode.uiTab = parent.uiTab
|
||||
newNode.box = b
|
||||
|
||||
if (Config.DebugNode) {
|
||||
fmt.Println("")
|
||||
log.Println("parent:")
|
||||
parent.Dump()
|
||||
|
||||
fmt.Println("")
|
||||
log.Println("newNode:")
|
||||
newNode.Dump()
|
||||
}
|
||||
|
||||
if (newNode.uiTab == nil) {
|
||||
log.Println("wit/gui/ AddTabNode() Something went wrong tab == nil")
|
||||
// TODO: try to find the tab or window and make them if need be
|
||||
return newNode
|
||||
}
|
||||
newNode.uiTab.Append(title, b.UiBox)
|
||||
|
||||
return newNode
|
||||
}
|
||||
|
||||
func (n *Node) AddTab(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.box == nil {
|
||||
parent.Dump()
|
||||
panic("gui.AddTab() ERROR box == nil")
|
||||
}
|
||||
if parent.uiTab == nil {
|
||||
inittab := ui.NewTab() // no, not that 'inittab'
|
||||
parent.uiWindow.SetChild(inittab)
|
||||
parent.uiWindow.SetMargined(true)
|
||||
parent.uiTab = inittab
|
||||
|
||||
// parent.Dump()
|
||||
// panic("gui.AddTab() ERROR uiTab == nil")
|
||||
}
|
||||
|
||||
tab := parent.uiTab
|
||||
parent.uiWindow.SetMargined(true)
|
||||
|
||||
if (uiC == nil) {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
uiC = hbox
|
||||
}
|
||||
tab.Append(title, uiC)
|
||||
|
||||
newNode := parent.makeNode(title, 555, 600 + Config.counter)
|
||||
newNode.uiTab = tab
|
||||
newNode.uiBox = uiC
|
||||
// panic("gui.AddTab() after makeNode()")
|
||||
tabSetMargined(newNode.uiTab)
|
||||
return newNode
|
||||
}
|
||||
|
|
173
structs.go
173
structs.go
|
@ -19,11 +19,20 @@ var Data GuiData
|
|||
var Config GuiConfig
|
||||
|
||||
type GuiConfig struct {
|
||||
Title string
|
||||
Width int
|
||||
Height int
|
||||
Debug bool
|
||||
DebugTable bool
|
||||
Exit func(*GuiWindow)
|
||||
Exit func(*Node)
|
||||
|
||||
Debug bool
|
||||
DebugNode bool
|
||||
DebugTabs bool
|
||||
DebugTable bool
|
||||
DebugWindow bool
|
||||
|
||||
depth int
|
||||
counter int // used to make unique ID's
|
||||
prefix string
|
||||
}
|
||||
|
||||
type GuiData struct {
|
||||
|
@ -35,7 +44,10 @@ type GuiData struct {
|
|||
AllEntries []*GuiEntry
|
||||
WindowMap map[string]*GuiWindow
|
||||
|
||||
// Windows []*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
|
||||
|
@ -45,7 +57,6 @@ type GuiData struct {
|
|||
// andlabs/ui & andlabs/libui work
|
||||
AllButtons []*GuiButton
|
||||
buttonMap map[*ui.Button]*GuiButton
|
||||
Nodes *Node
|
||||
}
|
||||
|
||||
type GuiTab struct {
|
||||
|
@ -87,11 +98,20 @@ type GuiWindow struct {
|
|||
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 {
|
||||
|
@ -99,121 +119,62 @@ type GuiBox struct {
|
|||
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 (s GuiBox) SetTitle(title string) {
|
||||
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 s.Window == nil {
|
||||
if b.Window == nil {
|
||||
return
|
||||
}
|
||||
if s.Window.UiWindow == nil {
|
||||
if b.Window.UiWindow == nil {
|
||||
return
|
||||
}
|
||||
s.Window.UiWindow.SetTitle(title)
|
||||
b.Window.UiWindow.SetTitle(title)
|
||||
return
|
||||
}
|
||||
|
||||
func (s GuiBox) Append(child ui.Control, x bool) {
|
||||
if s.UiBox == nil {
|
||||
func (w *GuiWindow) SetNode(n *Node) {
|
||||
if (w.node != nil) {
|
||||
w.Dump()
|
||||
panic("gui.SetNode() Error not nil")
|
||||
}
|
||||
w.node = n
|
||||
if (w.node == nil) {
|
||||
w.Dump()
|
||||
panic("gui.SetNode() node == nil")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *GuiBox) SetNode(n *Node) {
|
||||
if (b.node != nil) {
|
||||
b.Dump()
|
||||
panic("gui.SetNode() Error not nil")
|
||||
}
|
||||
b.node = n
|
||||
if (b.node == nil) {
|
||||
b.Dump()
|
||||
panic("gui.SetNode() node == nil")
|
||||
}
|
||||
}
|
||||
|
||||
func (b *GuiBox) Append(child ui.Control, x bool) {
|
||||
if b.UiBox == nil {
|
||||
panic("GuiBox.Append() can't work. UiBox == nil")
|
||||
return
|
||||
}
|
||||
s.UiBox.Append(child, x)
|
||||
}
|
||||
|
||||
/*
|
||||
func (w GuiWindow) InitWindow(title string) *GuiBox {
|
||||
if w.UiWindow == nil {
|
||||
log.Println("gui.InitBox() THIS SHOULD NEVER HAPPEN. Window doesn't exist", w)
|
||||
return nil
|
||||
}
|
||||
tab := ui.NewTab()
|
||||
w.UiWindow.SetChild(tab)
|
||||
w.UiWindow.SetMargined(true)
|
||||
|
||||
tab.Append(title, InitBlankWindow())
|
||||
tab.SetMargined(0, true)
|
||||
|
||||
w.UiTab = tab
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
func (s GuiBox) InitTab(title string, custom func() ui.Control) *ui.Tab {
|
||||
if s.Window == nil {
|
||||
return nil
|
||||
}
|
||||
if s.Window.UiWindow == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
window := s.Window.UiWindow
|
||||
tab := ui.NewTab()
|
||||
window.SetChild(tab)
|
||||
window.SetMargined(true)
|
||||
|
||||
tab.Append(title, custom())
|
||||
tab.SetMargined(0, true)
|
||||
// tab.SetMargined(1, true)
|
||||
|
||||
s.Window.UiTab = tab
|
||||
return tab
|
||||
}
|
||||
|
||||
func (s GuiBox) AddTab(title string, custom ui.Control) *ui.Tab {
|
||||
if s.Window == nil {
|
||||
return nil
|
||||
}
|
||||
if s.Window.UiTab == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tab := s.Window.UiTab
|
||||
|
||||
tab.Append(title, custom)
|
||||
return tab
|
||||
}
|
||||
|
||||
func (s GuiBox) AddTab2(title string, custom ui.Control) *ui.Tab {
|
||||
if s.Window == nil {
|
||||
return nil
|
||||
}
|
||||
if s.Window.UiTab == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
tab := s.Window.UiTab
|
||||
tab.Append(title, custom)
|
||||
return tab
|
||||
}
|
||||
|
||||
func (s GuiBox) AddBoxTab(title string) *GuiBox {
|
||||
uiTab := s.AddTab2(title, InitBlankWindow())
|
||||
tabSetMargined(uiTab)
|
||||
|
||||
var box *GuiBox
|
||||
box = HardBox(s.Window, Xaxis, "jcarrAddBoxTab")
|
||||
box.Window.UiTab = uiTab
|
||||
return box
|
||||
}
|
||||
|
||||
func (s GuiBox) AddDemoTab(title string) {
|
||||
uiTab := s.AddTab(title, makeWindowTemplate())
|
||||
tabSetMargined(uiTab)
|
||||
}
|
||||
|
||||
func (s GuiBox) AddDebugTab(title string) {
|
||||
uiTab := s.AddTab(title, makeWindowDebug())
|
||||
tabSetMargined(uiTab)
|
||||
}
|
||||
|
||||
func tabSetMargined(tab *ui.Tab) {
|
||||
c := tab.NumPages()
|
||||
for i := 0; i < c; i++ {
|
||||
log.Println("tabSetMargined() i =", i)
|
||||
// tab.SetMargined(i, true)
|
||||
}
|
||||
b.UiBox.Append(child, x)
|
||||
}
|
||||
|
||||
// Note: every mouse click is handled
|
||||
|
|
12
table.go
12
table.go
|
@ -98,12 +98,12 @@ func InitColumns(mh *TableData, parts []TableColumnData) {
|
|||
}
|
||||
|
||||
func AddTableTab(gw *GuiWindow, name string, rowcount int, parts []TableColumnData) *TableData {
|
||||
box := InitWindow(gw, name, Yaxis)
|
||||
|
||||
return AddTableBox(box, name, rowcount, parts)
|
||||
node := NewWindow()
|
||||
b := node.box
|
||||
return b.AddTableBox(name, rowcount, parts)
|
||||
}
|
||||
|
||||
func AddTableBox(box *GuiBox, name string, rowcount int, parts []TableColumnData) *TableData {
|
||||
func (b *GuiBox) AddTableBox(name string, rowcount int, parts []TableColumnData) *TableData {
|
||||
mh := new(TableData)
|
||||
|
||||
mh.RowCount = rowcount
|
||||
|
@ -142,9 +142,9 @@ func AddTableBox(box *GuiBox, name string, rowcount int, parts []TableColumnData
|
|||
|
||||
// is this needed?
|
||||
// gw.BoxMap[name] = box
|
||||
mh.Box = box
|
||||
mh.Box = b
|
||||
|
||||
box.UiBox.Append(table, true)
|
||||
b.UiBox.Append(table, true)
|
||||
|
||||
return mh
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ func (mh *TableData) ColumnTypes(m *ui.TableModel) []ui.TableValue {
|
|||
}
|
||||
|
||||
// TODO: Figure out why this is being called 1000 times a second (10 times for each row & column)
|
||||
// Nevermind this TODO. Who gives a shit. This is a really smart way to treat the OS toolkits
|
||||
//
|
||||
// Nevermind that TODO. Who gives a shit. This is a really smart way to treat the OS toolkits
|
||||
func (mh *TableData) CellValue(m *ui.TableModel, row, column int) ui.TableValue {
|
||||
if (Config.DebugTable) {
|
||||
log.Println("CellValue() row, column =", row, column)
|
||||
|
|
260
window.go
260
window.go
|
@ -2,40 +2,13 @@ package gui
|
|||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/andlabs/ui"
|
||||
|
||||
// import "regexp"
|
||||
|
||||
_ "github.com/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
func initUI(name string, callback func(*GuiBox) *GuiBox) {
|
||||
ui.Main(func() {
|
||||
log.Println("gui.initUI() inside ui.Main()")
|
||||
|
||||
box := InitWindow(nil, "StartNewWindow"+name, 0)
|
||||
box = callback(box)
|
||||
window := box.Window
|
||||
log.Println("StartNewWindow() box =", box)
|
||||
|
||||
window.UiWindow.Show()
|
||||
})
|
||||
}
|
||||
|
||||
func StartNewWindow(bg bool, name string, axis int, callback func(*GuiBox) *GuiBox) {
|
||||
log.Println("StartNewWindow() ui.Main() Create a new window")
|
||||
|
||||
if bg {
|
||||
go initUI(name, callback)
|
||||
time.Sleep(500 * time.Millisecond) // this might make it more stable on windows?
|
||||
} else {
|
||||
initUI(name, callback)
|
||||
}
|
||||
}
|
||||
|
||||
func MessageWindow(gw *GuiWindow, msg1 string, msg2 string) {
|
||||
ui.MsgBox(gw.UiWindow, msg1, msg2)
|
||||
}
|
||||
|
@ -44,71 +17,6 @@ func ErrorWindow(gw *GuiWindow, msg1 string, msg2 string) {
|
|||
ui.MsgBoxError(gw.UiWindow, msg1, msg2)
|
||||
}
|
||||
|
||||
//
|
||||
// This creates a new 'window' (which is just a tab in the window)
|
||||
// This is this way because on Linux you can have more than one
|
||||
// actual window but that does not appear to work on the MacOS or Windows
|
||||
//
|
||||
func InitWindow(gw *GuiWindow, name string, axis int) *GuiBox {
|
||||
log.Println("InitGuiWindow() START")
|
||||
|
||||
var box *GuiBox
|
||||
if gw == nil {
|
||||
box = mapWindow(nil, name, Config.Height, Config.Width)
|
||||
} else {
|
||||
box = mapWindow(gw.UiWindow, name, Config.Height, Config.Width)
|
||||
}
|
||||
|
||||
// box.Window = &newGuiWindow
|
||||
newGuiWindow := box.Window
|
||||
|
||||
// This is the first window. One must create it here
|
||||
if gw == nil {
|
||||
log.Println("initWindow() ADDING ui.NewWindow()")
|
||||
newGuiWindow.UiWindow = ui.NewWindow(name, int(newGuiWindow.Height), int(newGuiWindow.Width), true)
|
||||
newGuiWindow.UiWindow.SetBorderless(false)
|
||||
|
||||
// newGuiWindow.UiWindow.SetTitle("test")
|
||||
newGuiWindow.UiWindow.OnClosing(func(*ui.Window) bool {
|
||||
log.Println("initTabWindow() OnClosing() THIS WINDOW IS CLOSING newGuiWindow=", newGuiWindow)
|
||||
// newGuiWindow.UiWindow.Destroy()
|
||||
if Config.Exit == nil {
|
||||
ui.Quit()
|
||||
} else {
|
||||
// allow a custom exit function
|
||||
Config.Exit(newGuiWindow)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
newGuiWindow.UiTab = ui.NewTab()
|
||||
newGuiWindow.UiWindow.SetChild(newGuiWindow.UiTab)
|
||||
newGuiWindow.UiWindow.SetMargined(true)
|
||||
tmp := 0
|
||||
newGuiWindow.TabNumber = &tmp
|
||||
} else {
|
||||
newGuiWindow.UiWindow = gw.UiWindow
|
||||
newGuiWindow.UiTab = gw.UiTab
|
||||
}
|
||||
|
||||
newGuiWindow.BoxMap = make(map[string]*GuiBox)
|
||||
newGuiWindow.EntryMap = make(map[string]*GuiEntry)
|
||||
// Data.Windows = append(Data.Windows, &newGuiWindow)
|
||||
|
||||
if newGuiWindow.UiTab == nil {
|
||||
tabnum := 0
|
||||
newGuiWindow.TabNumber = &tabnum
|
||||
} else {
|
||||
tabnum := newGuiWindow.UiTab.NumPages()
|
||||
newGuiWindow.TabNumber = &tabnum
|
||||
}
|
||||
|
||||
Data.WindowMap[newGuiWindow.Name] = newGuiWindow
|
||||
|
||||
log.Println("InitGuiWindow() END *GuiWindow =", newGuiWindow)
|
||||
return box
|
||||
}
|
||||
|
||||
func DeleteWindow(name string) {
|
||||
log.Println("gui.DeleteWindow() START name =", name)
|
||||
window := Data.WindowMap[name]
|
||||
|
@ -144,57 +52,102 @@ func DeleteWindow(name string) {
|
|||
}
|
||||
}
|
||||
|
||||
func CreateWindow(title string, tabname string, x int, y int, custom func() ui.Control) *GuiBox {
|
||||
box := CreateBlankWindow(title, x, y)
|
||||
box.InitTab(title, custom)
|
||||
return box
|
||||
func makeNode(parent *Node, title string, x int, y int) *Node {
|
||||
var node Node
|
||||
node.Name = title
|
||||
node.Width = x
|
||||
node.Height = y
|
||||
|
||||
id := Config.prefix + strconv.Itoa(Config.counter)
|
||||
Config.counter += 1
|
||||
node.id = id
|
||||
|
||||
// panic("gui.makeNode() START")
|
||||
if (parent == nil) {
|
||||
if (Data.NodeMap[title] != nil) {
|
||||
log.Println("Duplicate window name =", title)
|
||||
// TODO: just change the 'title' to something unique
|
||||
panic(fmt.Sprintf("Duplicate window name = %s\n", title))
|
||||
return nil
|
||||
}
|
||||
// panic("gui.makeNode() before NodeMap()")
|
||||
Data.NodeMap[title] = &node
|
||||
Data.NodeArray = append(Data.NodeArray, &node)
|
||||
Data.NodeSlice = append(Data.NodeSlice, &node)
|
||||
// panic("gui.makeNode() after NodeMap()")
|
||||
return &node
|
||||
} else {
|
||||
// panic("gui.makeNode() before Append()")
|
||||
parent.Append(&node)
|
||||
// panic("gui.makeNode() after Append()")
|
||||
}
|
||||
node.parent = parent
|
||||
return &node
|
||||
}
|
||||
|
||||
func CreateBlankWindow(title string, x int, y int) *GuiBox {
|
||||
box := mapWindow(nil, title, x, y)
|
||||
log.Println("gui.CreateBlankWindow() title = box.Name =", box.Name)
|
||||
func (parent *Node) makeNode(title string, x int, y int) *Node {
|
||||
var node Node
|
||||
node.Name = title
|
||||
node.Width = x
|
||||
node.Height = y
|
||||
|
||||
window := ui.NewWindow(box.Name, x, y, false)
|
||||
window.SetBorderless(false)
|
||||
window.OnClosing(func(*ui.Window) bool {
|
||||
log.Println("createWindow().OnClosing()", box.Name)
|
||||
id := Config.prefix + strconv.Itoa(Config.counter)
|
||||
Config.counter += 1
|
||||
node.id = id
|
||||
|
||||
parent.Append(&node)
|
||||
node.parent = parent
|
||||
return &node
|
||||
}
|
||||
|
||||
func (n *Node) AddNode(title string) *Node {
|
||||
var node Node
|
||||
node.Name = title
|
||||
node.Width = n.Width
|
||||
node.Height = n.Height
|
||||
|
||||
id := Config.prefix + strconv.Itoa(Config.counter)
|
||||
Config.counter += 1
|
||||
node.id = id
|
||||
|
||||
n.Append(&node)
|
||||
node.parent = n
|
||||
return &node
|
||||
}
|
||||
|
||||
func (n *Node) uiNewWindow(title string, x int, y int) {
|
||||
w := ui.NewWindow(title, x, y, false)
|
||||
w.SetBorderless(false)
|
||||
f := Config.Exit
|
||||
w.OnClosing(func(*ui.Window) bool {
|
||||
if (Config.Debug) {
|
||||
log.Println("ui.Window().OnClosing()")
|
||||
}
|
||||
if (f != nil) {
|
||||
f(n)
|
||||
}
|
||||
return true
|
||||
})
|
||||
ui.OnShouldQuit(func() bool {
|
||||
log.Println("createWindow().Destroy()", box.Name)
|
||||
window.Destroy()
|
||||
return true
|
||||
})
|
||||
|
||||
window.SetMargined(true)
|
||||
window.Show()
|
||||
|
||||
box.Window.UiWindow = window
|
||||
return box
|
||||
w.SetMargined(true)
|
||||
w.Show()
|
||||
n.uiWindow = w
|
||||
// w.node = &node
|
||||
return
|
||||
}
|
||||
|
||||
func InitBlankWindow() ui.Control {
|
||||
hbox := ui.NewHorizontalBox()
|
||||
hbox.SetPadded(true)
|
||||
|
||||
return hbox
|
||||
}
|
||||
|
||||
var master = 0
|
||||
|
||||
func mapWindow(window *ui.Window, title string, x int, y int) *GuiBox {
|
||||
func mapWindow(parent *Node, window *ui.Window, title string, x int, y int) *Node {
|
||||
log.Println("gui.WindowMap START title =", title)
|
||||
if Data.WindowMap[title] != nil {
|
||||
log.Println("Data.WindowMap[title] already exists title =", title)
|
||||
master = master + 1
|
||||
title = title + " jcarr " + strconv.Itoa(master)
|
||||
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
|
||||
}
|
||||
log.Println("gui.WindowMap START title =", title)
|
||||
|
||||
var newGuiWindow GuiWindow
|
||||
newGuiWindow.Width = x
|
||||
newGuiWindow.Height = y
|
||||
|
@ -210,30 +163,47 @@ func mapWindow(window *ui.Window, title string, x int, y int) *GuiBox {
|
|||
box.Window = &newGuiWindow
|
||||
box.Name = title
|
||||
|
||||
node := makeNode(parent, title, x, y)
|
||||
node.box = &box
|
||||
node.uiWindow = window
|
||||
box.node = node
|
||||
|
||||
newGuiWindow.BoxMap["jcarrInitTest"] = &box
|
||||
|
||||
return &box
|
||||
return node
|
||||
}
|
||||
|
||||
func NewWindow(title string, x int, y int) *GuiBox {
|
||||
box := mapWindow(nil, title, x, y)
|
||||
// This routine creates a blank window with a Title and size (W x H)
|
||||
//
|
||||
// This routine can not have any arguements due to the nature of how
|
||||
// it can be passed via the 'andlabs/ui' queue which, because it is
|
||||
// cross platform, must pass UI changes into the OS threads (that is
|
||||
// my guess).
|
||||
func NewWindow() *Node {
|
||||
title := Config.Title
|
||||
w := Config.Width
|
||||
h := Config.Height
|
||||
|
||||
var n *Node
|
||||
n = mapWindow(nil, nil, title, w, h)
|
||||
box := n.box
|
||||
log.Println("gui.NewWindow() title = box.Name =", box.Name)
|
||||
|
||||
window := ui.NewWindow(box.Name, x, y, false)
|
||||
window.SetBorderless(false)
|
||||
window.OnClosing(func(*ui.Window) bool {
|
||||
log.Println("createWindow().OnClosing()", box.Name)
|
||||
return true
|
||||
})
|
||||
ui.OnShouldQuit(func() bool {
|
||||
log.Println("createWindow().Destroy()", box.Name)
|
||||
window.Destroy()
|
||||
return true
|
||||
})
|
||||
n.uiNewWindow(box.Name, w, h)
|
||||
window := n.uiWindow
|
||||
|
||||
window.SetMargined(true)
|
||||
window.Show()
|
||||
f := Config.Exit
|
||||
ui.OnShouldQuit(func() bool {
|
||||
log.Println("createWindow().Destroy() on node.Name =", n.Name)
|
||||
if (f != nil) {
|
||||
f(n)
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
box.Window.UiWindow = window
|
||||
return box
|
||||
if(n.uiWindow == nil) {
|
||||
panic("node.uiWindow == nil. This should never happen")
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue