diff options
| author | Jeff Carr <[email protected]> | 2022-10-19 13:23:22 -0500 |
|---|---|---|
| committer | Jeff Carr <[email protected]> | 2022-10-19 13:23:22 -0500 |
| commit | f3af1f5b7ff78b3f73d7510622fc9633dec36d35 (patch) | |
| tree | e4868584d5e19942938aaa122b2e1cab377db000 | |
| parent | f7b1036e544238d65b0e3ad46d08075aa4177032 (diff) | |
Refactor to 'gui/toolkit/'
* add a example cmds/consolemouse
uses a console button to launch the andlabs/ui
* fix wrong return value in toolkit/NewLabel()
* redirect STDIN output to a file
* wonderful fix of Window() exit
* finally remove the ancient stupid variables x & y
* phase out struct 'box' and use 'node' instead
* better names for things: use NewFoo() and NewBar()
36 files changed, 1122 insertions, 478 deletions
@@ -1,3 +1,4 @@ *.swp cmds/gui-demo/gui-demo cmds/helloworld/helloworld +cmds/consolemouse/consolemouse @@ -9,7 +9,10 @@ update: git pull go get -v -t -u ./... -examples: examples-gui-demo examples-helloworld +examples: examples-consolemouse examples-helloworld examples-gui-demo + +examples-consolemouse: + make -C cmds/consolemouse examples-helloworld: make -C cmds/helloworld @@ -18,4 +21,4 @@ examples-gui-demo: make -C cmds/gui-demo doc: - godoc -v + GO111MODULE="off" godoc -v @@ -1,6 +1,7 @@ package gui import "log" +import "os" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" @@ -15,7 +16,7 @@ func (n *Node) AddBox(axis int, name string) *Node { } // make a new box & a new node - newNode := n.makeNode(name, 111, 100 + Config.counter) + newNode := n.New(name) newNode.box = newBox Config.counter += 1 @@ -53,12 +54,21 @@ func VerticalBreak(box *GuiBox) { } func (n *Node) AddComboBox(title string, s ...string) *Node { - box := n.uiBox - if (box == nil) { - return n + 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.AddNode(title) + newNode := n.New(title) ecbox := ui.NewEditableCombobox() for id, name := range s { @@ -1,7 +1,7 @@ package gui import "log" -import "reflect" +// import "reflect" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" // import "github.com/davecgh/go-spew/spew" @@ -53,24 +53,33 @@ 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") + if (n.Toolkit == nil) { + log.Println("gui.Node.AppendButton() filed node.Toolkit == nil") + panic("gui.Node.AppendButton() filed node.Toolkit == 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 := n.New(name) + newNode.Toolkit = n.Toolkit.NewButton(name) + newNode.Toolkit.Custom = func() { + log.Println("gui.AppendButton() Button Clicked. Running custom()") + custom(newNode) + } 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 @@ -106,6 +115,10 @@ func (n *Node) CreateButton(custom func(*GuiButton), name string, values interfa 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) diff --git a/cmds/consolemouse/Makefile b/cmds/consolemouse/Makefile new file mode 100644 index 0000000..7061e7e --- /dev/null +++ b/cmds/consolemouse/Makefile @@ -0,0 +1,14 @@ +run: build + ./consolemouse + reset + +build-release: + go get -v -u -x . + go build + +build: + GO111MODULE="off" go get -v -x . + GO111MODULE="off" go build + +update: + GO111MODULE="off" go get -v -u -x . diff --git a/cmds/consolemouse/gocui.go b/cmds/consolemouse/gocui.go new file mode 100644 index 0000000..7da888e --- /dev/null +++ b/cmds/consolemouse/gocui.go @@ -0,0 +1,51 @@ +// This creates a simple hello world window +package main + +import ( + "log" + "time" + "git.wit.org/wit/gui" +) + +import toolkit "git.wit.org/wit/gui/toolkit/gocui" + +func configureGogui() { + toolkit.Init() + toolkit.OnExit(mycallback) +} + +func startGogui() { + toolkit.StartConsoleMouse() +} + +func mycallback(name string) { + log.Println("run andlabs here? name =", name) + if (name == "andlabs") { + go gui.Main(initGUI) + } + if (name == "something") { + log.Println("add something to do here") + } + if (name == "DemoToolkitWindow") { + gui.Queue( func () { + gui.DemoToolkitWindow() + }) + } + if (name == "addDemoTab") { + gui.Queue( func () { + addDemoTab(w, "A Tab from gocui") + }) + } + if (name == "DebugWindow") { + log.Println("Opening a Debug Window via the gui.Queue()") + gui.Config.Width = 800 + gui.Config.Height = 300 + gui.Config.Exit = myExit + gui.Queue(gui.DebugWindow) + time.Sleep(1 * time.Second) + gui.Queue(gui.DebugTab) + } + if (name == "exit") { + myExit(nil) + } +} diff --git a/cmds/consolemouse/main.go b/cmds/consolemouse/main.go new file mode 100644 index 0000000..44ad18d --- /dev/null +++ b/cmds/consolemouse/main.go @@ -0,0 +1,61 @@ +// This creates a simple hello world window +package main + +import ( + "os" + "log" +// "time" + "git.wit.org/wit/gui" +) + +import toolkit "git.wit.org/wit/gui/toolkit/gocui" + +var w *gui.Node + +func main() { + go gui.Main(initGUI) + + configureGogui() + startGogui() +} + +// This initializes the first window +func initGUI() { + gui.Config.Title = "Hello World golang wit/gui Window" + gui.Config.Width = 640 + gui.Config.Height = 480 + gui.Config.Exit = myExit + + w = gui.NewWindow() + w.Dump() + addDemoTab(w, "A Simple Tab Demo") + addDemoTab(w, "A Second Tab") +} + +func addDemoTab(window *gui.Node, title string) { + var newNode, g *gui.Node + + newNode = window.AddTab(title, nil) + 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") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + g.Dump() + g.Toolkit.Dump() + // myExit(nil) + g.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") +} + +func myExit(n *gui.Node) { + log.Println("You can Do exit() things here") + toolkit.Exit() + os.Exit(0) +} diff --git a/cmds/gui-demo/main.go b/cmds/gui-demo/main.go index 0084e3a..d89b1b0 100644 --- a/cmds/gui-demo/main.go +++ b/cmds/gui-demo/main.go @@ -22,7 +22,7 @@ func main() { // This initializes the first window func initGUI() { - gui.ToolkitDemoWindow() + gui.DemoToolkitWindow() } // This demonstrates how to properly interact with the GUI @@ -33,24 +33,22 @@ func watchGUI() { log.Println("Waiting", i, "seconds") i += 1 time.Sleep(1 * time.Second) - if i == 4 { + if i == 2 { log.Println("Opening a Debug Window via the gui.Queue()") gui.Config.Width = 800 gui.Config.Height = 300 - gui.Config.Exit = myDebugExit + gui.Config.Exit = myExit gui.Queue(gui.DebugWindow) + time.Sleep(1 * time.Second) + gui.Queue(gui.DebugTab) } } } +// TODO: myExit isn't getting used anymore 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()") -} diff --git a/cmds/helloworld/Makefile b/cmds/helloworld/Makefile index 1d12c3c..23d5aaa 100644 --- a/cmds/helloworld/Makefile +++ b/cmds/helloworld/Makefile @@ -8,7 +8,6 @@ build-release: build: GO111MODULE="off" go get -v -x . GO111MODULE="off" go build - ./helloworld update: GO111MODULE="off" go get -v -u -x . diff --git a/cmds/helloworld/main.go b/cmds/helloworld/main.go index bc0a046..97af97b 100644 --- a/cmds/helloworld/main.go +++ b/cmds/helloworld/main.go @@ -8,26 +8,51 @@ import ( ) func main() { + f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + defer f.Close() + + log.SetOutput(f) + log.Println("This is a test log entry") + gui.Main(initGUI) } // This initializes the first window func initGUI() { + var w *gui.Node gui.Config.Title = "Hello World golang wit/gui Window" gui.Config.Width = 640 gui.Config.Height = 480 gui.Config.Exit = myDefaultExit - node1 := gui.NewWindow() - addDemoTab(node1, "A Simple Tab Demo") - addDemoTab(node1, "A Second Tab") + w = gui.NewWindow() + w.Dump() + addDemoTab(w, "A Simple Tab Demo") + addDemoTab(w, "A Second Tab") } -func addDemoTab(n *gui.Node, title string) { - newNode := n.AddTab(title, nil) +func addDemoTab(window *gui.Node, title string) { + var newNode, g *gui.Node + + newNode = window.AddTab(title, nil) + 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.Dump() + g = newNode.NewGroup("group 1") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + log.Println("addDemoTab() g.Dump") + g.Dump() + g.Toolkit.Dump() + // os.Exit(0) g.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") } diff --git a/debug-window.go b/debug-window.go index 28a4a3c..776c8e0 100644 --- a/debug-window.go +++ b/debug-window.go @@ -2,6 +2,8 @@ package gui import ( "log" +// "time" +// "os" "github.com/andlabs/ui" _ "github.com/andlabs/ui/winmanifest" @@ -11,23 +13,31 @@ import ( 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" - Config.Width = 640 - Config.Height = 480 + Config.Title = "git.wit.org/wit/gui debug fixme" + Config.Width = 300 + Config.Height = 200 Config.Exit = StandardClose - node := NewWindow() - node.DebugTab("WIT GUI Debug Tab") + 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 addNodeName(c *ui.Combobox, s string, id string) { +func addNodeNameBAD(c *ui.Combobox, s string, id string) { c.Append(s) - nodeNames[y] = id - y = y + 1 + // nodeNames[y] = id + // y = y + 1 + log.Println("addNodeName:", s) + // time.Sleep(1 * time.Second) + // os.Exit(0) } func makeWindowDebug() *ui.Box { @@ -42,7 +52,7 @@ func makeWindowDebug() *ui.Box { if (Config.Debug) { log.Println("range Data.WindowMap() name =", name) } - addName(cbox, name) + addNameBAD(cbox, name) } cbox.SetSelected(0) @@ -83,8 +93,8 @@ func makeWindowDebug() *ui.Box { } scs := spew.ConfigState{MaxDepth: 1} scs.Dump(gw) - log.Println("gui.DumpBoxes()\tWindow.UiTab =", gw.UiTab) - log.Println("gui.DumpBoxes()\tWindow.TabNumber =", *gw.TabNumber) + log.Println("gui.dumpBoxes()\tWindow.UiTab =", gw.UiTab) + log.Println("gui.dumpBoxes()\tWindow.TabNumber =", *gw.TabNumber) gw.UiTab.SetMargined(*gw.TabNumber, true) }) @@ -141,17 +151,17 @@ func makeWindowDebug() *ui.Box { dump3 := addButton(vbox, "Dump Windows") dump3.OnClicked(func(*ui.Button) { - DumpWindows() + dumpWindows() }) dump2 := addButton(vbox, "Dump Boxes") dump2.OnClicked(func(*ui.Button) { - DumpBoxes() + dumpBoxes() }) dump1 := addButton(vbox, "Dump MAP") dump1.OnClicked(func(*ui.Button) { - DumpMap() + dumpMap() }) ///////////////////////////////////////////////////// @@ -159,12 +169,15 @@ func makeWindowDebug() *ui.Box { nodeCombo := ui.NewCombobox() for name, node := range Data.NodeMap { - if (Config.Debug) { + // if (Config.Debug) { log.Println("range Data.NodeMap() name =", name) - } + // } tmp := node.id + " (" + name + ")" - addNodeName(nodeCombo, tmp, node.id) + addNodeNameBAD(nodeCombo, tmp, node.id) } +// scs := spew.ConfigState{MaxDepth: 1} +// scs.Dump(Data.NodeMap) +// os.Exit(0) nodeCombo.SetSelected(0) nodeBox.Append(nodeCombo, false) @@ -245,14 +258,17 @@ func makeWindowDebug() *ui.Box { } // TODO: remove this crap -var x int = 0 -var y int = 0 +// var x int = 0 +// var y int = 0 // TODO: remove this crap -func addName(c *ui.Combobox, s string) { +func addNameBAD(c *ui.Combobox, s string) { c.Append(s) - names[x] = s - x = x + 1 + // 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 { @@ -300,7 +316,7 @@ func dumpBox(s string) { if window.UiTab != nil { pages := window.UiTab.NumPages() log.Println("gui.DumpBoxes()\tWindow.UiTab.NumPages() =", pages) - tabSetMargined(window.UiTab) + // fixme: tabSetMargined(window.UiTab) if Config.Debug { scs := spew.ConfigState{MaxDepth: 2} scs.Dump(window.UiTab) @@ -320,26 +336,22 @@ func addButton(box *ui.Box, name string) *ui.Button { return button } -func (n *Node) DebugTab(title string) { - newNode := n.AddTab(title, makeWindowDebug()) - if (Config.DebugNode) { - newNode.Dump() - } - tabSetMargined(newNode.uiTab) +func DebugTab() { + bugWin.DebugTab("does this work?") } -// 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) - } +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 } @@ -15,14 +15,15 @@ import ( 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() { +/* +func watchGUI() { count := 0 for { if count > 20 { log.Println("Sleep() in watchGUI()") if Config.Debug { - DumpBoxes() + dumpBoxes() } count = 0 } @@ -30,14 +31,15 @@ func WatchGUI() { time.Sleep(200 * time.Millisecond) } } +*/ -func DumpWindows() { +func dumpWindows() { for name, _ := range Data.WindowMap { log.Println("gui.DumpWindows() window =", name) } } -func DumpMap() { +func dumpMap() { for name, window := range Data.WindowMap { log.Println("gui.DumpBoxes() MAP: ", name) log.Println("gui.DumpBoxes() BOXES:", name) @@ -47,7 +49,7 @@ func DumpMap() { } } -func DumpBoxes() { +func dumpBoxes() { for name, window := range Data.WindowMap { log.Println("gui.DumpBoxes() MAP: ", name) if window.TabNumber == nil { @@ -1,13 +1,22 @@ /* Package gui implements a abstraction layer for Go visual elements in -a cross platform way. +a cross platform and library independent way. (hopefully this is will work) 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 +Definitions: + + * Toolkit: the underlying library (MacOS gui, Windows gui, gtk, qt, etc) + * Node: A binary tree of all the underlying GUI toolkit elements + +Principles: + + * Make code using this package simple to use + * When in doubt, search upward in the binary tree + * It's ok to guess. We will return something close. + * Hide complexity internally here + * Isolate the GUI toolkit Quick Start @@ -22,11 +31,11 @@ sections below for further details on formatting and configuration options. ) func main() { - gui.Main(initGUI) + gui.Main(helloworld) } // This initializes the first window - func initGUI() { + func helloworld() { gui.Config.Title = "Hello World golang wit/gui Window" gui.Config.Width = 640 gui.Config.Height = 480 @@ -42,7 +51,7 @@ sections below for further details on formatting and configuration options. groupNode1.AddComboBox("demoCombo2", "more 1", "more 2", "more 3") } -Toolkit Usage +Toolkits (hopefully more than one will work) Right now, this abstraction is built on top of the go package 'andlabs/ui' which does the cross platform support. @@ -63,5 +72,12 @@ Debugging To dump variables with full newlines, indentation, type, and pointer information this uses spew.Dump() +Bugs + +"The author's idea of friendly may differ to that of many other people." + +-- manpage quote from the excellent minimalistic window manager 'evilwm' + + */ package gui diff --git a/entry.go b/entry.go deleted file mode 100644 index 2ca578d..0000000 --- a/entry.go +++ /dev/null @@ -1,62 +0,0 @@ -package gui - -import "log" -// import "fmt" - -import toolkit "git.wit.org/wit/gui/toolkit/andlabs" - -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - - -import "github.com/davecgh/go-spew/spew" - -// functions for handling text entry boxes - -func NewLabel(box *GuiBox, text string) { - box.Append(ui.NewLabel(text), false) -} - -func (n *Node) NewLabel(text string) *Node { - // make new node here - newNode := makeNode(n, text, 333, 334) - newNode.Dump() - - t := toolkit.NewLabel(n.uiBox, text) - newNode.Toolkit = t - - 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(b.Window.EntryMap) - if (b.Window.EntryMap[name] == nil) { - log.Println("gui.GetText() ERROR box.Window.EntryMap[", name, "] == nil ") - return "" - } - 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 - } - if (n.uiWindow != nil) { - n.uiWindow.SetTitle(value) - return nil - } - return nil -} @@ -4,60 +4,28 @@ import "log" import toolkit "git.wit.org/wit/gui/toolkit/andlabs" -import "github.com/andlabs/ui" -import _ "github.com/andlabs/ui/winmanifest" - +// TODO: which name is better. AddGroup or NewGroup ? +// first reaction is NewGroup func (n *Node) NewGroup(name string) *Node { - var t *toolkit.Toolkit - var gNode, bNode *Node + var newT *toolkit.Toolkit + var gNode *Node log.Println("toolkit.NewGroup() START", name) + if (n.Toolkit == nil) { + log.Println("toolkit.NewGroup() Toolkit == nil") + panic("Toolkit should never be nil") + } + // make a *Node with a *toolkit.Group - gNode = n.AddNode(name + " part1") - t = toolkit.NewGroup(n.uiBox, name) - gNode.Toolkit = t + gNode = n.New(name + " part1") + newT = n.Toolkit.NewGroup(name) + gNode.Toolkit = newT + log.Println("################## gNode ####### ", name) gNode.Dump() - // make a *Node with a *toolkit.Box - bNode = n.AddNode(name + " part2") - bNode.Toolkit = t.NewBox() - bNode.uiBox = bNode.Toolkit.GetBox() - bNode.Dump() - return bNode + return gNode } func (n *Node) AddGroup(title string) *Node { - return n.NewGroup(title) + return n.NewGroup(title + "deprecated AddGroup") } - -func (n *Node) AddGroupOld(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 -} - -/* -func (n *Node) NewGroup(title string) *Node { - group := ui.NewGroup(title) - group.SetMargined(true) - hbox.Append(group, true) - - vbox := ui.NewVerticalBox() - vbox.SetPadded(true) - group.SetChild(vbox) -*/ @@ -4,13 +4,15 @@ import "log" import "github.com/davecgh/go-spew/spew" -// import toolkit "git.wit.org/wit/gui/toolkit/andlabs" +/* + Get the int from the gui toolkit + because eventually this gui package should become it's own seperate go routine and never interact from the + gui subroutine back into the upstream application using the gui package - -// Get the int from the gui toolkit -// TODO: instead store the int in the Node structure? (this is probably a better idea) -// because eventually this gui package should become it's own seperate go routine and never interact from the -// gui subroutine back into the upstream application using the gui package + TODO: instead store the int in the Node structure? (this is probably a better idea) + because technically every interaction with the toolkit has to go through the Queue() goroutine. + Is it "has to go" or "should go"? Probably it makes sense to strictly inforce it. No "callback" functions. IPC only (go channels) +*/ func (n *Node) Int() int { if (Config.DebugToolkit) { log.Println("gui.Node.Int() for node name =", n.Name) @@ -26,3 +28,19 @@ func (n *Node) Int() int { i := n.Toolkit.Value() return i } + +// which name to use? +func (n *Node) Value() int { + return n.Int() +} + +func (n *Node) SetValue(i int) { + log.Println("gui.SetValue() START") + if (n.Toolkit == nil) { + log.Println("gui.Node.SetValue() for toolkit struct = nil") + panic("SetValue failed") + } + n.Dump() + n.Toolkit.Dump() + n.Toolkit.SetValue(i) +} diff --git a/new-structs.go b/new-structs.go index fee1473..c05bf23 100644 --- a/new-structs.go +++ b/new-structs.go @@ -2,8 +2,6 @@ package gui import ( "log" - "fmt" -// "reflect" // "github.com/davecgh/go-spew/spew" @@ -241,76 +239,3 @@ func (n *Node) ListChildren(dump bool) { } 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 -} @@ -0,0 +1,40 @@ +package gui + +import "strconv" +// import "fmt" + +/* + generic function to create a new node on the binary tree +*/ +func (n *Node) New(title string) *Node { + var newN *Node + + newN = addNode(title, n.Width, n.Height) + + n.Append(newN) + newN.parent = n + return newN +} + +/* + raw create function for a new node struct +*/ +func addNode(title string, w int, h int) *Node { + var n Node + n.Name = title + n.Width = w + n.Height = h + + id := Config.prefix + strconv.Itoa(Config.counter) + Config.counter += 1 + n.id = id + /* + if (Data.NodeMap[title] != nil) { + panic(fmt.Sprintf("Duplicate window name = %s\n", title)) + } else { + Data.NodeMap[title] = &n + } + */ + + return &n +} @@ -5,20 +5,22 @@ import "log" import toolkit "git.wit.org/wit/gui/toolkit/andlabs" func (n *Node) NewSlider(name string, x int, y int) *Node { - // make new node here - log.Println("toolkit.NewSlider", x, y) + var newT *toolkit.Toolkit + var sNode *Node - newNode := n.makeNode(name, 767, 676 + Config.counter) - newNode.Name = name + log.Println("toolkit.NewSlider() START", name) - t := toolkit.NewSlider(n.uiBox, name, x, y) - t.OnChanged = func(t *toolkit.Toolkit) { - log.Println("toolkit.NewSlider() value =", t.Value()) - if (newNode.OnChanged != nil) { - newNode.OnChanged(newNode) - } + if (n.Toolkit == nil) { + log.Println("toolkit.NewSlider() Toolkit == nil") + panic("Toolkit should never be nil") } - newNode.Toolkit = t - return newNode + // make a *Node with a *toolkit.Group + sNode = n.New(name + " part1") + newT = n.Toolkit.NewSlider(name, x, y) + newT.Name = name + sNode.Toolkit = newT + sNode.Dump() + + return sNode } @@ -8,8 +8,7 @@ func (n *Node) NewSpinbox(name string, x int, y int) *Node { // make new node here log.Println("toolkit.NewSpinbox", x, y) - newNode := n.makeNode(name, 767, 676 + Config.counter) - newNode.Name = name + newNode := n.New(name) t := toolkit.NewSpinbox(n.uiBox, name, x, y) t.OnChanged = func(t *toolkit.Toolkit) { @@ -2,39 +2,76 @@ package gui import ( "log" -// "fmt" + "os" "github.com/andlabs/ui" _ "github.com/andlabs/ui/winmanifest" - ) // import toolkit "git.wit.org/wit/gui/toolkit/andlabs" -func (n *Node) AddTabRaw(title string, uiC ui.Control) *Node { - log.Println("gui.Node.AddTabRaw()") +// This function should make a new node with the parent and +// the 'tab' as a child + +func (n *Node) NewTab(title string) *Node { + log.Println("gui.Node.AddTab() START name =", title) + + return n.AddTabNew(title) +} + +func (n *Node) AddTabNew(title string) *Node { + log.Println("gui.Node.AddTab() START name =", title) - tab := n.uiTab - if (tab == nil) { - log.Println("gui.Node.AddTabRaw() FAIL tab == nil") - return n + 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() + os.Exit(0) + } + log.Println("Make new node") + newN := n.New(title) + log.Println("Add tab to window") + t := n.Toolkit.AddTab(title) + newN.Toolkit = t + + n.Append(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 - log.Println("gui.Node.AddTabRaw() FAIL *ui.Control == nil") - return n + hbox := ui.NewHorizontalBox() + hbox.SetPadded(true) + uiC = hbox } tab.Append(title, uiC) - /* - newNode := parent.makeNode(title, 555, 600 + Config.counter) + newNode := n.New(title) newNode.uiTab = tab newNode.uiBox = uiC - // panic("gui.AddTab() after makeNode()") - tabSetMargined(newNode.uiTab) - */ - return n + // tabSetMargined(newNode.uiTab) + return newNode } +*/ @@ -0,0 +1,40 @@ +package gui + +import "log" +import "errors" + +// import toolkit "git.wit.org/wit/gui/toolkit/andlabs" + +// functions for handling text related GUI elements + +func (n *Node) NewLabel(text string) *Node { + // make new node here + newNode := n.New(text) + newNode.Dump() + + t := n.Toolkit.NewLabel(text) + newNode.Toolkit = t + + return newNode +} + +func (n *Node) SetText(value string) error { + log.Println("gui.SetText() value =", value) + if (n.Toolkit != nil) { + 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()") +} diff --git a/toolkit/andlabs/box.go b/toolkit/andlabs/box.go new file mode 100644 index 0000000..548c90a --- /dev/null +++ b/toolkit/andlabs/box.go @@ -0,0 +1,49 @@ +package toolkit + +import "log" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// create a new box +func (t *Toolkit) GetBox() *ui.Box { + return t.uiBox +} + +// create a new box +func (t *Toolkit) NewBox() *Toolkit { + log.Println("gui.Toolbox.NewBox() START create default") + t.Dump() + if (t.uiGroup != nil) { + log.Println("gui.Toolbox.NewBox() is a Group") + var newTK Toolkit + + vbox := ui.NewVerticalBox() + vbox.SetPadded(true) + t.uiGroup.SetChild(vbox) + newTK.uiBox = vbox + + return &newTK + } + if (t.uiBox != nil) { + log.Println("gui.Toolbox.NewBox() is a Box") + // return t + } + log.Println("gui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box") + t.Dump() + return nil +} + +// Make a new box +func MakeBox(name string) *Toolkit { + var newt Toolkit + + vbox := ui.NewVerticalBox() + vbox.SetPadded(border) + newt.uiBox = vbox + newt.Name = name + + log.Println("gui.Toolbox.MakeBox() name =", name) + newt.Dump() + return &newt +} diff --git a/toolkit/andlabs/button.go b/toolkit/andlabs/button.go new file mode 100644 index 0000000..3278c09 --- /dev/null +++ b/toolkit/andlabs/button.go @@ -0,0 +1,50 @@ +package toolkit + +import "log" +import "os" + +import "github.com/andlabs/ui" +import _ "github.com/andlabs/ui/winmanifest" + +// make new Group here +func (t Toolkit) NewButton(name string) *Toolkit { + var newt Toolkit + var b *ui.Button + + if (t.uiBox == nil) { + log.Println("gui.ToolboxNode.NewButton() 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?") + os.Exit(0) + return nil + } + + log.Println("gui.Toolbox.NewGroup() create", name) + b = ui.NewButton(name) + newt.uiButton = b + + b.OnClicked(func(*ui.Button) { + log.Println("TODO: IN TOOLKIT GOROUTINE. SHOULD LEAVE HERE VIA channels. button name =", name) + t.Dump() + newt.Dump() + log.Println("wit/gui/toolkit NewButton() Should do something here") + if (newt.Custom == nil) { + log.Println("wit/gui/toolkit NewButton() toolkit.Custom == nil") + } else { + log.Println("wit/gui/toolkit NewButton() toolkit.Custom() START") + newt.Custom() + log.Println("wit/gui/toolkit NewButton() toolkit.Custom() END") + } + if (t.Custom == nil) { + log.Println("wit/gui/toolkit NewButton() parent toolkit.Custom == nil") + } else { + log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() START (IS THIS A BAD IDEA?)") + t.Custom() + log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() END (IS THIS A BAD IDEA?)") + } + log.Println("TODO: LEFT TOOLKIT GOROUTINE button name =", name) + }) + + t.uiBox.Append(b, false) + + return &newt +} diff --git a/toolkit/andlabs/group.go b/toolkit/andlabs/group.go index 1c3f63e..12d9206 100644 --- a/toolkit/andlabs/group.go +++ b/toolkit/andlabs/group.go @@ -1,59 +1,37 @@ package toolkit import "log" +import "os" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" // make new Group here -func NewGroup(b *ui.Box, title string) *Toolkit { - var t Toolkit +func (t Toolkit) NewGroup(title string) *Toolkit { + var newt 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 &t + 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("probably could just make a box here?") + os.Exit(0) + return nil } log.Println("gui.Toolbox.NewGroup() create", title) g := ui.NewGroup(title) g.SetMargined(true) - t.uiGroup = g - t.uiBox = b - t.uiBox.Append(g, false) + t.uiBox.Append(g, streachy) - return &t -} - -// create a new box -func (t *Toolkit) GetBox() *ui.Box { - return t.uiBox -} - -// create a new box -func (t *Toolkit) NewBox() *Toolkit { - log.Println("gui.Toolbox.NewBox() START create default") - if (t.uiGroup != nil) { - log.Println("gui.Toolbox.NewBox() is a Group") - var newTK Toolkit + hbox := ui.NewVerticalBox() + hbox.SetPadded(true) + g.SetChild(hbox) - vbox := ui.NewVerticalBox() - vbox.SetPadded(true) - t.uiGroup.SetChild(vbox) - newTK.uiBox = vbox + newt.uiGroup = g + newt.uiBox = hbox + newt.Name = title - return &newTK - } - log.Println("gui.Toolbox.NewBox() FAILED") - return nil + t.Dump() + newt.Dump() + // panic("toolkit.NewGroup") + return &newt } - -/* -func (n *Node) NewGroup(title string) *Node { - group := ui.NewGroup(title) - group.SetMargined(true) - hbox.Append(group, true) - - vbox := ui.NewVerticalBox() - vbox.SetPadded(true) - group.SetChild(vbox) -*/ diff --git a/toolkit/andlabs/label.go b/toolkit/andlabs/label.go index 23d4927..453412a 100644 --- a/toolkit/andlabs/label.go +++ b/toolkit/andlabs/label.go @@ -1,23 +1,31 @@ package toolkit import "log" +import "os" import "github.com/andlabs/ui" import _ "github.com/andlabs/ui/winmanifest" -func NewLabel(b *ui.Box, name string) *Toolkit { +// func NewLabel(b *ui.Box, name string) *Toolkit { + +func (t *Toolkit) NewLabel(name string) *Toolkit { // make new node here log.Println("gui.Toolbox.NewLabel", name) - var t Toolkit - if (b == nil) { + if (t.uiBox == nil) { log.Println("gui.ToolboxNode.NewLabel() node.UiBox == nil. I can't add a range UI element without a place to put it") - return &t + os.Exit(0) + return nil } - l := ui.NewLabel(name) - t.uiLabel = l - t.uiBox = b - t.uiBox.Append(l, false) + var newt Toolkit + newt.uiLabel = ui.NewLabel(name) + newt.uiBox = t.uiBox + t.uiBox.Append(newt.uiLabel, false) + log.Println("parent toolkit") + t.Dump() + log.Println("newt toolkit") + newt.Dump() + // panic("got here") - return &t + return &newt } diff --git a/toolkit/andlabs/slider.go b/toolkit/andlabs/slider.go index 930c514..65cf531 100644 --- a/toolkit/andlabs/slider.go +++ b/toolkit/andlabs/slider.go @@ -1,38 +1,44 @@ 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, x int, y int) *Toolkit { +// func NewSlider(b *ui.Box, name string *Toolkit { +func (t Toolkit) NewSlider(title string, x int, y int) *Toolkit { // make new node here log.Println("gui.Toolbox.NewSpinbox()", x, y) - var t Toolkit + var newt 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 &t + 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("probably could just make a box here?") + os.Exit(0) + return nil } + s := ui.NewSlider(x, y) - t.uiSlider = s - t.uiBox = b + newt.uiSlider = s + newt.uiBox = t.uiBox t.uiBox.Append(s, false) s.OnChanged(func(spin *ui.Slider) { i := spin.Value() + log.Println("gui.Toolbox.ui.Slider.OnChanged() val =", i) if (DebugToolkit) { log.Println("gui.Toolbox.ui.OnChanged() val =", i) scs := spew.ConfigState{MaxDepth: 1} - scs.Dump(t) + scs.Dump(newt) } if (t.OnChanged != nil) { log.Println("gui.Toolbox.OnChanged() entered val =", i) - t.OnChanged(&t) + newt.OnChanged(&newt) } }) - return &t + return &newt } diff --git a/toolkit/andlabs/spinbox.go b/toolkit/andlabs/spinbox.go index d3d7bfe..c47fab7 100644 --- a/toolkit/andlabs/spinbox.go +++ b/toolkit/andlabs/spinbox.go @@ -14,7 +14,7 @@ func NewSpinbox(b *ui.Box, name string, x int, y int) *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 &t + return nil } spin := ui.NewSpinbox(x, y) t.uiSpinbox = spin diff --git a/toolkit/andlabs/structs.go b/toolkit/andlabs/structs.go index ab75139..a089a12 100644 --- a/toolkit/andlabs/structs.go +++ b/toolkit/andlabs/structs.go @@ -9,6 +9,10 @@ import "github.com/davecgh/go-spew/spew" var DebugToolkit bool = false +var streachy = true +var border = true + + // stores the raw toolkit internals type Toolkit struct { id string @@ -18,8 +22,12 @@ type Toolkit struct { Height int OnChanged func(*Toolkit) + OnExit func(*Toolkit) + + Custom func() uiBox *ui.Box + uiBox2 *ui.Box // temporary hack while implementing tabs uiButton *ui.Button uiControl *ui.Control uiEntry *ui.Entry @@ -30,11 +38,7 @@ type Toolkit struct { uiTab *ui.Tab uiText *ui.EditableCombobox uiWindow *ui.Window -} - -func (t *Toolkit) Dump() { - log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox) - log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup) + UiWindowBad *ui.Window } func (t *Toolkit) GetText() string { @@ -68,6 +72,31 @@ func (t *Toolkit) SetText(s string) bool { return false } +func sanity(t *Toolkit) bool { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() Enter") + scs := spew.ConfigState{MaxDepth: 1} + scs.Dump(t) + } + if (t.uiEntry == nil) { + if (DebugToolkit) { + log.Println("gui.Toolkit.Value() =", t.uiEntry.Text) + } + return false + } + return true +} + +func (t *Toolkit) SetValue(i int) bool { + log.Println("gui.Toolkit.SetValue() START") + if (sanity(t)) { + return false + } + t.Dump() + // panic("got to toolkit.SetValue") + return true +} + func (t *Toolkit) Value() int { if (DebugToolkit) { log.Println("gui.Toolkit.Value() Enter") @@ -93,3 +122,28 @@ func (t *Toolkit) Value() int { log.Println("gui.Toolkit.Value() Could not find a ui element to get a value from") return 0 } + +func (t *Toolkit) Dump() { + log.Println("gui.Toolkit.Dump()", t.Name, t.Width, t.Height) + if (t.uiBox != nil) { + log.Println("gui.Toolkit.Dump() uiBox =", t.uiBox) + } + if (t.uiButton != nil) { + log.Println("gui.Toolkit.Dump() uiButton =", t.uiButton) + } + if (t.uiWindow != nil) { + log.Println("gui.Toolkit.Dump() uiWindow =", t.uiWindow) + } + if (t.uiTab != nil) { + log.Println("gui.Toolkit.Dump() uiTab =", t.uiTab) + } + if (t.uiGroup != nil) { + log.Println("gui.Toolkit.Dump() uiGroup =", t.uiGroup) + } + if (t.uiSlider != nil) { + log.Println("gui.Toolkit.Dump() uiSlider =", t.uiSlider) + } + if (t.OnExit != nil) { + log.Println("gui.Toolkit.Dump() uiExit =", t.OnExit) + } +} diff --git a/toolkit/andlabs/tab.go b/toolkit/andlabs/tab.go new file mode 100644 index 0000000..c068022 --- /dev/null +++ b/toolkit/andlabs/tab.go @@ -0,0 +1,143 @@ +package toolkit + +import ( + "log" + "time" + + "github.com/andlabs/ui" + _ "github.com/andlabs/ui/winmanifest" + +) + +/* + This adds a tab + + andlabs/ui is goofy in the sense that you have to determine + if the ui.Window already has a tab in it. If it does, then + you need to add this tab and not run SetChild() on the window + or instead it replaces the existing tab with the new one + + I work around this by always sending a Toolkit that is a tab + once there is one. If you send a Window here, it will replace + any existing tabs rather than adding a new one +*/ +func (t *Toolkit) AddTab(name string) *Toolkit { + var w *ui.Window + var newt *Toolkit + + log.Println("gui.Toolbox.AddTab() sleep 3") + + w = t.uiWindow + if (w == nil) { + log.Println("gui.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window") + return nil + } + + if (t.uiTab == nil) { + // this means you have to make a new tab + log.Println("gui.Toolbox.NewTab() GOOD. This should be the first tab:", name) + newt = newTab(w, name) + t.uiTab = newt.uiTab + } else { + log.Println("gui.Toolbox.NewTab() GOOD. This should be an additional tab:", name) + newt = t.appendTab(name) + // this means you have to append a tab + } + log.Println("t:") + t.Dump() + log.Println("newt:") + newt.Dump() + + return newt +} + +func (t *Toolkit) SetTabBox(box *ui.Box) { + var tab *ui.Tab + + log.Println("wit/gui/toolkit SetTabBox()") + t.Dump() + if (t.uiTab == nil) { + log.Println("wit/gui/toolkit SetTabBox() got uiTab == nil") + panic("fucknuts") + return + } + if (t.uiBox == nil) { + log.Println("wit/gui/toolkit SetTabBox() got uiBox == nil. Appending a new tab here") + tab = t.uiTab + tab.Append(t.Name, box) + tabSetMargined(tab) + return + } else { + log.Println("wit/gui/toolkit SetTabBox() got uiBox != nil. Appending the box to the existing box strechy = true") + t.uiBox.Append(box, true) // strechy == true + t.uiBox2 = box + // t.uiBox.Append(box, false) // strechy == false + return + } + +} + +// This sets _all_ the tabs to Margin = true +// +// TODO: do proper tab tracking (will be complicated). low priority +func tabSetMargined(tab *ui.Tab) { + c := tab.NumPages() + for i := 0; i < c; i++ { + tab.SetMargined(i, true) + } +} + +func newTab(w *ui.Window, name string) *Toolkit { + log.Println("gui.Toolbox.NewTab() ADD", name) + var t Toolkit + + if (w == nil) { + log.Println("gui.Toolbox.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.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window") + time.Sleep(1 * time.Second) + return nil + } + log.Println("gui.Toolbox.AddTab() START name =", name) + // time.Sleep(2 * time.Second) + tab := ui.NewTab() + w.SetMargined(true) + + hbox := ui.NewHorizontalBox() // this makes everything go along the horizon + // hbox := ui.NewVerticalBox() + hbox.SetPadded(true) + tab.Append(name, hbox) + w.SetChild(tab) + + t.uiWindow = w + t.uiTab = tab + t.uiBox = hbox + // tabSetMargined(newNode.uiTab) + return &t +} + +func (t *Toolkit) appendTab(name string) *Toolkit { + log.Println("gui.Toolbox.NewTab() ADD", name) + var newT Toolkit + + if (t.uiWindow == nil) { + log.Println("gui.Toolbox.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.Toolbox.NewTab() node.UiWindow == nil. I can't add a tab without a window") + time.Sleep(1 * time.Second) + return nil + } + log.Println("gui.Toolbox.AddTab() START name =", name) + + hbox := ui.NewHorizontalBox() // this makes everything go along the horizon + // hbox := ui.NewVerticalBox() + hbox.SetPadded(true) + t.uiTab.Append(name, hbox) + // w.SetChild(tab) + + newT.uiWindow = t.uiWindow + newT.uiTab = t.uiTab + newT.uiBox = hbox + // tabSetMargined(newNode.uiTab) + return &newT +} diff --git a/toolkit/andlabs/window.go b/toolkit/andlabs/window.go new file mode 100644 index 0000000..f0357ed --- /dev/null +++ b/toolkit/andlabs/window.go @@ -0,0 +1,45 @@ +package toolkit + +import ( + "log" + "os" + + "github.com/andlabs/ui" + _ "github.com/andlabs/ui/winmanifest" +) + +func (t *Toolkit) MessageWindow(msg1 string, msg2 string) { + ui.MsgBox(t.uiWindow, msg1, msg2) +} + +func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) { + ui.MsgBoxError(t.uiWindow, msg1, msg2) +} + +func NewWindow(title string, x int, y int) *Toolkit { + var t Toolkit + log.Println("toolkit NewWindow", title, x, y) + w := ui.NewWindow(title, x, y, false) + w.SetBorderless(false) + w.OnClosing(func(*ui.Window) bool { + log.Println("ui.Window().OnExit() SHOULD ATTEMPT CALLBACK here") + t.Dump() + if (t.OnExit != nil) { + log.Println("ui.Window().OnExit() ATTEMPTING toolkit.OnExit CALLBACK") + t.OnExit(&t) + } + if (t.Custom != nil) { + log.Println("ui.Window().Custom() ATTEMPTING toolkit.Custom CALLBACK") + t.Custom() + } + log.Println("ui.Window().OnExit() Toolkit.OnExit is nil") + t.Dump() + os.Exit(0) + return true + }) + w.SetMargined(true) + w.Show() + t.uiWindow = w + t.UiWindowBad = w // deprecate this as soon as possible + return &t +} diff --git a/toolkit/gocui/mouse.go b/toolkit/gocui/mouse.go new file mode 100644 index 0000000..7c77b14 --- /dev/null +++ b/toolkit/gocui/mouse.go @@ -0,0 +1,186 @@ +// Copyright 2014 The gocui Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package toolkit + +import ( + "errors" + "fmt" + "log" + "os" + + "github.com/awesome-gocui/gocui" +) + +var g *gocui.Gui +var err error +var Custom func(string) + +func OnExit(f func(string)) { + Custom = f +} + +func Exit() { + g.Close() +} + +func mouseClick(name string) { + // output screws up the console. Need to fix this by redirecting all console output to a file from log.Println() + // log.Println("g.Close()") + // g.Close() + + log.Println("Found andlabs Running custom function for the mouse click") + Custom(name) + // panic("got andlabs") +} + +func Init() { + log.Println("start Init()") + + f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666) + if err != nil { + log.Fatalf("error opening file: %v", err) + } + defer f.Close() + + log.SetOutput(f) + log.Println("This is a test log entry") + + g, err = gocui.NewGui(gocui.OutputNormal, true) + if err != nil { + log.Panicln(err) + } + + g.Cursor = true + g.Mouse = true + + g.SetManagerFunc(layout) + + if err := keybindings(g); err != nil { + log.Panicln(err) + } + log.Println("exit Init()") +} + +func StartConsoleMouse() { + defer g.Close() + log.Println("start Main()") + + if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { + log.Panicln(err) + } + log.Println("exit Main()") +} + +func layout(g *gocui.Gui) error { + if v, err := g.SetView("but1", 2, 2, 22, 17, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + v.Highlight = true + v.SelBgColor = gocui.ColorGreen + v.SelFgColor = gocui.ColorBlack + fmt.Fprintln(v, "andlabs") + fmt.Fprintln(v, "addDemoTab") + fmt.Fprintln(v, "DemoToolkitWindow") + fmt.Fprintln(v, "DebugWindow") + fmt.Fprintln(v, "do nothing") + fmt.Fprintln(v, "exit") + if _, err := g.SetCurrentView("but1"); err != nil { + return err + } + } + if v, err := g.SetView("but2", 24, 2, 44, 4, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + v.Highlight = true + v.SelBgColor = gocui.ColorGreen + v.SelFgColor = gocui.ColorBlack + fmt.Fprintln(v, "Button 2 - line 1") + } + if v, err := g.SetView("but3", 24, 2, 44, 4, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + v.Highlight = true + v.SelBgColor = gocui.ColorGreen + v.SelFgColor = gocui.ColorBlack + fmt.Fprintln(v, "Button 2 - line 1") + } + if v, err := g.SetView("but4", 24, 2, 44, 4, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + v.Highlight = true + v.SelBgColor = gocui.ColorGreen + v.SelFgColor = gocui.ColorBlack + fmt.Fprintln(v, "Button 2 - line 1") + } + if v, err := g.SetView("but5", 24, 2, 44, 4, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + v.Highlight = true + v.SelBgColor = gocui.ColorGreen + v.SelFgColor = gocui.ColorBlack + fmt.Fprintln(v, "Button 2 - line 1") + } + return nil +} + +func keybindings(g *gocui.Gui) error { + if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil { + return err + } + for _, n := range []string{"but1", "but2"} { + if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil { + return err + } + } + if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, delMsg); err != nil { + return err + } + if err := g.SetKeybinding("", gocui.MouseRight, gocui.ModNone, delMsg); err != nil { + return err + } + if err := g.SetKeybinding("", gocui.MouseMiddle, gocui.ModNone, delMsg); err != nil { + return err + } + return nil +} + +func quit(g *gocui.Gui, v *gocui.View) error { + return gocui.ErrQuit +} + +func showMsg(g *gocui.Gui, v *gocui.View) error { + var l string + var err error + + if _, err := g.SetCurrentView(v.Name()); err != nil { + return err + } + + _, cy := v.Cursor() + if l, err = v.Line(cy); err != nil { + l = "" + } + + maxX, maxY := g.Size() + if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err != nil { + if !errors.Is(err, gocui.ErrUnknownView) { + return err + } + mouseClick(l) + fmt.Fprintln(v, l) + } + return nil +} + +func delMsg(g *gocui.Gui, v *gocui.View) error { + // Error check removed, because delete could be called multiple times with the above keybindings + g.DeleteView("msg") + return nil +} diff --git a/window-toolkit-demo.go b/window-demo-toolkit.go index 84a1f13..df6268e 100644 --- a/window-toolkit-demo.go +++ b/window-demo-toolkit.go @@ -13,14 +13,21 @@ func NewStandardWindow(title string) *Node { Config.Exit = StandardClose return NewWindow() } -func ToolkitDemoWindow() { + +// +// This creates a window that shows how the toolkit works +// internally using it's raw unchanged code for the toolkit itself +// +// This is a way to test and see if the toolkit is working at all +// right now it shows the andlabs/ui/DemoNumbersPage() +// +func DemoToolkitWindow() { var w, d *Node var tk *toolkit.Toolkit w = NewStandardWindow("Demo of the GUI Toolkit") - d = w.makeNode("demo", 767, 676 + Config.counter) - d.Name = "demo" + d = w.New("demo") tk = toolkit.DemoNumbersPage(w.uiWindow) tk.OnChanged = func(t *toolkit.Toolkit) { diff --git a/window-demo.go b/window-demo.go new file mode 100644 index 0000000..c4e0374 --- /dev/null +++ b/window-demo.go @@ -0,0 +1,20 @@ +package gui + +import "log" +// import "time" +// import toolkit "git.wit.org/wit/gui/toolkit/andlabs" + +// +// This creates a window that shows how this package works +// +func DemoWindow() { + var w, t1 *Node + log.Println("DemoWindow() START") + + w = NewStandardWindow("Demo of WIT/GUI") + + t1 = w.DebugTab("WIT GUI Debug Tab t1") + t1.DebugTab("WIT GUI Debug Tab t2") + + log.Println("DemoWindow() END") +} diff --git a/window-golang-debug.go b/window-golang-debug.go index 1e47081..8598f3a 100644 --- a/window-golang-debug.go +++ b/window-golang-debug.go @@ -26,12 +26,12 @@ func GolangDebugWindow() { Config.Exit = StandardClose w = NewWindow() - t = w.AddTab("Debug Tab", nil) + t = w.NewTab("Debug Tab") log.Println("debugWindow() START") /////////////////////////////// Column DEBUG GOLANG ////////////////////// - g := t.NewGroup("GO Language") + g := t.AddGroup("GO Language") g.AddButton("runtime.Stack()", func (*Node) { log.Println("\tSTART") @@ -2,13 +2,15 @@ package gui import ( "log" - "fmt" "strconv" - "github.com/andlabs/ui" - _ "github.com/andlabs/ui/winmanifest" +// "github.com/andlabs/ui" +// _ "github.com/andlabs/ui/winmanifest" ) +import toolkit "git.wit.org/wit/gui/toolkit/andlabs" + +/* func MessageWindow(gw *GuiWindow, msg1 string, msg2 string) { ui.MsgBox(gw.UiWindow, msg1, msg2) } @@ -16,6 +18,7 @@ func MessageWindow(gw *GuiWindow, msg1 string, msg2 string) { 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) @@ -58,96 +61,8 @@ func DeleteWindow(name string) { } } -/* -generic function to create a newnode structure on the tree of nodes - -If the parent is null, it tries to find out where it should go otherwise -it creates a new window or new tab depending on the toolkit or OS -*/ -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 (parent *Node) makeNode(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 - - 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 - }) - w.SetMargined(true) - w.Show() - n.uiWindow = w - // w.node = &node - return -} - -func mapWindow(parent *Node, window *ui.Window, title string, x int, y int) *Node { +// 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) @@ -161,10 +76,10 @@ func mapWindow(parent *Node, window *ui.Window, title string, x int, y int) *Nod } var newGuiWindow GuiWindow - newGuiWindow.Width = x - newGuiWindow.Height = y + newGuiWindow.Width = w + newGuiWindow.Height = h newGuiWindow.Name = title - newGuiWindow.UiWindow = window + // newGuiWindow.UiWindow = window newGuiWindow.BoxMap = make(map[string]*GuiBox) newGuiWindow.EntryMap = make(map[string]*GuiEntry) @@ -175,9 +90,8 @@ func mapWindow(parent *Node, window *ui.Window, title string, x int, y int) *Nod box.Window = &newGuiWindow box.Name = title - node := makeNode(parent, title, x, y) + node := addNode(title, w, h) node.box = &box - node.uiWindow = window box.node = node newGuiWindow.BoxMap["jcarrInitTest"] = &box @@ -192,19 +106,30 @@ func mapWindow(parent *Node, window *ui.Window, title string, x int, y int) *Nod // cross platform, must pass UI changes into the OS threads (that is // my guess). func NewWindow() *Node { + var n *Node + var t *toolkit.Toolkit + title := Config.Title w := Config.Width h := Config.Height f := Config.Exit - var n *Node - n = mapWindow(nil, nil, title, w, h) + n = mapWindow(title, w, h) + n.custom = f box := n.box log.Println("gui.NewWindow() title = box.Name =", box.Name) - n.uiNewWindow(box.Name, w, h) + t = toolkit.NewWindow(title, w, h) + t.Custom = func () { + log.Println("GOT TO MY CUSTOM EXIT!!!! for window name:", box.Name) + f(n) + } + 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) { @@ -212,6 +137,7 @@ func NewWindow() *Node { } return true }) + */ box.Window.UiWindow = window if(n.uiWindow == nil) { |
