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()
This commit is contained in:
Jeff Carr 2022-10-19 13:23:22 -05:00
parent a482e34efa
commit 6286635049
36 changed files with 1124 additions and 480 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
*.swp
cmds/gui-demo/gui-demo
cmds/helloworld/helloworld
cmds/consolemouse/consolemouse

View File

@ -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

20
box.go
View File

@ -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 {

View File

@ -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)

View File

@ -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 .

View File

@ -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)
}
}

61
cmds/consolemouse/main.go Normal file
View File

@ -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)
}

View File

@ -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()")
}

View File

@ -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 .

View File

@ -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
g := newNode.NewGroup("group 1")
// g.Dump()
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()
// os.Exit(0)
g.AddComboBox("demoCombo2", "more 1", "more 2", "more 3")
}

View File

@ -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
}

View File

@ -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 {

30
doc.go
View File

@ -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

View File

@ -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
}

View File

@ -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)
*/

30
int.go
View File

@ -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)
}

View File

@ -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
}

40
node.go Normal file
View File

@ -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
}

View File

@ -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
}

View File

@ -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) {

75
tab.go
View File

@ -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
tab := n.uiTab
if (tab == nil) {
log.Println("gui.Node.AddTabRaw() FAIL tab == nil")
return n
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)
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
}
*/

40
text.go Normal file
View File

@ -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()")
}

49
toolkit/andlabs/box.go Normal file
View File

@ -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
}

50
toolkit/andlabs/button.go Normal file
View File

@ -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
}

View File

@ -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
hbox := ui.NewVerticalBox()
hbox.SetPadded(true)
g.SetChild(hbox)
newt.uiGroup = g
newt.uiBox = hbox
newt.Name = title
t.Dump()
newt.Dump()
// panic("toolkit.NewGroup")
return &newt
}
// 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
vbox := ui.NewVerticalBox()
vbox.SetPadded(true)
t.uiGroup.SetChild(vbox)
newTK.uiBox = vbox
return &newTK
}
log.Println("gui.Toolbox.NewBox() FAILED")
return nil
}
/*
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)
*/

View File

@ -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
}

View File

@ -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
}

View File

@ -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

View File

@ -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)
}
}

143
toolkit/andlabs/tab.go Normal file
View File

@ -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
}

45
toolkit/andlabs/window.go Normal file
View File

@ -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
}

186
toolkit/gocui/mouse.go Normal file
View File

@ -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
}

View File

@ -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) {

20
window-demo.go Normal file
View File

@ -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")
}

View File

@ -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")

128
window.go
View File

@ -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) {