Compare commits
9 Commits
4e7bbd8990
...
3f7cca35f3
Author | SHA1 | Date |
---|---|---|
|
3f7cca35f3 | |
|
60ede602fc | |
|
49f8029a5f | |
|
0a20b22a6c | |
|
3f42ba1882 | |
|
0090da64fc | |
|
a08bbaf04f | |
|
d8f1107387 | |
|
e9a0ee35c9 |
|
@ -1,15 +1 @@
|
||||||
*.swp
|
*.swp
|
||||||
|
|
||||||
# ignore compiled plugins
|
|
||||||
*.so
|
|
||||||
|
|
||||||
examples/buttons/buttons
|
|
||||||
examples/console-ui-helloworld/console-ui-helloworld
|
|
||||||
examples/helloworld/helloworld
|
|
||||||
|
|
||||||
# protobuf compiled files
|
|
||||||
protobuf/*.pb.go
|
|
||||||
|
|
||||||
# temporary files when building debian packages
|
|
||||||
/*.deb
|
|
||||||
/files
|
|
||||||
|
|
17
Makefile
17
Makefile
|
@ -37,11 +37,6 @@ update:
|
||||||
git pull
|
git pull
|
||||||
go get -v -t -u ./...
|
go get -v -t -u ./...
|
||||||
|
|
||||||
deb:
|
|
||||||
cd debian && make
|
|
||||||
dpkg-deb -c go-wit-gui*.deb
|
|
||||||
-wit mirrors
|
|
||||||
|
|
||||||
examples: \
|
examples: \
|
||||||
all \
|
all \
|
||||||
examples-helloworld \
|
examples-helloworld \
|
||||||
|
@ -58,10 +53,15 @@ examples-buttons:
|
||||||
examples-console-ui-helloworld:
|
examples-console-ui-helloworld:
|
||||||
make -C examples/console-ui-helloworld
|
make -C examples/console-ui-helloworld
|
||||||
|
|
||||||
|
git.wit.org:
|
||||||
|
git push witgui master
|
||||||
|
git push witgui devel
|
||||||
|
git push witgui jcarr
|
||||||
|
git push witgui --tags
|
||||||
|
|
||||||
# sync repo to the github backup
|
# sync repo to the github backup
|
||||||
# git remote add github git@github.com:witorg/gui.git
|
# git remote add github git@github.com:wit-go/gui.git
|
||||||
# git remote add github2 git@github.com:wit-go/gui.git
|
github: git.wit.org
|
||||||
github:
|
|
||||||
git push origin master
|
git push origin master
|
||||||
git push origin devel
|
git push origin devel
|
||||||
git push origin --tags
|
git push origin --tags
|
||||||
|
@ -82,7 +82,6 @@ goget:
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f toolkit/*.so
|
rm -f toolkit/*.so
|
||||||
cd debian && make clean
|
|
||||||
|
|
||||||
plugins: plugins-gocui plugins-andlabs
|
plugins: plugins-gocui plugins-andlabs
|
||||||
|
|
||||||
|
|
23
README.md
23
README.md
|
@ -38,32 +38,21 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
"git.wit.org/wit/gui"
|
"go.wit.com/wit/gui/gui"
|
||||||
)
|
)
|
||||||
|
|
||||||
var window *gui.Node // This is the beginning of the binary tree of widgets
|
var myGui *gui.Node // This is your gui object
|
||||||
|
|
||||||
// go will sit here until the window exits
|
// go will sit here until the window exits
|
||||||
func main() {
|
func main() {
|
||||||
gui.Init()
|
myGui = gui.Init()
|
||||||
gui.Main(helloworld)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This initializes the first window and 2 tabs
|
// This initializes the first window and 2 tabs
|
||||||
func helloworld() {
|
func helloworld() {
|
||||||
gui.Config.Title = "Hello World golang wit/gui Window"
|
window := myGui.NewWindow()
|
||||||
gui.Config.Width = 640
|
|
||||||
gui.Config.Height = 480
|
|
||||||
|
|
||||||
window := gui.NewWindow()
|
group := window.NewGroup("foo bar")
|
||||||
addTab(window, "A Simple Tab Demo")
|
|
||||||
addTab(window, "A Second Tab")
|
|
||||||
}
|
|
||||||
|
|
||||||
func addTab(w *gui.Node, title string) {
|
|
||||||
tab := w.NewTab(title)
|
|
||||||
|
|
||||||
group := tab.NewGroup("foo bar")
|
|
||||||
group.NewButton("hello", func() {
|
group.NewButton("hello", func() {
|
||||||
log.Println("world")
|
log.Println("world")
|
||||||
})
|
})
|
||||||
|
@ -94,7 +83,7 @@ Useful links and other
|
||||||
external things which might be useful
|
external things which might be useful
|
||||||
|
|
||||||
* Wikipedia Graphical widget - [https://en.wikipedia.org/wiki/Graphical_widget](https://en.wikipedia.org/wiki/Graphical_widget)
|
* Wikipedia Graphical widget - [https://en.wikipedia.org/wiki/Graphical_widget](https://en.wikipedia.org/wiki/Graphical_widget)
|
||||||
* Github mirror - [https://github.com/witorg/gui](https://github.com/witorg/gui)
|
* Github mirror - [https://github.com/wit-go/gui](https://github.com/wit-go/gui)
|
||||||
* Federated git pull - [https://github.com/forgefed/forgefed](https://github.com/forgefed/forgefed)
|
* Federated git pull - [https://github.com/forgefed/forgefed](https://github.com/forgefed/forgefed)
|
||||||
* GO Style Guide - [https://google.github.io/styleguide/go/index](https://google.github.io/styleguide/go/index)
|
* GO Style Guide - [https://google.github.io/styleguide/go/index](https://google.github.io/styleguide/go/index)
|
||||||
|
|
||||||
|
|
59
args.go
59
args.go
|
@ -3,34 +3,63 @@ package gui
|
||||||
import (
|
import (
|
||||||
arg "github.com/alexflint/go-arg"
|
arg "github.com/alexflint/go-arg"
|
||||||
|
|
||||||
newlog "go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var INFO log.LogFlag
|
||||||
|
|
||||||
|
var GUI log.LogFlag
|
||||||
|
var NODE log.LogFlag
|
||||||
|
var PLUG log.LogFlag
|
||||||
|
var CHANGE log.LogFlag
|
||||||
|
|
||||||
var argGui ArgsGui
|
var argGui ArgsGui
|
||||||
|
|
||||||
// This struct can be used with the go-arg package
|
// This struct can be used with the go-arg package
|
||||||
type ArgsGui struct {
|
type ArgsGui struct {
|
||||||
GuiDebug bool `arg:"--gui-debug" help:"open the GUI debugger"`
|
|
||||||
GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"`
|
GuiPlugin string `arg:"--gui" help:"Use this gui toolkit [andlabs,gocui,nocui]"`
|
||||||
GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
|
GuiVerbose bool `arg:"--gui-verbose" help:"enable all logging"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
|
||||||
arg.Register(&argGui)
|
|
||||||
|
|
||||||
newlog.Register("gui", "debugGui", &debugGui)
|
|
||||||
|
|
||||||
for _, s := range newlog.ListFlags() {
|
|
||||||
newlog.Info("go.wit.org/gui ListFlags() returned:", s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns the toolkit
|
// returns the toolkit
|
||||||
func ArgToolkit() string {
|
func ArgToolkit() string {
|
||||||
return argGui.GuiPlugin
|
return argGui.GuiPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if --gui-debug was passed from the command line
|
func init() {
|
||||||
func ArgDebug() bool {
|
arg.Register(&argGui)
|
||||||
return argGui.GuiDebug
|
|
||||||
|
INFO.B = false
|
||||||
|
INFO.Name = "INFO"
|
||||||
|
INFO.Subsystem = "gui"
|
||||||
|
INFO.Desc = "Enable log.Info()"
|
||||||
|
INFO.Register()
|
||||||
|
|
||||||
|
GUI.B = false
|
||||||
|
GUI.Name = "GUI"
|
||||||
|
GUI.Subsystem = "gui"
|
||||||
|
GUI.Desc = "basic GUI debugging"
|
||||||
|
GUI.Register()
|
||||||
|
|
||||||
|
NODE.B = false
|
||||||
|
NODE.Name = "NODE"
|
||||||
|
NODE.Subsystem = "gui"
|
||||||
|
NODE.Desc = "basic NODE debugging"
|
||||||
|
NODE.Register()
|
||||||
|
|
||||||
|
PLUG.B = false
|
||||||
|
PLUG.Name = "PLUG"
|
||||||
|
PLUG.Subsystem = "gui"
|
||||||
|
PLUG.Desc = "basic PLUG debugging"
|
||||||
|
PLUG.Register()
|
||||||
|
|
||||||
|
CHANGE.B = false
|
||||||
|
CHANGE.Name = "CHANGE"
|
||||||
|
CHANGE.Subsystem = "gui"
|
||||||
|
CHANGE.Desc = "user changed something"
|
||||||
|
CHANGE.Register()
|
||||||
|
|
||||||
|
for _, s := range log.ListFlags() {
|
||||||
|
log.Info("go.wit.com/gui/gui ListFlags() returned:", s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
2
box.go
2
box.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewBox(name string, b bool) *Node {
|
func (parent *Node) NewBox(name string, b bool) *Node {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/gui/toolkit"
|
import "go.wit.com/gui/toolkits"
|
||||||
|
|
||||||
func (parent *Node) NewButton(name string, custom func()) *Node {
|
func (parent *Node) NewButton(name string, custom func()) *Node {
|
||||||
newNode := parent.newNode(name, toolkit.Button)
|
newNode := parent.newNode(name, toolkit.Button)
|
||||||
|
|
122
chan.go
122
chan.go
|
@ -1,122 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
// channel communication to the plugins
|
|
||||||
// https://github.com/sourcegraph/conc
|
|
||||||
// https://www.reddit.com/r/golang/comments/11x1oek/hello_gophers_show_me_your_concurrent_code/
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "regexp"
|
|
||||||
// "go.wit.com/gui/toolkit"
|
|
||||||
"sync"
|
|
||||||
"runtime"
|
|
||||||
"github.com/sourcegraph/conc"
|
|
||||||
"github.com/sourcegraph/conc/stream"
|
|
||||||
"github.com/sourcegraph/conc/panics"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this should never exit
|
|
||||||
// TODO: clean up all this poorly named code
|
|
||||||
func makeConc() {
|
|
||||||
var wg conc.WaitGroup
|
|
||||||
defer wg.Wait()
|
|
||||||
|
|
||||||
startTheThing(&wg)
|
|
||||||
log(debugError, "panic?")
|
|
||||||
sleep(2)
|
|
||||||
log(debugError, "panic? after sleep(5)")
|
|
||||||
}
|
|
||||||
|
|
||||||
func startTheThing(wg *conc.WaitGroup) {
|
|
||||||
f := func() {
|
|
||||||
log(debugError, "startTheThing() == about to panic now")
|
|
||||||
panic("test conc.WaitGroup")
|
|
||||||
}
|
|
||||||
wg.Go(func() {
|
|
||||||
ExampleCatcher(f)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExampleCatcher(f func()) {
|
|
||||||
var pc panics.Catcher
|
|
||||||
i := 0
|
|
||||||
pc.Try(func() { i += 1 })
|
|
||||||
pc.Try(f)
|
|
||||||
pc.Try(func() { i += 1 })
|
|
||||||
|
|
||||||
recovered := pc.Recovered()
|
|
||||||
|
|
||||||
log(debugError, "panic.Recovered():", recovered.Value.(string))
|
|
||||||
frames := runtime.CallersFrames(recovered.Callers)
|
|
||||||
for {
|
|
||||||
frame, more := frames.Next()
|
|
||||||
log(debugError, "\t", frame.Function)
|
|
||||||
|
|
||||||
if !more {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapStream(
|
|
||||||
in chan int,
|
|
||||||
out chan int,
|
|
||||||
f func(int) int,
|
|
||||||
) {
|
|
||||||
tasks := make(chan func())
|
|
||||||
taskResults := make(chan chan int)
|
|
||||||
|
|
||||||
// Worker goroutines
|
|
||||||
var workerWg sync.WaitGroup
|
|
||||||
for i := 0; i < 10; i++ {
|
|
||||||
workerWg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer workerWg.Done()
|
|
||||||
for task := range tasks {
|
|
||||||
task()
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ordered reader goroutines
|
|
||||||
var readerWg sync.WaitGroup
|
|
||||||
readerWg.Add(1)
|
|
||||||
go func() {
|
|
||||||
defer readerWg.Done()
|
|
||||||
for result := range taskResults {
|
|
||||||
item := <-result
|
|
||||||
out <- item
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// Feed the workers with tasks
|
|
||||||
for elem := range in {
|
|
||||||
resultCh := make(chan int, 1)
|
|
||||||
taskResults <- resultCh
|
|
||||||
tasks <- func() {
|
|
||||||
resultCh <- f(elem)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We've exhausted input.
|
|
||||||
// Wait for everything to finish
|
|
||||||
close(tasks)
|
|
||||||
workerWg.Wait()
|
|
||||||
close(taskResults)
|
|
||||||
readerWg.Wait()
|
|
||||||
}
|
|
||||||
|
|
||||||
func mapStream2(
|
|
||||||
in chan int,
|
|
||||||
out chan int,
|
|
||||||
f func(int) int,
|
|
||||||
) {
|
|
||||||
s := stream.New().WithMaxGoroutines(10)
|
|
||||||
for elem := range in {
|
|
||||||
elem := elem
|
|
||||||
s.Go(func() stream.Callback {
|
|
||||||
res := f(elem)
|
|
||||||
return func() { out <- res }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
s.Wait()
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/gui/toolkit"
|
import "go.wit.com/gui/toolkits"
|
||||||
|
|
||||||
func (n *Node) Checked() bool {
|
func (n *Node) Checked() bool {
|
||||||
return n.B
|
return n.B
|
||||||
|
|
53
common.go
53
common.go
|
@ -4,8 +4,9 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"errors"
|
||||||
newlog "go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// functions for handling text related GUI elements
|
// functions for handling text related GUI elements
|
||||||
|
@ -35,7 +36,7 @@ func (n *Node) Disable() *Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Add(str string) {
|
func (n *Node) Add(str string) {
|
||||||
newlog.Log(debugGui, "gui.Add() value =", str)
|
log.Log(GUI, "gui.Add() value =", str)
|
||||||
|
|
||||||
n.S = str
|
n.S = str
|
||||||
|
|
||||||
|
@ -44,7 +45,7 @@ func (n *Node) Add(str string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) AddText(str string) {
|
func (n *Node) AddText(str string) {
|
||||||
newlog.Log(debugChange, "AddText() value =", str)
|
log.Log(CHANGE, "AddText() value =", str)
|
||||||
|
|
||||||
n.Text = str
|
n.Text = str
|
||||||
n.S = str
|
n.S = str
|
||||||
|
@ -54,7 +55,7 @@ func (n *Node) AddText(str string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetText(text string) *Node {
|
func (n *Node) SetText(text string) *Node {
|
||||||
newlog.Log(debugChange, "SetText() value =", text)
|
log.Log(CHANGE, "SetText() value =", text)
|
||||||
|
|
||||||
n.Text = text
|
n.Text = text
|
||||||
n.S = text
|
n.S = text
|
||||||
|
@ -67,11 +68,11 @@ func (n *Node) SetText(text string) *Node {
|
||||||
func (n *Node) SetNext(w int, h int) {
|
func (n *Node) SetNext(w int, h int) {
|
||||||
n.NextW = w
|
n.NextW = w
|
||||||
n.NextH = h
|
n.NextH = h
|
||||||
newlog.Log(debugNow, "SetNext() w,h =", n.NextW, n.NextH)
|
log.Info("SetNext() w,h =", n.NextW, n.NextH)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) Set(val any) {
|
func (n *Node) Set(val any) {
|
||||||
newlog.Log(debugChange, "Set() value =", val)
|
log.Log(CHANGE, "Set() value =", val)
|
||||||
|
|
||||||
switch v := val.(type) {
|
switch v := val.(type) {
|
||||||
case bool:
|
case bool:
|
||||||
|
@ -82,7 +83,7 @@ func (n *Node) Set(val any) {
|
||||||
case int:
|
case int:
|
||||||
n.I = val.(int)
|
n.I = val.(int)
|
||||||
default:
|
default:
|
||||||
newlog.Log(debugError, "Set() unknown type =", v)
|
log.Error(errors.New("Set() unknown type"), "v =", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := newAction(n, toolkit.Set)
|
a := newAction(n, toolkit.Set)
|
||||||
|
@ -98,11 +99,17 @@ func (n *Node) AppendText(str string) {
|
||||||
sendAction(a)
|
sendAction(a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// THESE TWO FUNCTIONS ARE TERRIBLY NAMED AND NEED TO BE FIXED
|
||||||
|
// 5 seconds worth of ideas:
|
||||||
|
// Value() ?
|
||||||
|
// Progname() Reference() ?
|
||||||
|
|
||||||
|
// should get the value of the node
|
||||||
func (n *Node) GetText() string {
|
func (n *Node) GetText() string {
|
||||||
if (n.S != n.Text) {
|
if (n.S != n.Text) {
|
||||||
newlog.Warn("GetText() is screwed up. TODO: fix this dumb crap")
|
log.Warn("GetText() is screwed up. TODO: fix this dumb crap")
|
||||||
stuff := newlog.ListFlags()
|
stuff := log.ListFlags()
|
||||||
newlog.Warn("ListFlags() =", stuff)
|
log.Warn("ListFlags() =", stuff)
|
||||||
}
|
}
|
||||||
if (n.S != "") {
|
if (n.S != "") {
|
||||||
return n.S
|
return n.S
|
||||||
|
@ -110,13 +117,21 @@ func (n *Node) GetText() string {
|
||||||
return n.Text
|
return n.Text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// should get the value of the node
|
||||||
|
// myButton = myGroup.NewButton("hit ball", nil).SetName("HIT")
|
||||||
|
// myButton.GetName() should return "HIT"
|
||||||
|
// n = Find("HIT") should return myButton
|
||||||
|
func (n *Node) GetName() string {
|
||||||
|
return n.Name
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// string handling examples that might be helpful for normalizeInt()
|
// string handling examples that might be helpful for normalizeInt()
|
||||||
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString
|
||||||
|
|
||||||
for _, username := range []string{"userone", "user2", "user-three"} {
|
for _, username := range []string{"userone", "user2", "user-three"} {
|
||||||
if !isAlpha(username) {
|
if !isAlpha(username) {
|
||||||
newlog.Log(debugGui, "%q is not valid\n", username)
|
log.Log(GUI, "%q is not valid\n", username)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,11 +151,11 @@ func normalizeInt(s string) string {
|
||||||
// reg, err := regexp.Compile("[^a-zA-Z0-9]+")
|
// reg, err := regexp.Compile("[^a-zA-Z0-9]+")
|
||||||
reg, err := regexp.Compile("[^0-9]+")
|
reg, err := regexp.Compile("[^0-9]+")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
newlog.Log(debugGui, "normalizeInt() regexp.Compile() ERROR =", err)
|
log.Log(GUI, "normalizeInt() regexp.Compile() ERROR =", err)
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
clean := reg.ReplaceAllString(s, "")
|
clean := reg.ReplaceAllString(s, "")
|
||||||
newlog.Log(debugGui, "normalizeInt() s =", clean)
|
log.Log(GUI, "normalizeInt() s =", clean)
|
||||||
return clean
|
return clean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,9 +163,9 @@ func commonCallback(n *Node) {
|
||||||
// TODO: make all of this common code to all the widgets
|
// TODO: make all of this common code to all the widgets
|
||||||
// This might be common everywhere finally (2023/03/01)
|
// This might be common everywhere finally (2023/03/01)
|
||||||
if (n.Custom == nil) {
|
if (n.Custom == nil) {
|
||||||
newlog.Log(debugChange, "Not Running n.Custom(n) == nil")
|
log.Log(CHANGE, "Not Running n.Custom(n) == nil")
|
||||||
} else {
|
} else {
|
||||||
newlog.Log(debugChange, "Running n.Custom(n)")
|
log.Log(CHANGE, "Running n.Custom(n)")
|
||||||
n.Custom()
|
n.Custom()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +207,7 @@ func (n *Node) Expand() *Node {
|
||||||
// myFunnyWindow = myGui.NewWindow("Hello").Standard().SetText("Hola")
|
// myFunnyWindow = myGui.NewWindow("Hello").Standard().SetText("Hola")
|
||||||
|
|
||||||
func (n *Node) Window(title string) *Node {
|
func (n *Node) Window(title string) *Node {
|
||||||
newlog.Log(debugError, "Window()", n)
|
log.Warn("Window()", n)
|
||||||
return n.NewWindow(title)
|
return n.NewWindow(title)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,12 +215,12 @@ func (n *Node) Window(title string) *Node {
|
||||||
// should be the default way
|
// should be the default way
|
||||||
/*
|
/*
|
||||||
func (n *Node) Standard() *Node {
|
func (n *Node) Standard() *Node {
|
||||||
newlog.Log(debugInfo, "Standard() not implemented yet")
|
log.Warn("Standard() not implemented yet")
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) SetMargin() *Node {
|
func (n *Node) SetMargin() *Node {
|
||||||
newlog.Log(debugError, "DoMargin() not implemented yet")
|
log.Warn("DoMargin() not implemented yet")
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
# GITVERSION=$(shell git rev-parse FETCH_HEAD)
|
|
||||||
VERSION=$(shell git describe --tags $(git rev-list --tags --max-count=1) | sed 's/^v//')
|
|
||||||
|
|
||||||
BASENAME=go-wit-gui
|
|
||||||
|
|
||||||
all: help deb
|
|
||||||
|
|
||||||
help:
|
|
||||||
@echo
|
|
||||||
@echo "make deb # attempt to build the .deb package using dpkg"
|
|
||||||
@echo
|
|
||||||
|
|
||||||
deb: clean extract DEBIAN build
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -rf ../files
|
|
||||||
rm -f ../*.deb
|
|
||||||
rm -f ../*.tar.xz data.tar.xz
|
|
||||||
rm -rf DEBIAN
|
|
||||||
|
|
||||||
extract:
|
|
||||||
mkdir -p ../files/usr/lib/go-gui
|
|
||||||
cp ../toolkit/*.so ../files/usr/lib/go-gui/
|
|
||||||
cp ../README.md ../files/usr/lib/go-gui/
|
|
||||||
cp ../cmds/textbox/textbox ../files/usr/lib/go-gui/textbox-demo
|
|
||||||
|
|
||||||
# makes the DEBIAN/ directory
|
|
||||||
DEBIAN:
|
|
||||||
mkdir -p DEBIAN
|
|
||||||
|
|
||||||
# make the md5sum file
|
|
||||||
cd ../files/ && find -type f -exec md5sum '{}' \; |sort -k2 >../md5sums
|
|
||||||
mv ../md5sums DEBIAN/
|
|
||||||
|
|
||||||
# make the control there
|
|
||||||
mkdir -p DEBIAN
|
|
||||||
cp control DEBIAN/
|
|
||||||
echo Version: ${VERSION} >>DEBIAN/control
|
|
||||||
|
|
||||||
cp postinst DEBIAN
|
|
||||||
|
|
||||||
build:
|
|
||||||
mv DEBIAN ../files/
|
|
||||||
cd .. && dpkg-deb --build files ${BASENAME}_${VERSION}_amd64.deb
|
|
||||||
@echo
|
|
||||||
@echo '#######################'
|
|
||||||
cd .. && dpkg-deb --info ${BASENAME}_${VERSION}_amd64.deb
|
|
||||||
@echo '#######################'
|
|
||||||
@echo
|
|
|
@ -1 +0,0 @@
|
||||||
10
|
|
|
@ -1,9 +0,0 @@
|
||||||
Source: go-wit-gui
|
|
||||||
Build-Depends: golang
|
|
||||||
Package: go-wit-gui
|
|
||||||
Maintainer: Jeff Carr <jcarr@wit.com>
|
|
||||||
Architecture: amd64
|
|
||||||
Depends:
|
|
||||||
Recommends: libgtk-3-0
|
|
||||||
Description: a abstraction layer for Go visual elements (GTK, QT, etc)
|
|
||||||
Package gui implements a abstraction layer for Go visual elements.
|
|
|
@ -1,25 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<title>go.wit.com/gui</title>
|
|
||||||
<meta name="go-import" content="go.wit.com/gui git https://github.com/wit-go/gui">
|
|
||||||
<meta name="go-source" content="go.wit.com/gui https://github.com/wit-go/gui https://github.com/wit-go/gui/tree/master{/dir} https://github.com/wit-go/gui/blob/master{/dir}/{file}#L{line}">
|
|
||||||
<style>
|
|
||||||
* { font-family: sans-serif; }
|
|
||||||
body { margin-top: 0; }
|
|
||||||
.content { display: inline-block; }
|
|
||||||
code { display: block; font-family: monospace; font-size: 1em; background-color: #d5d5d5; padding: 1em; margin-bottom: 16px; }
|
|
||||||
ul { margin-top: 16px; margin-bottom: 16px; }
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="content">
|
|
||||||
<h2>go.wit.com/gui</h2>
|
|
||||||
<code>go get -v go.wit.com/gui</code>
|
|
||||||
<code>import "go.wit.com/gui"</code>
|
|
||||||
Home: <a href="https://godoc.org/go.wit.com/gui">https://godoc.org/go.wit.com/gui</a><br/>
|
|
||||||
Source: <a href="https://github.com/wit-go/gui">https://github.com/wit-go/gui</a><br/>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
|
@ -1 +0,0 @@
|
||||||
#!/bin/sh
|
|
133
debug.go
133
debug.go
|
@ -1,101 +1,24 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
// Lots of debugging things:
|
// old debugging things. probably deprecate
|
||||||
|
// everything should be moved to "go.wit.com/gui/debugger"
|
||||||
// A function dump out the binary tree
|
// A function dump out the binary tree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"strconv"
|
"strconv"
|
||||||
"go.wit.com/gui/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
// various debugging flags
|
"go.wit.com/log"
|
||||||
var debugNow bool = true // useful for active development
|
"go.wit.com/gui/toolkits"
|
||||||
var debugGui bool = false
|
)
|
||||||
var debugError bool = true
|
|
||||||
var debugDump bool = false
|
|
||||||
var debugNode bool = false
|
|
||||||
var debugTabs bool = false
|
|
||||||
var debugFlags bool = false
|
|
||||||
var debugChange bool = false // shows user events like mouse and keyboard
|
|
||||||
var debugPlugin bool = false
|
|
||||||
var debugAction bool = false
|
|
||||||
|
|
||||||
// for printing out the binary tree
|
// for printing out the binary tree
|
||||||
var listChildrenParent *Node
|
var listChildrenParent *Node
|
||||||
var listChildrenDepth int = 0
|
var listChildrenDepth int = 0
|
||||||
var defaultPadding = " "
|
var defaultPadding = " "
|
||||||
|
|
||||||
func SetDebug (s bool) {
|
|
||||||
debugGui = s
|
|
||||||
debugTabs = s
|
|
||||||
|
|
||||||
logNow = s
|
|
||||||
logInfo = s
|
|
||||||
logWarn = s
|
|
||||||
logError = s
|
|
||||||
logVerbose = s
|
|
||||||
|
|
||||||
SetFlag("Node", s)
|
|
||||||
SetFlag("Tabs", s)
|
|
||||||
SetFlag("Dump", s)
|
|
||||||
SetFlag("Flags", s)
|
|
||||||
SetFlag("Plugin", s)
|
|
||||||
SetFlag("Change", s)
|
|
||||||
SetFlag("Error", s)
|
|
||||||
|
|
||||||
// This flag is only for the internal toolkit debugging
|
|
||||||
SetFlag("Toolkit", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetFlag (s string, b bool) {
|
|
||||||
switch s {
|
|
||||||
case "Toolkit":
|
|
||||||
// This flag is only for internal toolkit debugging
|
|
||||||
case "Tabs":
|
|
||||||
debugTabs = b
|
|
||||||
case "Node":
|
|
||||||
debugNode = b
|
|
||||||
case "Dump":
|
|
||||||
debugDump = b
|
|
||||||
case "Error":
|
|
||||||
debugError = b
|
|
||||||
case "Change":
|
|
||||||
debugChange = b
|
|
||||||
case "Flags":
|
|
||||||
debugFlags = b
|
|
||||||
case "Plugin":
|
|
||||||
debugPlugin = b
|
|
||||||
case "Show":
|
|
||||||
// ShowDebugValues() // print them here?
|
|
||||||
default:
|
|
||||||
log(debugGui, "Can't set unknown flag", s)
|
|
||||||
}
|
|
||||||
|
|
||||||
a := new(toolkit.Action)
|
|
||||||
a.ActionType = toolkit.Set
|
|
||||||
a.WidgetType = toolkit.Flag
|
|
||||||
a.S = s
|
|
||||||
a.B = b
|
|
||||||
sendAction(a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func ShowDebugValues() {
|
|
||||||
// The order here should match the order in the GUI
|
|
||||||
// TODO: get the order from the node binary tree
|
|
||||||
log(true, "Debug =", debugGui)
|
|
||||||
log(true, "DebugError =", debugError)
|
|
||||||
log(true, "DebugChange =", debugChange)
|
|
||||||
log(true, "DebugDump =", debugDump)
|
|
||||||
log(true, "DebugTabs =", debugTabs)
|
|
||||||
log(true, "DebugPlugin =", debugPlugin)
|
|
||||||
log(true, "DebugNode =", debugNode)
|
|
||||||
|
|
||||||
SetFlag("Show", true)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) Dump() {
|
func (n *Node) Dump() {
|
||||||
b := true
|
b := true
|
||||||
// log("Dump() dump =", b)
|
|
||||||
Indent(b, "NODE DUMP START")
|
Indent(b, "NODE DUMP START")
|
||||||
Indent(b, "id = ", n.id)
|
Indent(b, "id = ", n.id)
|
||||||
Indent(b, "Name = ", n.Name)
|
Indent(b, "Name = ", n.Name)
|
||||||
|
@ -129,7 +52,7 @@ func (n *Node) dumpWidget(b bool) string {
|
||||||
var info, d string
|
var info, d string
|
||||||
|
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
log(debugError, "dumpWidget() node == nil")
|
log.Error(errors.New("dumpWidget() node == nil"))
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
info = n.WidgetType.String()
|
info = n.WidgetType.String()
|
||||||
|
@ -144,6 +67,10 @@ func (n *Node) dumpWidget(b bool) string {
|
||||||
return tabs + d
|
return tabs + d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (n *Node) Children() []*Node {
|
||||||
|
return n.children
|
||||||
|
}
|
||||||
|
|
||||||
// func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
|
// func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
|
||||||
func (n *Node) ListChildren(dump bool) {
|
func (n *Node) ListChildren(dump bool) {
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
|
@ -155,32 +82,32 @@ func (n *Node) ListChildren(dump bool) {
|
||||||
if (n.parent == nil) {
|
if (n.parent == nil) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log(debugNode, "\t\t\tparent =",n.parent.id)
|
log.Log(NODE, "\t\t\tparent =",n.parent.id)
|
||||||
if (listChildrenParent != nil) {
|
if (listChildrenParent != nil) {
|
||||||
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
|
log.Log(NODE, "\t\t\tlistChildrenParent =",listChildrenParent.id)
|
||||||
if (listChildrenParent.id != n.parent.id) {
|
if (listChildrenParent.id != n.parent.id) {
|
||||||
log(true, "parent =",n.parent.id, n.parent.Name)
|
log.Log(true, "parent =",n.parent.id, n.parent.Name)
|
||||||
log(true, "listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
|
log.Log(true, "listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
|
||||||
log(true, listChildrenParent.id, "!=", n.parent.id)
|
log.Log(true, listChildrenParent.id, "!=", n.parent.id)
|
||||||
exit("parent.child does not match child.parent")
|
log.Exit("parent.child does not match child.parent")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log(debugNode, "\t\t", n.id, "has no children")
|
log.Log(NODE, "\t\t", n.id, "has no children")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, child := range n.children {
|
for _, child := range n.children {
|
||||||
if (child.parent != nil) {
|
if (child.parent != nil) {
|
||||||
log(debugNode, "\t\t\tparent =",child.parent.id)
|
log.Log(NODE, "\t\t\tparent =",child.parent.id)
|
||||||
} else {
|
} else {
|
||||||
log(debugGui, "\t\t\tno parent")
|
log.Log(GUI, "\t\t\tno parent")
|
||||||
// memory corruption? non-threadsafe access?
|
// memory corruption? non-threadsafe access?
|
||||||
// can all binary tree changes to Node.parent & Node.child be forced into a singular goroutine?
|
// can all binary tree changes to Node.parent & Node.child be forced into a singular goroutine?
|
||||||
panic("something is wrong with the wit golang gui logic and the binary tree is broken. child has no parent")
|
panic("something is wrong with the wit golang gui logic and the binary tree is broken. child has no parent")
|
||||||
}
|
}
|
||||||
if (child.children == nil) {
|
if (child.children == nil) {
|
||||||
log(debugNode, "\t\t", child.id, "has no children")
|
log.Log(NODE, "\t\t", child.id, "has no children")
|
||||||
} else {
|
} else {
|
||||||
log(debugNode, "\t\t\tHas children:", child.children)
|
log.Log(NODE, "\t\t\tHas children:", child.children)
|
||||||
}
|
}
|
||||||
listChildrenParent = n
|
listChildrenParent = n
|
||||||
listChildrenDepth += 1
|
listChildrenDepth += 1
|
||||||
|
@ -190,3 +117,19 @@ func (n *Node) ListChildren(dump bool) {
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// b bool, print if true
|
||||||
|
func logindent(b bool, depth int, format string, a ...any) {
|
||||||
|
var tabs string
|
||||||
|
for i := 0; i < depth; i++ {
|
||||||
|
tabs = tabs + format
|
||||||
|
}
|
||||||
|
|
||||||
|
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
||||||
|
newFormat := tabs + format
|
||||||
|
|
||||||
|
// array prepend(). Why isn't this a standard function. It should be:
|
||||||
|
// a.prepend(debugGui, newFormat)
|
||||||
|
a = append([]any{b, newFormat}, a...)
|
||||||
|
log.Log(b, a...)
|
||||||
|
}
|
||||||
|
|
118
debugFlags.go
118
debugFlags.go
|
@ -1,118 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
newlog "go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
type LogSettings struct {
|
|
||||||
ready bool
|
|
||||||
hidden bool
|
|
||||||
err error
|
|
||||||
name string
|
|
||||||
|
|
||||||
parent *Node // should be the root of the 'gui' package binary tree
|
|
||||||
window *Node // our window for displaying the log package settings
|
|
||||||
group *Node //
|
|
||||||
grid *Node //
|
|
||||||
checkbox *Node
|
|
||||||
label *Node
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ls *LogSettings) Set(b bool) {
|
|
||||||
newlog.Set(ls.name, b)
|
|
||||||
ls.checkbox.Set(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Node) NewLogFlag(name string) *LogSettings {
|
|
||||||
ls := new(LogSettings)
|
|
||||||
ls.parent = p
|
|
||||||
ls.ready = false
|
|
||||||
ls.name = name
|
|
||||||
|
|
||||||
ls.checkbox = p.NewCheckbox(name)
|
|
||||||
ls.label = p.NewLabel("Enable log." + name)
|
|
||||||
ls.checkbox.Set(newlog.Get(name))
|
|
||||||
ls.checkbox.Custom = func() {
|
|
||||||
newlog.Set(name, ls.checkbox.B)
|
|
||||||
}
|
|
||||||
return ls
|
|
||||||
}
|
|
||||||
|
|
||||||
// Let's you toggle on and off the various types of debugging output
|
|
||||||
// These checkboxes should be in the same order as the are printed
|
|
||||||
func (n *Node) DebugFlags() {
|
|
||||||
var w, g *Node
|
|
||||||
|
|
||||||
logGadgets := make(map[string]*LogSettings)
|
|
||||||
|
|
||||||
// Either:
|
|
||||||
// make a new window
|
|
||||||
// make a new tab in the existing window
|
|
||||||
if (n.UseTabs()) {
|
|
||||||
w = me.rootNode.NewWindow("Debug Flags")
|
|
||||||
w.Custom = w.StandardClose
|
|
||||||
w = w.NewBox("hBox", true)
|
|
||||||
} else {
|
|
||||||
w = n.NewTab("Flags")
|
|
||||||
}
|
|
||||||
|
|
||||||
g = w.NewGroup("Show").Pad()
|
|
||||||
|
|
||||||
g.NewButton("log.SetTmp()", func () {
|
|
||||||
newlog.SetTmp()
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("log.All(true)", func () {
|
|
||||||
for _, lf := range logGadgets {
|
|
||||||
lf.Set(true)
|
|
||||||
}
|
|
||||||
newlog.All(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("log.All(false)", func () {
|
|
||||||
for _, lf := range logGadgets {
|
|
||||||
lf.Set(false)
|
|
||||||
}
|
|
||||||
newlog.All(false)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("Dump Flags", func () {
|
|
||||||
// ShowDebugValues()
|
|
||||||
newlog.ListFlags()
|
|
||||||
})
|
|
||||||
|
|
||||||
/*
|
|
||||||
g.NewButton("All On", func () {
|
|
||||||
SetDebug(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("All Off", func () {
|
|
||||||
SetDebug(false)
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
|
|
||||||
g = w.NewGroup("List")
|
|
||||||
g = g.NewGrid("flags grid", 2, 2)
|
|
||||||
|
|
||||||
logGadgets["INFO"] = g.NewLogFlag("INFO")
|
|
||||||
logGadgets["WARN"] = g.NewLogFlag("WARN")
|
|
||||||
logGadgets["SPEW"] = g.NewLogFlag("SPEW")
|
|
||||||
logGadgets["ERROR"] = g.NewLogFlag("ERROR")
|
|
||||||
|
|
||||||
// generally useful debugging
|
|
||||||
cb1 := g.NewCheckbox("debug Gui")
|
|
||||||
g.NewLabel("like verbose=1")
|
|
||||||
cb1.Custom = func() {
|
|
||||||
debugGui = cb1.B
|
|
||||||
log(debugGui, "Custom() n.widget =", cb1.Name, cb1.B)
|
|
||||||
}
|
|
||||||
|
|
||||||
// turns on debugging inside the plugin toolkit
|
|
||||||
cb7 := g.NewCheckbox("debug Toolkit")
|
|
||||||
g.NewLabel("the plugin internals)")
|
|
||||||
cb7.Custom = func() {
|
|
||||||
// SetDebugToolkit(cb7.B)
|
|
||||||
SetFlag("Toolkit", cb7.B)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,97 +0,0 @@
|
||||||
// https://www.digitalocean.com/community/tutorials/how-to-run-multiple-functions-concurrently-in-go
|
|
||||||
// who came up with the idea of making community tutorials. that was a good idea!
|
|
||||||
|
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var debugWG *sync.WaitGroup
|
|
||||||
var debugNumberChan chan int
|
|
||||||
|
|
||||||
func (n *Node) DebugGoChannels() {
|
|
||||||
var w, g *Node
|
|
||||||
|
|
||||||
w = n.NewWindow("Debug GO Channels")
|
|
||||||
w.Custom = w.StandardClose
|
|
||||||
|
|
||||||
g = w.NewGroup("Channel stuff")
|
|
||||||
|
|
||||||
// var debugWG sync.WaitGroup
|
|
||||||
g.NewButton("init()", func () {
|
|
||||||
if (debugNumberChan == nil) {
|
|
||||||
log(true, "making debugNumberChan channel")
|
|
||||||
debugNumberChan = make(chan int)
|
|
||||||
} else {
|
|
||||||
log(true, "debugNumberChan already made")
|
|
||||||
}
|
|
||||||
debugWG = new(sync.WaitGroup)
|
|
||||||
})
|
|
||||||
g.NewButton("go printInt(x) (read x values off the channel)", func () {
|
|
||||||
debugWG.Add(1)
|
|
||||||
go printInt(2, "routine1")
|
|
||||||
debugWG.Add(1)
|
|
||||||
go printInt(2, "routine2")
|
|
||||||
})
|
|
||||||
g.NewButton("sendNumber(2) (chan <- 2, 4)", func () {
|
|
||||||
debugWG.Add(1)
|
|
||||||
debugWG.Add(1)
|
|
||||||
go sendNumber(2)
|
|
||||||
go sendNumber(4)
|
|
||||||
})
|
|
||||||
g.NewButton("sendNumber(1) (chan <- 7)", func () {
|
|
||||||
debugWG.Add(1)
|
|
||||||
go sendNumber(7)
|
|
||||||
})
|
|
||||||
g.NewButton("send 4 numbers (chan <- int)", func () {
|
|
||||||
log(true, "generateNumbers(4)")
|
|
||||||
go generateNumbers(4)
|
|
||||||
})
|
|
||||||
g.NewButton("debugWG.Done()", func () {
|
|
||||||
log(true, "ran debugWG.Done()")
|
|
||||||
debugWG.Done()
|
|
||||||
})
|
|
||||||
g.NewButton("close chan", func () {
|
|
||||||
log(true, "close() on", debugNumberChan)
|
|
||||||
close(debugNumberChan)
|
|
||||||
})
|
|
||||||
g.NewButton("print", func () {
|
|
||||||
log(true, "waitgroup counter is ?")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func sendNumber(i int) {
|
|
||||||
log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)")
|
|
||||||
debugNumberChan <- i
|
|
||||||
debugWG.Wait()
|
|
||||||
log(true, "END debugNumberChan sendNumber() done", i)
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateNumbers(total int) {
|
|
||||||
fmt.Printf("START generateNumbers()\n")
|
|
||||||
for idx := 1; idx <= total; idx++ {
|
|
||||||
log(true, "ran debugNumberChan <= idx where idx =", idx)
|
|
||||||
fmt.Printf("S generateNumbers() sending %d to channel\n", idx)
|
|
||||||
debugNumberChan <- idx
|
|
||||||
// res, err := (<-r)()
|
|
||||||
fmt.Printf("E generateNumbers() sending %d to channel\n", idx)
|
|
||||||
}
|
|
||||||
debugWG.Wait()
|
|
||||||
fmt.Printf("END generateNumbers()\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
// i equals the number of times to read values from the channel
|
|
||||||
func printInt(i int, name string) {
|
|
||||||
tmp := 1
|
|
||||||
log(true, "START printInt", name, "read debugNumberChan()")
|
|
||||||
for num := range debugNumberChan {
|
|
||||||
log(true, "printInt()",name, "read", num, "from channel")
|
|
||||||
debugWG.Done()
|
|
||||||
if (tmp == i) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tmp += 1
|
|
||||||
}
|
|
||||||
fmt.Printf("END printInt()", name, "read debugNumberChan\n")
|
|
||||||
}
|
|
171
debugGolang.go
171
debugGolang.go
|
@ -1,171 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"bytes"
|
|
||||||
// "os"
|
|
||||||
"runtime"
|
|
||||||
"runtime/debug"
|
|
||||||
"runtime/pprof"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (n *Node) DebugGolangWindow() {
|
|
||||||
var w, g, og, outputTextbox *Node
|
|
||||||
|
|
||||||
w = n.NewWindow("GO")
|
|
||||||
w.Custom = w.StandardClose
|
|
||||||
|
|
||||||
g = w.NewGroup("Language Internals")
|
|
||||||
|
|
||||||
g.NewButton("ReadModuleInfo()", func () {
|
|
||||||
tmp, _ := debug.ReadBuildInfo()
|
|
||||||
outputTextbox.SetText(tmp.String())
|
|
||||||
})
|
|
||||||
g.NewButton("runtime.NumGoroutine()", func () {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
pprof.Lookup("goroutine").WriteTo(buf, 1)
|
|
||||||
outputTextbox.SetText(buf.String())
|
|
||||||
|
|
||||||
outputTextbox.AppendText(fmt.Sprintln("runtime.NumGoroutine() = ", runtime.NumGoroutine()))
|
|
||||||
})
|
|
||||||
g.NewButton("pprof.Lookup(heap)", func () {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
pprof.Lookup("heap").WriteTo(buf, 1)
|
|
||||||
outputTextbox.SetText(buf.String())
|
|
||||||
})
|
|
||||||
g.NewButton("debug.PrintStack(current)", func () {
|
|
||||||
outputTextbox.SetText(string(debug.Stack()))
|
|
||||||
})
|
|
||||||
g.NewButton("pprof.Lookup(goroutine)", func () {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
pprof.Lookup("goroutine").WriteTo(buf, 1)
|
|
||||||
outputTextbox.SetText(buf.String())
|
|
||||||
})
|
|
||||||
g.NewButton("pprof.Lookup(block)", func () {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
pprof.Lookup("block").WriteTo(buf, 1)
|
|
||||||
outputTextbox.SetText(buf.String())
|
|
||||||
})
|
|
||||||
g.NewButton("pprof.Lookup threadcreate", func () {
|
|
||||||
buf := new(bytes.Buffer)
|
|
||||||
pprof.Lookup("threadcreate").WriteTo(buf, 1)
|
|
||||||
outputTextbox.SetText(buf.String())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("runtime.ReadMemStats()", func () {
|
|
||||||
outputTextbox.SetText(runtimeReadMemStats())
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.FreeOSMemory()", func () {
|
|
||||||
var out string = "Before debug.FreeOSMemory():\n\n"
|
|
||||||
out += runtimeReadMemStats()
|
|
||||||
debug.FreeOSMemory()
|
|
||||||
out += "\n\nAfter debug.FreeOSMemory():\n\n"
|
|
||||||
out += runtimeReadMemStats()
|
|
||||||
outputTextbox.SetText(out)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.ReadGCStats()", func () {
|
|
||||||
var tmp debug.GCStats
|
|
||||||
var out string
|
|
||||||
debug.ReadGCStats(&tmp)
|
|
||||||
log(true, tmp)
|
|
||||||
out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection")
|
|
||||||
out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections")
|
|
||||||
out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
|
|
||||||
out += fmt.Sprintln("Pause:", tmp.Pause, "// []time.Duration pause history, most recent first")
|
|
||||||
out += fmt.Sprintln("PauseEnd:", tmp.Pause, "// []time.Time pause history, most recent first")
|
|
||||||
out += fmt.Sprintln("PauseQuantiles:", tmp.PauseQuantiles, "// []time.Duration")
|
|
||||||
outputTextbox.SetText(out)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.SetTraceback('all')", func () {
|
|
||||||
debug.SetTraceback("all")
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("panic()", func () {
|
|
||||||
panic("test")
|
|
||||||
})
|
|
||||||
|
|
||||||
g = w.NewGroup("TODO: finish these")
|
|
||||||
|
|
||||||
// g.NewLabel("TODO:")
|
|
||||||
|
|
||||||
g.NewButton("runtime.Stack(true)", func () {
|
|
||||||
// TODO: https://stackoverflow.com/questions/61127053/how-to-list-all-the-running-goroutines-in-a-go-program
|
|
||||||
// func Stack(buf []byte, all bool) int
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.SetMemoryLimit(int)", func () {
|
|
||||||
// TODO:
|
|
||||||
//debug.SetMemoryLimit(1024 * 1024 * 100)
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.SetMaxStack(int bytes)", func () {
|
|
||||||
// default is apparently 1GB
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.SetMaxThreads(int)", func () {
|
|
||||||
// default is apparently 10,000
|
|
||||||
})
|
|
||||||
|
|
||||||
g.NewButton("debug.SetTraceback('all')", func () {
|
|
||||||
debug.SetTraceback("all")
|
|
||||||
})
|
|
||||||
|
|
||||||
// deprecated (probably) by String() implementation within golang
|
|
||||||
g.NewButton("dumpModuleInfo() (deprecate)", func () {
|
|
||||||
outputTextbox.SetText(dumpModuleInfo())
|
|
||||||
})
|
|
||||||
|
|
||||||
og = w.NewGroup("output")
|
|
||||||
outputTextbox = og.NewTextbox("outputBox")
|
|
||||||
outputTextbox.Custom = func () {
|
|
||||||
log(true, "custom TextBox() for golang output a =", outputTextbox.S, outputTextbox.id)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func runtimeReadMemStats() string {
|
|
||||||
var s runtime.MemStats
|
|
||||||
var out string
|
|
||||||
runtime.ReadMemStats(&s)
|
|
||||||
out += fmt.Sprintln("alloc:", s.Alloc, "bytes")
|
|
||||||
out += fmt.Sprintln("total-alloc:", s.TotalAlloc, "bytes")
|
|
||||||
out += fmt.Sprintln("sys:", s.Sys, "bytes")
|
|
||||||
out += fmt.Sprintln("lookups:", s.Lookups)
|
|
||||||
out += fmt.Sprintln("mallocs:", s.Mallocs)
|
|
||||||
out += fmt.Sprintln("frees:", s.Frees)
|
|
||||||
out += fmt.Sprintln("heap-alloc:", s.HeapAlloc, "bytes")
|
|
||||||
out += fmt.Sprintln("heap-sys:", s.HeapSys, "bytes")
|
|
||||||
out += fmt.Sprintln("heap-idle:", s.HeapIdle,"bytes")
|
|
||||||
out += fmt.Sprintln("heap-in-use:", s.HeapInuse, "bytes")
|
|
||||||
out += fmt.Sprintln("heap-released:", s.HeapReleased, "bytes")
|
|
||||||
out += fmt.Sprintln("heap-objects:", s.HeapObjects)
|
|
||||||
out += fmt.Sprintln("stack-in-use:", s.StackInuse, "bytes")
|
|
||||||
out += fmt.Sprintln("stack-sys", s.StackSys, "bytes")
|
|
||||||
out += fmt.Sprintln("next-gc: when heap-alloc >=", s.NextGC, "bytes")
|
|
||||||
out += fmt.Sprintln("last-gc:", s.LastGC, "ns")
|
|
||||||
out += fmt.Sprintln("gc-pause:", s.PauseTotalNs, "ns")
|
|
||||||
out += fmt.Sprintln("num-gc:", s.NumGC)
|
|
||||||
out += fmt.Sprintln("enable-gc:", s.EnableGC)
|
|
||||||
out += fmt.Sprintln("debug-gc:", s.DebugGC)
|
|
||||||
return out
|
|
||||||
}
|
|
||||||
|
|
||||||
func dumpModuleInfo() string {
|
|
||||||
var out string
|
|
||||||
tmp, _ := debug.ReadBuildInfo()
|
|
||||||
if tmp == nil {
|
|
||||||
out += fmt.Sprintln("This wasn't compiled with go module support")
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
out += fmt.Sprintln("mod.Path = ", tmp.Path)
|
|
||||||
out += fmt.Sprintln("mod.Main.Path = ", tmp.Main.Path)
|
|
||||||
out += fmt.Sprintln("mod.Main.Version = ", tmp.Main.Version)
|
|
||||||
out += fmt.Sprintln("mod.Main.Sum = ", tmp.Main.Sum)
|
|
||||||
for _, value := range tmp.Deps {
|
|
||||||
out += fmt.Sprintln("\tmod.Path = ", value.Path)
|
|
||||||
out += fmt.Sprintln("\tmod.Version = ", value.Version)
|
|
||||||
}
|
|
||||||
return out
|
|
||||||
}
|
|
302
debugWidget.go
302
debugWidget.go
|
@ -1,302 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
"strconv"
|
|
||||||
"go.wit.com/gui/gui/toolkit"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
// global var for checking to see if this
|
|
||||||
// window/tab for debugging a widget exists
|
|
||||||
// check the binary tree instead (?) for a window called "Widgets" (bad idea)
|
|
||||||
var bugWidget *Node
|
|
||||||
|
|
||||||
// the widget all these actions are run against
|
|
||||||
var activeWidget *Node
|
|
||||||
|
|
||||||
// for testing move, this is the node things are put on
|
|
||||||
var activeJunk *Node
|
|
||||||
|
|
||||||
// the label where the user can see which widget is active
|
|
||||||
var activeLabel *Node
|
|
||||||
var activeLabelType *Node
|
|
||||||
var activeLabelNewName *Node
|
|
||||||
var activeLabelNewType *Node
|
|
||||||
var activeLabelNewX *Node
|
|
||||||
var activeLabelNewY *Node
|
|
||||||
var activeLabelNewB *Node
|
|
||||||
|
|
||||||
// tmp junk
|
|
||||||
var debugGrid *Node
|
|
||||||
var debugGridLabel *Node
|
|
||||||
var debugWidgetBut1, debugWidgetBut2 *Node
|
|
||||||
|
|
||||||
func setActiveWidget(w *Node) {
|
|
||||||
if (w == nil) {
|
|
||||||
log(debugError, "setActiveWidget() was sent nil !!!")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
activeWidget = w
|
|
||||||
log(true, "The Widget is set to", w.id, w.Name)
|
|
||||||
if (activeLabel == nil) {
|
|
||||||
// the debug window doesn't exist yet so you can't display the change
|
|
||||||
// TODO: make a fake binary tree for this(?)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
title := "ID =" + strconv.Itoa(w.id) + " " + w.Name
|
|
||||||
activeLabel.SetText(title)
|
|
||||||
activeLabelType.SetText("widget.Type = " + w.WidgetType.String())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func DebugWidgetWindow(w *Node) {
|
|
||||||
if (bugWidget != nil) {
|
|
||||||
// this window was already created. Just change the widget we are working against
|
|
||||||
setActiveWidget(w)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Either:
|
|
||||||
// make a new window
|
|
||||||
// make a new tab in the existing window
|
|
||||||
if (me.rootNode.UseTabs()) {
|
|
||||||
bugWidget = me.rootNode.NewWindow("Widgets")
|
|
||||||
bugWidget.Custom = bugWidget.StandardClose
|
|
||||||
} else {
|
|
||||||
bugWidget = bugWin.NewTab("Widgets")
|
|
||||||
}
|
|
||||||
|
|
||||||
g := bugWidget.NewGroup("widget:")
|
|
||||||
|
|
||||||
g2 := g.NewGroup("widget:")
|
|
||||||
activeLabel = g2.NewLabel("undef")
|
|
||||||
g2 = g.NewGroup("type:")
|
|
||||||
activeLabelType = g2.NewLabel("undef")
|
|
||||||
g2 = g.NewGroup("New name:")
|
|
||||||
activeLabelNewName = g2.NewCombobox("newthing")
|
|
||||||
activeLabelNewName.AddText("penguin")
|
|
||||||
activeLabelNewName.AddText("snow")
|
|
||||||
activeLabelNewName.AddText("GO")
|
|
||||||
activeLabelNewName.AddText("debian")
|
|
||||||
activeLabelNewName.AddText("RiscV")
|
|
||||||
|
|
||||||
g2 = g.NewGroup("At X:")
|
|
||||||
activeLabelNewX = g2.NewSpinner("tmp spinner", -1, 100)
|
|
||||||
|
|
||||||
g2 = g.NewGroup("At Y:")
|
|
||||||
activeLabelNewY = g2.NewSpinner("tmp spinner", -1, 100)
|
|
||||||
|
|
||||||
g2 = g.NewGroup("bool B:")
|
|
||||||
activeLabelNewB = g2.NewCheckbox("tmp bool")
|
|
||||||
|
|
||||||
|
|
||||||
// common things that should work against each widget
|
|
||||||
g = bugWidget.NewGroup("common things")
|
|
||||||
g.NewButton("Enable()", func () {
|
|
||||||
activeWidget.Enable()
|
|
||||||
})
|
|
||||||
g.NewButton("Disable()", func () {
|
|
||||||
activeWidget.Disable()
|
|
||||||
})
|
|
||||||
g.NewButton("Show()", func () {
|
|
||||||
activeWidget.Show()
|
|
||||||
})
|
|
||||||
g.NewButton("Hide()", func () {
|
|
||||||
activeWidget.Hide()
|
|
||||||
})
|
|
||||||
g.NewButton("Dump()", func () {
|
|
||||||
activeWidget.Dump()
|
|
||||||
})
|
|
||||||
|
|
||||||
g = bugWidget.NewGroup("add things")
|
|
||||||
g.debugAddWidgetButton()
|
|
||||||
g.NewLabel("experiments:")
|
|
||||||
g.debugAddWidgetButtons()
|
|
||||||
|
|
||||||
g = bugWidget.NewGroup("change things")
|
|
||||||
g.NewButton("AddText()", func () {
|
|
||||||
activeWidget.S = activeLabelNewName.S
|
|
||||||
a := newAction(activeWidget, toolkit.AddText)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("SetText()", func () {
|
|
||||||
activeWidget.S = activeLabelNewName.S
|
|
||||||
a := newAction(activeWidget, toolkit.SetText)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Margin()", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Margin)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Unmargin()", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Unmargin)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Pad()", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Pad)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Unpad()", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Unpad)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Move(junk)", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Move)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
g.NewButton("Delete()", func () {
|
|
||||||
a := newAction(activeWidget, toolkit.Delete)
|
|
||||||
sendAction(a)
|
|
||||||
})
|
|
||||||
|
|
||||||
g = bugWidget.NewGroup("not working?")
|
|
||||||
activeJunk = bugWidget.NewGroup("junk:")
|
|
||||||
activeJunk.NewLabel("test junk")
|
|
||||||
|
|
||||||
if (activeWidget == nil) {
|
|
||||||
setActiveWidget(me.rootNode)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) debugAddWidgetButtons() {
|
|
||||||
n.NewButton("Dropdown", func () {
|
|
||||||
a := activeWidget.NewDropdown("tmp dropdown")
|
|
||||||
a.AddText("this is better than tcl/tk")
|
|
||||||
a.AddText("make something for tim for qflow")
|
|
||||||
a.AddText("and for riscv")
|
|
||||||
a.Custom = func () {
|
|
||||||
log(true, "custom dropdown() a =", a.Name, a.S, "id=", a.id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
n.NewButton("Combobox", func () {
|
|
||||||
a := activeWidget.NewCombobox("tmp combobox")
|
|
||||||
a.AddText("mirrors.wit.com")
|
|
||||||
a.AddText("go.wit.com")
|
|
||||||
a.Custom = func () {
|
|
||||||
log(true, "custom combobox() a =", a.Name, a.S, "id=", a.id)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
n.NewButton("Grid", func () {
|
|
||||||
// Grid numbering by (X,Y)
|
|
||||||
// -----------------------------
|
|
||||||
// -- (1,1) -- (2,1) -- (3,1) --
|
|
||||||
// -- (1,2) -- (2,1) -- (3,1) --
|
|
||||||
// -----------------------------
|
|
||||||
|
|
||||||
// SetDebug(true)
|
|
||||||
debugGrid = activeWidget.NewGrid("tmp grid", 2, 3)
|
|
||||||
debugGridLabel = debugGrid.NewLabel("mirrors.wit.com")
|
|
||||||
/*
|
|
||||||
debugGrid.SetNext(0,1)
|
|
||||||
debugGrid.NewLabel("foo (0,1)")
|
|
||||||
debugGrid.SetNext(1,1)
|
|
||||||
debugGrid.NewLabel("foo (1,1)")
|
|
||||||
debugGrid.SetNext(2,1)
|
|
||||||
debugGrid.NewLabel("foo (2,1)")
|
|
||||||
*/
|
|
||||||
// SetDebug(false)
|
|
||||||
DebugWidgetWindow(debugGrid)
|
|
||||||
})
|
|
||||||
n.NewButton("Image", func () {
|
|
||||||
activeWidget.NewImage("image")
|
|
||||||
})
|
|
||||||
n.NewButton("Box(horizontal)", func () {
|
|
||||||
a := activeWidget.NewBox("hBox", true)
|
|
||||||
a.NewLabel("hBox")
|
|
||||||
a.NewLabel("hBox 2")
|
|
||||||
})
|
|
||||||
n.NewButton("Box(vertical)", func () {
|
|
||||||
a := activeWidget.NewBox("vBox", false)
|
|
||||||
a.NewLabel("vBox")
|
|
||||||
a.NewLabel("vBox 2")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) debugAddWidgetButton() {
|
|
||||||
activeLabelNewType = n.NewDropdown("tmp dropdown")
|
|
||||||
activeLabelNewType.AddText("Window")
|
|
||||||
activeLabelNewType.AddText("Tab")
|
|
||||||
activeLabelNewType.AddText("Frame")
|
|
||||||
activeLabelNewType.AddText("Grid")
|
|
||||||
activeLabelNewType.AddText("Group")
|
|
||||||
activeLabelNewType.AddText("Box")
|
|
||||||
activeLabelNewType.AddText("Button")
|
|
||||||
activeLabelNewType.AddText("Checkbox")
|
|
||||||
activeLabelNewType.AddText("Dropdown")
|
|
||||||
activeLabelNewType.AddText("Combobox")
|
|
||||||
activeLabelNewType.AddText("Label")
|
|
||||||
activeLabelNewType.AddText("Textbox")
|
|
||||||
activeLabelNewType.AddText("Slider")
|
|
||||||
activeLabelNewType.AddText("Spinner")
|
|
||||||
activeLabelNewType.AddText("Image")
|
|
||||||
activeLabelNewType.AddText("Area")
|
|
||||||
activeLabelNewType.AddText("Form")
|
|
||||||
activeLabelNewType.AddText("Font")
|
|
||||||
activeLabelNewType.AddText("Color")
|
|
||||||
activeLabelNewType.AddText("Dialog")
|
|
||||||
|
|
||||||
n.NewButton("Add", func () {
|
|
||||||
name := activeLabelNewName.S
|
|
||||||
newX := activeLabelNewX.I
|
|
||||||
newY := activeLabelNewY.I
|
|
||||||
newB := activeLabelNewB.B
|
|
||||||
|
|
||||||
if (newY == -1) {
|
|
||||||
name = name + " (" + strconv.Itoa(activeWidget.NextW) + "," + strconv.Itoa(activeWidget.NextH) + ")"
|
|
||||||
} else {
|
|
||||||
activeWidget.SetNext(newX, newY)
|
|
||||||
name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")"
|
|
||||||
}
|
|
||||||
log(true, "New Name =", name)
|
|
||||||
log(true, "New Type =", activeLabelNewType.S)
|
|
||||||
log(true, "New X =", newX)
|
|
||||||
log(true, "New Y =", newY)
|
|
||||||
log(true, "activeWidget.NextW =", activeWidget.NextW)
|
|
||||||
log(true, "activeWidget.NextH =", activeWidget.NextH)
|
|
||||||
log(debugNow, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH)
|
|
||||||
activeWidget.Dump()
|
|
||||||
|
|
||||||
// activeWidget.X = newX
|
|
||||||
// activeWidget.Y = newY
|
|
||||||
|
|
||||||
switch activeLabelNewType.S {
|
|
||||||
case "Grid":
|
|
||||||
activeWidget.NewGrid(name, newX, newY)
|
|
||||||
case "Group":
|
|
||||||
activeWidget.NewGroup(name)
|
|
||||||
case "Box":
|
|
||||||
activeWidget.NewBox(name, newB)
|
|
||||||
case "Button":
|
|
||||||
var n *Node
|
|
||||||
n = activeWidget.NewButton(name, func () {
|
|
||||||
log(true, "got to button", name, n.id)
|
|
||||||
})
|
|
||||||
case "Checkbox":
|
|
||||||
a := activeWidget.NewCheckbox(name)
|
|
||||||
a.Custom = func () {
|
|
||||||
log(true, "custom checkox func a=", a.B, "id=", a.id)
|
|
||||||
}
|
|
||||||
case "Dropdown":
|
|
||||||
a := activeWidget.NewDropdown(name)
|
|
||||||
a.AddText(name + " yay")
|
|
||||||
a.AddText(name + " haha")
|
|
||||||
a.Custom = func () {
|
|
||||||
log(true, "WTF a=", a.B, "id=", a.id)
|
|
||||||
}
|
|
||||||
case "Combobox":
|
|
||||||
a := activeWidget.NewCombobox(name)
|
|
||||||
a.AddText(name + " foo")
|
|
||||||
a.AddText(name + " bar")
|
|
||||||
case "Label":
|
|
||||||
activeWidget.NewLabel(name)
|
|
||||||
case "Textbox":
|
|
||||||
activeWidget.NewTextbox(name)
|
|
||||||
case "Slider":
|
|
||||||
activeWidget.NewSlider(name, newX, newY)
|
|
||||||
case "Spinner":
|
|
||||||
activeWidget.NewSpinner(name, newX, newY)
|
|
||||||
default:
|
|
||||||
log(debugError, "make what type?")
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
185
debugWindow.go
185
debugWindow.go
|
@ -1,185 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
newlog "go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// TODO: move all this shit into somewhere not global
|
|
||||||
|
|
||||||
// main debugging window
|
|
||||||
var bugWin *Node
|
|
||||||
|
|
||||||
var mapWindows map[string]*Node
|
|
||||||
var checkd, checkdn, checkdt, checkdtk, lb1, lb2 *Node
|
|
||||||
var myButton *Node
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates a window helpful for debugging this package
|
|
||||||
*/
|
|
||||||
func (n *Node) DebugWindow() {
|
|
||||||
newlog.Warn("Don't use DebugWindow() directly anymore")
|
|
||||||
DebugWindow() // todo, remove the non-binary tree access
|
|
||||||
}
|
|
||||||
|
|
||||||
func DebugWindow() {
|
|
||||||
bugWin = me.rootNode.NewWindow("go.wit.com/gui debug window").DebugTab("Debug Tab")
|
|
||||||
bugWin.Custom = bugWin.StandardClose
|
|
||||||
if ArgDebug() {
|
|
||||||
newlog.SetTmp()
|
|
||||||
bugWin.DebugFlags()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// should the debugging windows be new windows or tabs
|
|
||||||
// var makeTabs bool = true
|
|
||||||
func (n *Node) UseTabs() bool {
|
|
||||||
return me.makeTabs
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) SetTabs(b bool) {
|
|
||||||
me.makeTabs = b
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *Node) DebugTab(title string) *Node {
|
|
||||||
var newN, gog, g1 *Node
|
|
||||||
// var logSettings *gadgets.LogSettings
|
|
||||||
|
|
||||||
// time.Sleep(1 * time.Second)
|
|
||||||
newN = n.NewTab(title)
|
|
||||||
|
|
||||||
//////////////////////// main debug things //////////////////////////////////
|
|
||||||
gog = newN.NewGroup("Debugging Windows:")
|
|
||||||
|
|
||||||
// generally useful debugging
|
|
||||||
cb := gog.NewCheckbox("Seperate windows")
|
|
||||||
cb.Custom = func() {
|
|
||||||
log(debugGui, "Custom() n.widget =", cb.Name, cb.B)
|
|
||||||
n.SetTabs(cb.B)
|
|
||||||
}
|
|
||||||
cb.Set(false)
|
|
||||||
n.SetTabs(false)
|
|
||||||
|
|
||||||
gog.NewButton("logging", func () {
|
|
||||||
bugWin.DebugFlags()
|
|
||||||
})
|
|
||||||
gog.NewButton("Debug Widgets", func () {
|
|
||||||
DebugWidgetWindow(newN)
|
|
||||||
})
|
|
||||||
gog.NewButton("GO Language Internals", func () {
|
|
||||||
bugWin.DebugGolangWindow()
|
|
||||||
})
|
|
||||||
gog.NewButton("GO Channels debug", func () {
|
|
||||||
bugWin.DebugGoChannels()
|
|
||||||
})
|
|
||||||
|
|
||||||
gog.NewLabel("Force Quit:")
|
|
||||||
|
|
||||||
gog.NewButton("os.Exit()", func () {
|
|
||||||
exit()
|
|
||||||
})
|
|
||||||
|
|
||||||
//////////////////////// window debugging things //////////////////////////////////
|
|
||||||
g1 = newN.NewGroup("list things")
|
|
||||||
|
|
||||||
g1.NewButton("List toolkits", func () {
|
|
||||||
dropdownWindow(g1)
|
|
||||||
me.rootNode.ListToolkits()
|
|
||||||
})
|
|
||||||
g1.NewButton("List Windows", func () {
|
|
||||||
dropdownWindow(g1)
|
|
||||||
})
|
|
||||||
g1.NewButton("List Window Widgets", func () {
|
|
||||||
dropdownWindowWidgets(g1)
|
|
||||||
})
|
|
||||||
|
|
||||||
g2 := newN.NewGroup("more things")
|
|
||||||
|
|
||||||
g2.NewButton("Node.ListChildren(true)", func () {
|
|
||||||
if (activeWidget == nil) {
|
|
||||||
activeWidget = me.rootNode
|
|
||||||
}
|
|
||||||
activeWidget.ListChildren(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
g2.NewButton("test conc", func () {
|
|
||||||
makeConc()
|
|
||||||
})
|
|
||||||
|
|
||||||
g2.NewButton("List Plugins", func () {
|
|
||||||
for _, aplug := range allPlugins {
|
|
||||||
log(true, "Loaded plugin:", aplug.name, aplug.filename)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
g2.NewButton("load toolkit 'gocui'", func () {
|
|
||||||
me.rootNode.LoadToolkit("gocui")
|
|
||||||
})
|
|
||||||
|
|
||||||
g2.NewButton("load toolkit 'andlabs'", func () {
|
|
||||||
me.rootNode.LoadToolkit("andlabs")
|
|
||||||
})
|
|
||||||
|
|
||||||
return newN
|
|
||||||
}
|
|
||||||
|
|
||||||
func dropdownWindow(p *Node) {
|
|
||||||
var mapWindows map[string]*Node
|
|
||||||
mapWindows = make(map[string]*Node)
|
|
||||||
|
|
||||||
dd := p.NewDropdown("Window Dropdown")
|
|
||||||
dd.Custom = func() {
|
|
||||||
name := dd.S
|
|
||||||
activeWidget = mapWindows[name]
|
|
||||||
setActiveWidget(activeWidget)
|
|
||||||
log(true, "The Window was set to", name)
|
|
||||||
}
|
|
||||||
log(debugGui, "dd =", dd)
|
|
||||||
if (activeWidget == nil) {
|
|
||||||
// the debug window doesn't exist yet so you can't display the change
|
|
||||||
// TODO: make a fake binary tree for this(?)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// var last = ""
|
|
||||||
for _, child := range me.rootNode.children {
|
|
||||||
log(logInfo, "\t\t", child.id, child.Name)
|
|
||||||
dd.AddDropdownName(child.Name)
|
|
||||||
// last = child.Name
|
|
||||||
mapWindows[child.Name] = child
|
|
||||||
if (activeWidget == nil) {
|
|
||||||
activeWidget = child
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// dd.SetDropdownName(last)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dropdownWindowWidgets(p *Node) {
|
|
||||||
var mapWindows map[string]*Node
|
|
||||||
mapWindows = make(map[string]*Node)
|
|
||||||
|
|
||||||
dd := p.NewDropdown("Window Widgets Dropdown")
|
|
||||||
dd.Custom = func() {
|
|
||||||
name := dd.S
|
|
||||||
activeWidget = mapWindows[name]
|
|
||||||
setActiveWidget(activeWidget)
|
|
||||||
}
|
|
||||||
log(debugGui, "dd =", dd)
|
|
||||||
|
|
||||||
// log("dumpWidget() ", b, listChildrenDepth, defaultPadding, n.id, info)
|
|
||||||
|
|
||||||
var addDropdowns func (*Node)
|
|
||||||
addDropdowns = func (n *Node) {
|
|
||||||
s := n.dumpWidget(true)
|
|
||||||
dd.AddDropdownName(s)
|
|
||||||
mapWindows[s] = n
|
|
||||||
|
|
||||||
for _, child := range n.children {
|
|
||||||
listChildrenDepth += 1
|
|
||||||
addDropdowns(child)
|
|
||||||
listChildrenDepth -= 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// list everything in the binary tree
|
|
||||||
addDropdowns(me.rootNode)
|
|
||||||
}
|
|
|
@ -6,7 +6,7 @@ package gui
|
||||||
// since it is the same. confusing names? maybe...
|
// since it is the same. confusing names? maybe...
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// add a new entry to the dropdown name
|
// add a new entry to the dropdown name
|
||||||
|
|
10
go.mod
10
go.mod
|
@ -1,16 +1,14 @@
|
||||||
module go.wit.com/gui
|
module go.wit.com/gui/gui
|
||||||
|
|
||||||
go 1.21.4
|
go 1.21.4
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexflint/go-arg v1.4.3
|
github.com/alexflint/go-arg v1.4.3
|
||||||
github.com/sourcegraph/conc v0.3.0
|
go.wit.com/gui/toolkits v0.4.1
|
||||||
go.wit.com/log v0.0.0-20240101060000-bf41970f7793
|
go.wit.com/log v0.3.1
|
||||||
)
|
)
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/alexflint/go-scalar v1.1.0 // indirect
|
github.com/alexflint/go-scalar v1.1.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
go.wit.com/spew v0.0.0-20240101141411-c7b8e91573c9 // indirect
|
||||||
go.uber.org/atomic v1.7.0 // indirect
|
|
||||||
go.uber.org/multierr v1.9.0 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
21
go.sum
21
go.sum
|
@ -7,21 +7,16 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
|
||||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
|
go.wit.com/gui/toolkits v0.4.1 h1:Kw9gTAajHwQShuK8MOj8UizGPeY5hOtDfvAxYpDXjUw=
|
||||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
go.wit.com/gui/toolkits v0.4.1/go.mod h1:f2QuC3z15/JxNnwujyFkgvkYjBS1fy0ni+QQ9idZnWQ=
|
||||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
go.wit.com/log v0.3.1 h1:UXtgJ4dwyWL0Yv4mw6gQnlmrIQU/zz6nClCB7NGKBQs=
|
||||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
go.wit.com/log v0.3.1/go.mod h1:GmsggfsKrqdZdAj26fEOlcTz6qEIazbV33uyuuktvB8=
|
||||||
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
|
go.wit.com/spew v0.0.0-20240101141411-c7b8e91573c9 h1:UEX2EzLQPzLTfy/kUFQD7OXtvKn8wk/+jpDOkbl4ff4=
|
||||||
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
|
go.wit.com/spew v0.0.0-20240101141411-c7b8e91573c9/go.mod h1:qBpgJXThMMT15vym7/E4Ur9y8oOo2nP7t2RP52QHUNw=
|
||||||
go.wit.com/log v0.0.0-20240101060000-bf41970f7793 h1:kLs+rU96k6b48DqpkO4n3yDZ8hjiVnYjzPSEHU+93aY=
|
|
||||||
go.wit.com/log v0.0.0-20240101060000-bf41970f7793/go.mod h1:uXgfF8oPx5KYhtNZel6gsFYPMr9+z6sav5lSws1mN6A=
|
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
||||||
|
|
5
grid.go
5
grid.go
|
@ -1,7 +1,8 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Grid numbering examples (H) or (W,H)
|
// Grid numbering examples (H) or (W,H)
|
||||||
|
@ -73,7 +74,7 @@ func (n *Node) At(w int, h int) *Node {
|
||||||
|
|
||||||
n.gridIncrement()
|
n.gridIncrement()
|
||||||
if (n.NextW != w) || (n.NextH != h) {
|
if (n.NextW != w) || (n.NextH != h) {
|
||||||
log(logError, "At() (W,H)", w, h, " was moved to avoid a collision (W,H) =", n.NextW, n.NextH)
|
log.Warn("At() (W,H)", w, h, " was moved to avoid a collision (W,H) =", n.NextW, n.NextH)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
2
group.go
2
group.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make a "Group" a "Grid" ?
|
// TODO: make a "Group" a "Grid" ?
|
||||||
|
|
2
image.go
2
image.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewImage(name string) *Node {
|
func (parent *Node) NewImage(name string) *Node {
|
||||||
|
|
2
label.go
2
label.go
|
@ -1,7 +1,7 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewLabel(text string) *Node {
|
func (parent *Node) NewLabel(text string) *Node {
|
||||||
|
|
43
log.go
43
log.go
|
@ -1,43 +0,0 @@
|
||||||
package gui
|
|
||||||
|
|
||||||
import (
|
|
||||||
witlog "go.wit.com/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
// various debugging flags
|
|
||||||
var logNow bool = true // useful for active development
|
|
||||||
var logError bool = true
|
|
||||||
var logWarn bool = false
|
|
||||||
var logInfo bool = false
|
|
||||||
var logVerbose bool = false
|
|
||||||
|
|
||||||
// var log interface{}
|
|
||||||
|
|
||||||
func log(b bool, a ...any) {
|
|
||||||
// witlog.Where = "wit/gui"
|
|
||||||
witlog.Log(b, a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sleep(a ...any) {
|
|
||||||
witlog.Sleep(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func exit(a ...any) {
|
|
||||||
witlog.Exit(a...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// b bool, print if true
|
|
||||||
func logindent(b bool, depth int, format string, a ...any) {
|
|
||||||
var tabs string
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
tabs = tabs + format
|
|
||||||
}
|
|
||||||
|
|
||||||
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
|
||||||
newFormat := tabs + format
|
|
||||||
|
|
||||||
// array prepend(). Why isn't this a standard function. It should be:
|
|
||||||
// a.prepend(debugGui, newFormat)
|
|
||||||
a = append([]any{b, newFormat}, a...)
|
|
||||||
witlog.Log(b, a...)
|
|
||||||
}
|
|
148
log/log.go
148
log/log.go
|
@ -1,148 +0,0 @@
|
||||||
package witlog
|
|
||||||
//
|
|
||||||
// version v1.2
|
|
||||||
//
|
|
||||||
// I like things to be easy.
|
|
||||||
//
|
|
||||||
// this means all the log settings are in one place. it should allow
|
|
||||||
// things to be over-ridden externally to the library
|
|
||||||
// but still allow command line --args to pass debugging settings
|
|
||||||
//
|
|
||||||
// I also have a generic sleep() and exit() in here because it's simple
|
|
||||||
//
|
|
||||||
// Usage:
|
|
||||||
//
|
|
||||||
// log("something", foo, bar)
|
|
||||||
// var DEBUG bool = true
|
|
||||||
// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
|
|
||||||
//
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
"runtime/pprof"
|
|
||||||
golog "log"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
"reflect"
|
|
||||||
// "net"
|
|
||||||
)
|
|
||||||
|
|
||||||
// various debugging flags
|
|
||||||
var LogNow bool = true // useful for active development
|
|
||||||
var LogError bool = true
|
|
||||||
var LogWarn bool = false
|
|
||||||
var LogInfo bool = false
|
|
||||||
var LogVerbose bool = false
|
|
||||||
var LogSleep bool = false
|
|
||||||
|
|
||||||
var LOGOFF bool = false // turn this off, all logging stops
|
|
||||||
var debugToolkit bool = false // does spew stuff?
|
|
||||||
|
|
||||||
var Where string = "gui/log"
|
|
||||||
|
|
||||||
var externalLog func(...any)
|
|
||||||
|
|
||||||
type Spewt struct {
|
|
||||||
a bool
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
sleep() # you know what this does? sleeps for 1 second. yep. dump. easy.
|
|
||||||
sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second
|
|
||||||
*/
|
|
||||||
func Sleep(a ...any) {
|
|
||||||
if (a == nil) {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
Log(LogSleep, "sleep", a[0])
|
|
||||||
|
|
||||||
switch a[0].(type) {
|
|
||||||
case int:
|
|
||||||
time.Sleep(time.Duration(a[0].(int)) * time.Second)
|
|
||||||
case float64:
|
|
||||||
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
|
|
||||||
default:
|
|
||||||
Log("sleep a[0], type = ", a[0], reflect.TypeOf(a[0]))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
exit() # yep. exits. I guess everything must be fine
|
|
||||||
exit(3) # I guess 3 it is then
|
|
||||||
exit("dont like apples") # ok. I'll make a note of that
|
|
||||||
*/
|
|
||||||
func Exit(a ...any) {
|
|
||||||
Log(LogError, "exit", a)
|
|
||||||
//if (a) {
|
|
||||||
// os.Exit(a)
|
|
||||||
//}
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever.
|
|
||||||
I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this
|
|
||||||
implementation is probably faster than all of those because you just set one bool to FALSE
|
|
||||||
and it all stops.
|
|
||||||
Sometimes I need to capture to stdout, sometimes stdout can't
|
|
||||||
work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread
|
|
||||||
over 8 million references in every .go file. I'm tapping out and putting
|
|
||||||
it in one place. here it is. Also, this makes having debug levels really fucking easy.
|
|
||||||
You can define whatever level of logging you want from anywhere (command line) etc.
|
|
||||||
|
|
||||||
log() # doesn't do anything
|
|
||||||
log(stuff) # sends it to whatever log you define in a single place. here is the place
|
|
||||||
*/
|
|
||||||
|
|
||||||
func Log(a ...any) {
|
|
||||||
if (LOGOFF) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (a == nil) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var tbool bool
|
|
||||||
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
|
|
||||||
if (a[0] == false) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
a[0] = Where
|
|
||||||
}
|
|
||||||
|
|
||||||
golog.Println(a...)
|
|
||||||
if (externalLog == nil) {
|
|
||||||
// golog.Println(a...)
|
|
||||||
} else {
|
|
||||||
externalLog(fmt.Sprint(a...))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func loggo() {
|
|
||||||
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
|
||||||
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
|
|
||||||
}
|
|
||||||
|
|
||||||
func logindent(depth int, format string, a ...interface{}) {
|
|
||||||
var tabs string
|
|
||||||
for i := 0; i < depth; i++ {
|
|
||||||
tabs = tabs + format
|
|
||||||
}
|
|
||||||
|
|
||||||
// newFormat := tabs + strconv.Itoa(depth) + " " + format
|
|
||||||
newFormat := tabs + format
|
|
||||||
Log(debugToolkit, newFormat, a)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetOutput(w io.Writer) {
|
|
||||||
golog.SetOutput(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetToolkitOutput(newLog func(...any)) {
|
|
||||||
externalLog = newLog
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
package witlog
|
|
||||||
|
|
||||||
import (
|
|
||||||
)
|
|
||||||
|
|
||||||
//
|
|
||||||
// Attempt to switch logging to syslog on linux
|
|
||||||
//
|
|
||||||
|
|
||||||
// This struct can be used with the go-arg package
|
|
||||||
type LogArgs struct {
|
|
||||||
Log []string `arg:"--log" help:"Where to log [syslog,stdout]"`
|
|
||||||
}
|
|
87
main.go
87
main.go
|
@ -2,8 +2,9 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
|
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
|
||||||
|
@ -15,7 +16,7 @@ const Xaxis = 0 // stack things horizontally
|
||||||
const Yaxis = 1 // stack things vertically
|
const Yaxis = 1 // stack things vertically
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
log(true, "init() has been run")
|
log.Log(true, "init() has been run")
|
||||||
|
|
||||||
me.counter = 0
|
me.counter = 0
|
||||||
me.prefix = "wit"
|
me.prefix = "wit"
|
||||||
|
@ -36,28 +37,29 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func watchCallback() {
|
func watchCallback() {
|
||||||
log(logInfo, "watchCallback() START")
|
log.Info("watchCallback() START")
|
||||||
for {
|
for {
|
||||||
log(logInfo, "watchCallback() restarted select for toolkit user events")
|
log.Info("watchCallback() restarted select for toolkit user events")
|
||||||
select {
|
select {
|
||||||
case a := <-me.guiChan:
|
case a := <-me.guiChan:
|
||||||
if (a.ActionType == toolkit.UserQuit) {
|
if (a.ActionType == toolkit.UserQuit) {
|
||||||
log(logInfo, "doUserEvent() User sent Quit()")
|
log.Info("doUserEvent() User sent Quit()")
|
||||||
me.rootNode.doCustom()
|
me.rootNode.doCustom()
|
||||||
exit("wit/gui toolkit.UserQuit")
|
log.Exit("wit/gui toolkit.UserQuit")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if (a.ActionType == toolkit.EnableDebug) {
|
if (a.ActionType == toolkit.EnableDebug) {
|
||||||
log(logInfo, "doUserEvent() Enable Debugging Window")
|
log.Warn("doUserEvent() Enable Debugging Window")
|
||||||
DebugWindow()
|
log.Warn("doUserEvent() TODO: not implemented")
|
||||||
|
// DebugWindow()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
n := me.rootNode.FindId(a.WidgetId)
|
n := me.rootNode.FindId(a.WidgetId)
|
||||||
if (n == nil) {
|
if (n == nil) {
|
||||||
log(logError, "watchCallback() UNKNOWN widget id =", a.WidgetId, a.Name)
|
log.Warn("watchCallback() UNKNOWN widget id =", a.WidgetId, a.Name)
|
||||||
} else {
|
} else {
|
||||||
log(logInfo, "watchCallback() FOUND widget id =", n.id, n.Name)
|
log.Info("watchCallback() FOUND widget id =", n.id, n.Name)
|
||||||
n.doUserEvent(a)
|
n.doUserEvent(a)
|
||||||
}
|
}
|
||||||
// this maybe a good idea?
|
// this maybe a good idea?
|
||||||
|
@ -68,49 +70,49 @@ func watchCallback() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) doCustom() {
|
func (n *Node) doCustom() {
|
||||||
log(logInfo, "doUserEvent() widget =", n.id, n.Name, n.WidgetType, n.B)
|
log.Info("doUserEvent() widget =", n.id, n.Name, n.WidgetType, n.B)
|
||||||
if (n.Custom == nil) {
|
if (n.Custom == nil) {
|
||||||
log(debugError, "Custom() = nil. SKIPPING")
|
log.Warn("Custom() = nil. SKIPPING")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go n.Custom()
|
go n.Custom()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) doUserEvent(a toolkit.Action) {
|
func (n *Node) doUserEvent(a toolkit.Action) {
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name)
|
log.Info("doUserEvent() node =", n.id, n.Name)
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case toolkit.Checkbox:
|
case toolkit.Checkbox:
|
||||||
n.B = a.B
|
n.B = a.B
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.B)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.B)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Button:
|
case toolkit.Button:
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "button clicked")
|
log.Info("doUserEvent() node =", n.id, n.Name, "button clicked")
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Combobox:
|
case toolkit.Combobox:
|
||||||
n.S = a.S
|
n.S = a.S
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Dropdown:
|
case toolkit.Dropdown:
|
||||||
n.S = a.S
|
n.S = a.S
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Textbox:
|
case toolkit.Textbox:
|
||||||
n.S = a.S
|
n.S = a.S
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.S)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Spinner:
|
case toolkit.Spinner:
|
||||||
n.I = a.I
|
n.I = a.I
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.I)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.I)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Slider:
|
case toolkit.Slider:
|
||||||
n.I = a.I
|
n.I = a.I
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "set to:", n.I)
|
log.Info("doUserEvent() node =", n.id, n.Name, "set to:", n.I)
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
case toolkit.Window:
|
case toolkit.Window:
|
||||||
log(logInfo, "doUserEvent() node =", n.id, n.Name, "window closed")
|
log.Info("doUserEvent() node =", n.id, n.Name, "window closed")
|
||||||
n.doCustom()
|
n.doCustom()
|
||||||
default:
|
default:
|
||||||
log(logInfo, "doUserEvent() type =", n.WidgetType)
|
log.Info("doUserEvent() type =", n.WidgetType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,18 +126,15 @@ func New() *Node {
|
||||||
|
|
||||||
// try to load andlabs, if that doesn't work, fall back to the console
|
// try to load andlabs, if that doesn't work, fall back to the console
|
||||||
func (n *Node) Default() *Node {
|
func (n *Node) Default() *Node {
|
||||||
// start the GUI debugger if --gui-debug is true
|
|
||||||
checkDebug()
|
|
||||||
|
|
||||||
if (argGui.GuiPlugin != "") {
|
if (argGui.GuiPlugin != "") {
|
||||||
log(logError, "New.Default() try toolkit =", argGui.GuiPlugin)
|
log.Warn("New.Default() try toolkit =", argGui.GuiPlugin)
|
||||||
return n.LoadToolkit(argGui.GuiPlugin)
|
return n.LoadToolkit(argGui.GuiPlugin)
|
||||||
}
|
}
|
||||||
// if DISPLAY isn't set, return since gtk can't load
|
// if DISPLAY isn't set, return since gtk can't load
|
||||||
// TODO: figure out how to check what to do in macos and mswindows
|
// TODO: figure out how to check what to do in macos and mswindows
|
||||||
if (os.Getenv("DISPLAY") == "") {
|
if (os.Getenv("DISPLAY") == "") {
|
||||||
if (n.LoadToolkit("gocui") == nil) {
|
if (n.LoadToolkit("gocui") == nil) {
|
||||||
log(logError, "New() failed to load gocui")
|
log.Warn("New() failed to load gocui")
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
@ -146,39 +145,19 @@ func (n *Node) Default() *Node {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkDebug() {
|
|
||||||
if ! ArgDebug() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
f := func() {
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
log(debugGui, "wit/gui START DEBUG")
|
|
||||||
DebugWindow()
|
|
||||||
log(debugGui, "wit/gui END DEBUG")
|
|
||||||
log(debugGui, "wit/gui END DEBUG")
|
|
||||||
log(debugGui, "wit/gui END DEBUG")
|
|
||||||
}
|
|
||||||
go f()
|
|
||||||
}
|
|
||||||
|
|
||||||
// The window is destroyed but the application does not quit
|
// The window is destroyed but the application does not quit
|
||||||
func (n *Node) StandardClose() {
|
func (n *Node) StandardClose() {
|
||||||
log(debugGui, "wit/gui Standard Window Close. name =", n.Name)
|
log.Log(GUI, "wit/gui Standard Window Close. name =", n.Name)
|
||||||
log(debugGui, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
|
log.Log(GUI, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The window is destroyed and the application exits
|
// The window is destroyed and the application exits
|
||||||
// TODO: properly exit the plugin since Quit() doesn't do it
|
// TODO: properly exit the plugin since Quit() doesn't do it
|
||||||
func StandardExit() {
|
func StandardExit() {
|
||||||
log(true, "wit/gui Standard Window Exit. running os.Exit()")
|
log.Log(true, "wit/gui Standard Window Exit. running os.Exit()")
|
||||||
log(true, "StandardExit() attempt to exit each toolkit plugin")
|
log.Log(true, "StandardExit() attempt to exit each toolkit plugin")
|
||||||
for i, plug := range allPlugins {
|
for i, plug := range allPlugins {
|
||||||
log(true, "NewButton()", i, plug)
|
log.Log(true, "NewButton()", i, plug)
|
||||||
}
|
}
|
||||||
exit(0)
|
log.Exit(0)
|
||||||
}
|
}
|
||||||
|
|
13
node.go
13
node.go
|
@ -1,6 +1,9 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import "go.wit.com/gui/gui/toolkit"
|
import (
|
||||||
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
generic function to create a new node on the binary tree
|
generic function to create a new node on the binary tree
|
||||||
|
@ -30,7 +33,7 @@ func addNode(title string) *Node {
|
||||||
n.Name = title
|
n.Name = title
|
||||||
n.Text = title
|
n.Text = title
|
||||||
n.id = me.counter
|
n.id = me.counter
|
||||||
log(debugNode, "addNode = widget setid =", n.id)
|
log.Log(NODE, "addNode = widget setid =", n.id)
|
||||||
|
|
||||||
me.counter += 1
|
me.counter += 1
|
||||||
return n
|
return n
|
||||||
|
@ -42,12 +45,12 @@ func (n *Node) Parent() *Node {
|
||||||
|
|
||||||
func (n *Node) Delete(d *Node) {
|
func (n *Node) Delete(d *Node) {
|
||||||
for i, child := range n.children {
|
for i, child := range n.children {
|
||||||
log(debugNode, "\t", i, child.id, child.Name)
|
log.Log(NODE, "\t", i, child.id, child.Name)
|
||||||
if (child.id == d.id) {
|
if (child.id == d.id) {
|
||||||
log(debugNode, "\t\t Deleting this")
|
log.Log(NODE, "\t\t Deleting this")
|
||||||
n.children = append(n.children[:i], n.children[i+1:]...)
|
n.children = append(n.children[:i], n.children[i+1:]...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log(debugError, "did not find node to delete", d.id, d.Name)
|
log.Warn("did not find node to delete", d.id, d.Name)
|
||||||
}
|
}
|
||||||
|
|
96
plugin.go
96
plugin.go
|
@ -10,7 +10,8 @@ import (
|
||||||
"embed"
|
"embed"
|
||||||
"plugin"
|
"plugin"
|
||||||
|
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
@ -50,12 +51,12 @@ var allPlugins []*aplug
|
||||||
// loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
// loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
||||||
// attempts to locate the .so file
|
// attempts to locate the .so file
|
||||||
func initPlugin(name string) *aplug {
|
func initPlugin(name string) *aplug {
|
||||||
log(logInfo, "initPlugin() START")
|
log.Log(PLUG, "initPlugin() START")
|
||||||
|
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log(debugGui, "initPlugin() already loaded toolkit plugin =", aplug.name)
|
log.Log(PLUG, "initPlugin() already loaded toolkit plugin =", aplug.name)
|
||||||
if (aplug.name == name) {
|
if (aplug.name == name) {
|
||||||
log(debugError, "initPlugin() SKIPPING", name, "as you can't load it twice")
|
log.Warn("initPlugin() SKIPPING", name, "as you can't load it twice")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,13 +72,13 @@ func getPluginChannel(p *aplug, funcName string) func() chan toolkit.Action {
|
||||||
|
|
||||||
test, err = p.plug.Lookup(funcName)
|
test, err = p.plug.Lookup(funcName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log(debugGui, "DID NOT FIND: name =", test, "err =", err)
|
log.Error(err, "DID NOT FIND: name =", test)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newfunc, ok = test.(func() chan toolkit.Action)
|
newfunc, ok = test.(func() chan toolkit.Action)
|
||||||
if !ok {
|
if !ok {
|
||||||
log(debugGui, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
|
log.Log(PLUG, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return newfunc
|
return newfunc
|
||||||
|
@ -90,13 +91,13 @@ func sendCallback(p *aplug, funcName string) func(chan toolkit.Action) {
|
||||||
|
|
||||||
test, err = p.plug.Lookup(funcName)
|
test, err = p.plug.Lookup(funcName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log(debugGui, "DID NOT FIND: name =", test, "err =", err)
|
log.Error(err, "DID NOT FIND: name =", test)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newfunc, ok = test.(func(chan toolkit.Action))
|
newfunc, ok = test.(func(chan toolkit.Action))
|
||||||
if !ok {
|
if !ok {
|
||||||
log(debugGui, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
|
log.Log(PLUG, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return newfunc
|
return newfunc
|
||||||
|
@ -120,7 +121,7 @@ func searchPaths(name string) *aplug {
|
||||||
pfile, err = me.resFS.ReadFile(filename)
|
pfile, err = me.resFS.ReadFile(filename)
|
||||||
if (err == nil) {
|
if (err == nil) {
|
||||||
filename = "/tmp/" + name + ".so"
|
filename = "/tmp/" + name + ".so"
|
||||||
log(logError, "write out file here", name, filename, len(pfile))
|
log.Error(err, "write out file here", name, filename, len(pfile))
|
||||||
f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
|
f, _ := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE, 0600)
|
||||||
f.Write(pfile)
|
f.Write(pfile)
|
||||||
f.Close()
|
f.Close()
|
||||||
|
@ -129,11 +130,11 @@ func searchPaths(name string) *aplug {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log(logError, filename, "was not embedded in the binary. Error:", err)
|
log.Error(err, filename, "was not embedded in the binary")
|
||||||
}
|
}
|
||||||
|
|
||||||
// attempt to write out the file from the internal resource
|
// attempt to write out the file from the internal resource
|
||||||
filename = "toolkit/" + name + ".so"
|
filename = "toolkits/" + name + ".so"
|
||||||
p := initToolkit(name, filename)
|
p := initToolkit(name, filename)
|
||||||
if (p != nil) {
|
if (p != nil) {
|
||||||
return p
|
return p
|
||||||
|
@ -141,33 +142,23 @@ func searchPaths(name string) *aplug {
|
||||||
|
|
||||||
homeDir, err := os.UserHomeDir()
|
homeDir, err := os.UserHomeDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log(logError, "searchPaths() error. exiting here?")
|
log.Error(err, "os.UserHomeDir() error. giving up")
|
||||||
} else {
|
return nil
|
||||||
filename = homeDir + "/go/src/go.wit.com/gui/toolkits/" + name + ".so"
|
|
||||||
p = initToolkit(name, filename)
|
|
||||||
if (p != nil) {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
homeDir, err = os.UserHomeDir()
|
filename = homeDir + "/go/src/go.wit.com/gui/toolkits/" + name + ".so"
|
||||||
if err != nil {
|
|
||||||
log(logError, "searchPaths() error. exiting here?")
|
|
||||||
} else {
|
|
||||||
filename = homeDir + "/go/src/go.wit.com/toolkits/" + name + ".so"
|
|
||||||
p = initToolkit(name, filename)
|
|
||||||
if (p != nil) {
|
|
||||||
return p
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filename = "/usr/lib/go-gui/" + name + ".so"
|
|
||||||
p = initToolkit(name, filename)
|
p = initToolkit(name, filename)
|
||||||
if (p != nil) {
|
if (p != nil) {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = "/usr/local/lib/" + name + ".so"
|
filename = "/usr/lib/go-gui/latest/" + name + ".so"
|
||||||
|
p = initToolkit(name, filename)
|
||||||
|
if (p != nil) {
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
filename = "/usr/local/lib/gui/toolkits/" + name + ".so"
|
||||||
p = initToolkit(name, filename)
|
p = initToolkit(name, filename)
|
||||||
if (p != nil) {
|
if (p != nil) {
|
||||||
return p
|
return p
|
||||||
|
@ -180,18 +171,18 @@ func searchPaths(name string) *aplug {
|
||||||
func initToolkit(name string, filename string) *aplug {
|
func initToolkit(name string, filename string) *aplug {
|
||||||
if _, err := os.Stat(filename); err != nil {
|
if _, err := os.Stat(filename); err != nil {
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
log(true, "missing plugin", name, "as filename", filename)
|
log.Log(true, "missing plugin", name, "as filename", filename)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log(true, "Found plugin", name, "as filename", filename)
|
log.Log(true, "Found plugin", name, "as filename", filename)
|
||||||
|
|
||||||
plug, err := plugin.Open(filename)
|
plug, err := plugin.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log(debugError, "plugin FAILED =", filename, err)
|
log.Error(err, "plugin FAILED =", filename)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log(debugPlugin, "initToolkit() loading plugin =", filename)
|
log.Log(PLUG, "initToolkit() loading plugin =", filename)
|
||||||
|
|
||||||
var newPlug *aplug
|
var newPlug *aplug
|
||||||
newPlug = new(aplug)
|
newPlug = new(aplug)
|
||||||
|
@ -214,12 +205,12 @@ func initToolkit(name string, filename string) *aplug {
|
||||||
// set the communication to the plugins
|
// set the communication to the plugins
|
||||||
newPlug.pluginChan = newPlug.PluginChannel()
|
newPlug.pluginChan = newPlug.PluginChannel()
|
||||||
if (newPlug.pluginChan == nil) {
|
if (newPlug.pluginChan == nil) {
|
||||||
log(debugError, "initToolkit() ERROR PluginChannel() returned nil for plugin:", newPlug.name, filename)
|
log.Warn("initToolkit() ERROR PluginChannel() returned nil for plugin:", newPlug.name, filename)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
newPlug.Callback(me.guiChan)
|
newPlug.Callback(me.guiChan)
|
||||||
|
|
||||||
log(debugPlugin, "initToolkit() END", newPlug.name, filename)
|
log.Log(PLUG, "initToolkit() END", newPlug.name, filename)
|
||||||
return newPlug
|
return newPlug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,16 +246,16 @@ func newAction(n *Node, atype toolkit.ActionType) *toolkit.Action {
|
||||||
// sends the action/event to each toolkit via a golang plugin channel
|
// sends the action/event to each toolkit via a golang plugin channel
|
||||||
func sendAction(a *toolkit.Action) {
|
func sendAction(a *toolkit.Action) {
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.ActionType)
|
log.Log(PLUG, "Action() aplug =", aplug.name, "Action type=", a.ActionType)
|
||||||
if (aplug.pluginChan == nil) {
|
if (aplug.pluginChan == nil) {
|
||||||
log(logInfo, "Action() retrieving the aplug.PluginChannel()", aplug.name)
|
log.Info("Action() retrieving the aplug.PluginChannel()", aplug.name)
|
||||||
aplug.pluginChan = aplug.PluginChannel()
|
aplug.pluginChan = aplug.PluginChannel()
|
||||||
log(logInfo, "Action() retrieved", aplug.pluginChan)
|
log.Info("Action() retrieved", aplug.pluginChan)
|
||||||
}
|
}
|
||||||
log(logInfo, "Action() SEND to pluginChan", aplug.name)
|
log.Info("Action() SEND to pluginChan", aplug.name)
|
||||||
aplug.pluginChan <- *a
|
aplug.pluginChan <- *a
|
||||||
// added during debugging. might be a good idea in general for a tactile experience
|
// added during debugging. might be a good idea in general for a tactile experience
|
||||||
sleep(.02) // this delay makes it so SetText() works on initial widget creation
|
log.Sleep(.02) // this delay makes it so SetText() works on initial widget creation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,15 +266,16 @@ func (n *Node) InitEmbed(resFS embed.FS) *Node {
|
||||||
|
|
||||||
func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node {
|
func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node {
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log(logInfo, "LoadToolkitEmbed() already loaded toolkit plugin =", aplug.name)
|
log.Info("LoadToolkitEmbed() already loaded toolkit plugin =", aplug.name)
|
||||||
if (aplug.name == name) {
|
if (aplug.name == name) {
|
||||||
log(logError, "LoadToolkitEmbed() SKIPPING", name, "as you can't load it twice")
|
log.Warn("LoadToolkitEmbed() SKIPPING", name, "as you can't load it twice")
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.CreateTemp("", "sample." + name + ".so")
|
f, err := os.CreateTemp("", "sample." + name + ".so")
|
||||||
if (err != nil) {
|
if (err != nil) {
|
||||||
|
log.Error(err, "LoadToolkitEmbed() SKIPPING", name, "as you can't load it twice")
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
defer os.Remove(f.Name())
|
defer os.Remove(f.Name())
|
||||||
|
@ -291,25 +283,25 @@ func (n *Node) LoadToolkitEmbed(name string, b []byte) *Node {
|
||||||
|
|
||||||
p := initToolkit(name, f.Name())
|
p := initToolkit(name, f.Name())
|
||||||
if (p == nil) {
|
if (p == nil) {
|
||||||
log(logError, "LoadToolkitEmbed() embedded go file failed", name)
|
log.Warn("LoadToolkitEmbed() embedded go file failed", name)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) ListToolkits() {
|
func (n *Node) ListToolkits() {
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log(logNow, "ListToolkits() already loaded toolkit plugin =", aplug.name)
|
log.Log(PLUG, "ListToolkits() already loaded toolkit plugin =", aplug.name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) LoadToolkit(name string) *Node {
|
func (n *Node) LoadToolkit(name string) *Node {
|
||||||
log(logInfo, "LoadToolkit() START for name =", name)
|
log.Log(PLUG, "LoadToolkit() START for name =", name)
|
||||||
plug := initPlugin(name)
|
plug := initPlugin(name)
|
||||||
if (plug == nil) {
|
if (plug == nil) {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
log(logInfo, "LoadToolkit() sending InitToolkit action to the plugin channel")
|
log.Log(PLUG, "LoadToolkit() sending InitToolkit action to the plugin channel")
|
||||||
var a toolkit.Action
|
var a toolkit.Action
|
||||||
a.ActionType = toolkit.InitToolkit
|
a.ActionType = toolkit.InitToolkit
|
||||||
plug.pluginChan <- a
|
plug.pluginChan <- a
|
||||||
|
@ -317,16 +309,16 @@ func (n *Node) LoadToolkit(name string) *Node {
|
||||||
|
|
||||||
// TODO: find a new way to do this that is locking, safe and accurate
|
// TODO: find a new way to do this that is locking, safe and accurate
|
||||||
me.rootNode.redraw(plug)
|
me.rootNode.redraw(plug)
|
||||||
log(logInfo, "LoadToolkit() END for name =", name)
|
log.Log(PLUG, "LoadToolkit() END for name =", name)
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) CloseToolkit(name string) bool {
|
func (n *Node) CloseToolkit(name string) bool {
|
||||||
log(logInfo, "CloseToolkit() for name =", name)
|
log.Log(PLUG, "CloseToolkit() for name =", name)
|
||||||
for _, plug := range allPlugins {
|
for _, plug := range allPlugins {
|
||||||
log(debugGui, "CloseToolkit() found", plug.name)
|
log.Log(PLUG, "CloseToolkit() found", plug.name)
|
||||||
if (plug.name == name) {
|
if (plug.name == name) {
|
||||||
log(debugNow, "CloseToolkit() sending close", name)
|
log.Log(PLUG, "CloseToolkit() sending close", name)
|
||||||
var a toolkit.Action
|
var a toolkit.Action
|
||||||
a.ActionType = toolkit.CloseToolkit
|
a.ActionType = toolkit.CloseToolkit
|
||||||
plug.pluginChan <- a
|
plug.pluginChan <- a
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This recreates the whole GUI for a plugin
|
// This recreates the whole GUI for a plugin
|
||||||
|
@ -20,7 +21,7 @@ func (n *Node) redraw(p *aplug) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *Node) redo(plug *aplug) {
|
func (n *Node) redo(plug *aplug) {
|
||||||
log(logNow, "redo()", plug.name, n.id, n.WidgetType, n.Name)
|
log.Info("redo()", plug.name, n.id, n.WidgetType, n.Name)
|
||||||
|
|
||||||
var a *toolkit.Action
|
var a *toolkit.Action
|
||||||
a = new(toolkit.Action)
|
a = new(toolkit.Action)
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSlider(name string, x int, y int) *Node {
|
func (parent *Node) NewSlider(name string, x int, y int) *Node {
|
||||||
newNode := parent.newNode(name, toolkit.Slider)
|
newNode := parent.newNode(name, toolkit.Slider)
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log(debugGui, "even newer clicker() name in NewSlider name =", name)
|
log.Log(GUI, "even newer clicker() name in NewSlider name =", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.X = x
|
newNode.X = x
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewSpinner(name string, x int, y int) *Node {
|
func (parent *Node) NewSpinner(name string, x int, y int) *Node {
|
||||||
newNode := parent.newNode(name, toolkit.Spinner)
|
newNode := parent.newNode(name, toolkit.Spinner)
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log(debugChange, "default NewSpinner() change", name)
|
log.Info("default NewSpinner() change", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
newNode.X = x
|
newNode.X = x
|
||||||
|
|
|
@ -3,7 +3,7 @@ package gui
|
||||||
import (
|
import (
|
||||||
"sync"
|
"sync"
|
||||||
"embed"
|
"embed"
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
12
tab.go
12
tab.go
|
@ -1,7 +1,9 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This function should make a new node with the parent and
|
// This function should make a new node with the parent and
|
||||||
|
@ -12,16 +14,16 @@ func (n *Node) NewTab(text string) *Node {
|
||||||
|
|
||||||
if (n.WidgetType != toolkit.Window) {
|
if (n.WidgetType != toolkit.Window) {
|
||||||
// figure out what the actual window is
|
// figure out what the actual window is
|
||||||
log(logError, "NewTab() is being requested on something that isn't a Window. node =", n)
|
log.Warn("NewTab() is being requested on something that isn't a Window. node =", n)
|
||||||
if (n.parent == nil) {
|
if (n.parent == nil) {
|
||||||
// TODO: find a window. any window. never give up. never die.
|
// TODO: find a window. any window. never give up. never die.
|
||||||
log(logError, "NewTab() TODO: make a window here", n)
|
log.Warn("NewTab() TODO: make a window here", n)
|
||||||
panic("NewTab did not get passed a window")
|
panic("NewTab did not get passed a window")
|
||||||
}
|
}
|
||||||
log(logError, "NewTab() parent =", n.parent)
|
log.Warn("NewTab() parent =", n.parent)
|
||||||
if (n.parent.WidgetType == toolkit.Root) {
|
if (n.parent.WidgetType == toolkit.Root) {
|
||||||
// also broken
|
// also broken
|
||||||
log(logError, "NewTab() TODO: make or find a window here", n)
|
log.Warn("NewTab() TODO: make or find a window here", n)
|
||||||
panic("NewTab() did not get passed a window")
|
panic("NewTab() did not get passed a window")
|
||||||
}
|
}
|
||||||
// go up the binary tree until we find a window widget to add a tab too
|
// go up the binary tree until we find a window widget to add a tab too
|
||||||
|
|
|
@ -1,14 +1,16 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (parent *Node) NewTextbox(name string) *Node {
|
func (parent *Node) NewTextbox(name string) *Node {
|
||||||
newNode := parent.newNode(name, toolkit.Textbox)
|
newNode := parent.newNode(name, toolkit.Textbox)
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log(debugGui, "NewTextbox changed =", name)
|
log.Log(GUI, "NewTextbox changed =", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := newAction(newNode, toolkit.Add)
|
a := newAction(newNode, toolkit.Add)
|
||||||
|
@ -22,7 +24,7 @@ func (parent *Node) NewEntryLine(name string) *Node {
|
||||||
newNode.X = 1
|
newNode.X = 1
|
||||||
|
|
||||||
newNode.Custom = func() {
|
newNode.Custom = func() {
|
||||||
log(debugGui, "NewTextbox changed =", name)
|
log.Log(GUI, "NewTextbox changed =", name)
|
||||||
}
|
}
|
||||||
|
|
||||||
a := newAction(newNode, toolkit.Add)
|
a := newAction(newNode, toolkit.Add)
|
||||||
|
|
|
@ -1,204 +0,0 @@
|
||||||
package toolkit
|
|
||||||
|
|
||||||
// passes information between the toolkit library (plugin)
|
|
||||||
//
|
|
||||||
// This is the only thing that is passed between the toolkit plugin
|
|
||||||
//
|
|
||||||
// what names should be used? This is not part of [[Graphical Widget]]
|
|
||||||
// Event() seems like a good name.
|
|
||||||
// Event is used too much: web dev, cloud, etc
|
|
||||||
// I'm using "Action". Maybe it should really be
|
|
||||||
// "Interaction" as per wikipedia [[User interface]]
|
|
||||||
//
|
|
||||||
// TODO: convert this to a protobuf (?)
|
|
||||||
//
|
|
||||||
|
|
||||||
type WidgetType int // Button, Menu, Checkbox, etc.
|
|
||||||
type ActionType int // Add, SetText, Click, Hide, Append, Delete, etc
|
|
||||||
|
|
||||||
type Action struct {
|
|
||||||
ActionType ActionType
|
|
||||||
WidgetType WidgetType
|
|
||||||
|
|
||||||
WidgetId int
|
|
||||||
ParentId int
|
|
||||||
|
|
||||||
Text string // what is visable to the user
|
|
||||||
Name string // a name useful for programming
|
|
||||||
|
|
||||||
// This is how the values are passed back and forth
|
|
||||||
// values from things like checkboxes & dropdown's
|
|
||||||
B bool
|
|
||||||
I int
|
|
||||||
S string
|
|
||||||
|
|
||||||
// This is used for things like a slider(0,100)
|
|
||||||
X int
|
|
||||||
Y int
|
|
||||||
|
|
||||||
// This is for the grid size & widget position
|
|
||||||
W int
|
|
||||||
H int
|
|
||||||
AtW int
|
|
||||||
AtH int
|
|
||||||
|
|
||||||
// Put space around elements to improve look & feel
|
|
||||||
Margin bool
|
|
||||||
|
|
||||||
// Make widgets fill up the space available
|
|
||||||
Expand bool
|
|
||||||
|
|
||||||
A any // switch to this or deprecate this? pros/cons?
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
Unknown WidgetType = iota
|
|
||||||
Root // the master 'root' node of the binary tree
|
|
||||||
Flag // used to send configuration values to plugins
|
|
||||||
Window // in certain gui's (ncurses), these are tabs
|
|
||||||
Tab // internally, this is a window
|
|
||||||
Frame // deprecate?
|
|
||||||
Grid // like drawers in a chest
|
|
||||||
Group // like the 'Appetizers' section on a menu
|
|
||||||
Box // a vertical or horizontal stack of widgets
|
|
||||||
Button
|
|
||||||
Checkbox // select 'on' or 'off'
|
|
||||||
Dropdown
|
|
||||||
Combobox // dropdown with edit=true
|
|
||||||
Label
|
|
||||||
Textbox // is this a Label with edit=true
|
|
||||||
Slider // like a progress bar
|
|
||||||
Spinner // like setting the oven temperature
|
|
||||||
Separator // TODO
|
|
||||||
Image // TODO
|
|
||||||
Area // TODO
|
|
||||||
Form // TODO
|
|
||||||
Font // TODO
|
|
||||||
Color // TODO
|
|
||||||
Dialog // TODO
|
|
||||||
Stdout // can be used to capture and display log output
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
Add ActionType = iota
|
|
||||||
Delete
|
|
||||||
Get
|
|
||||||
Set
|
|
||||||
GetText
|
|
||||||
SetText
|
|
||||||
AddText
|
|
||||||
Show
|
|
||||||
Hide
|
|
||||||
Enable
|
|
||||||
Disable
|
|
||||||
Margin
|
|
||||||
Unmargin
|
|
||||||
Pad
|
|
||||||
Unpad
|
|
||||||
Append
|
|
||||||
Move
|
|
||||||
Dump
|
|
||||||
User // the user did something (mouse, keyboard, etc)
|
|
||||||
InitToolkit // initializes the toolkit
|
|
||||||
CloseToolkit // closes the toolkit
|
|
||||||
UserQuit // the user closed the GUI
|
|
||||||
EnableDebug // open the debugging window
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s WidgetType) String() string {
|
|
||||||
switch s {
|
|
||||||
case Root:
|
|
||||||
return "Root"
|
|
||||||
case Flag:
|
|
||||||
return "Flag"
|
|
||||||
case Window:
|
|
||||||
return "Window"
|
|
||||||
case Tab:
|
|
||||||
return "Tab"
|
|
||||||
case Frame:
|
|
||||||
return "Frame"
|
|
||||||
case Grid:
|
|
||||||
return "Grid"
|
|
||||||
case Group:
|
|
||||||
return "Group"
|
|
||||||
case Box:
|
|
||||||
return "Box"
|
|
||||||
case Button:
|
|
||||||
return "Button"
|
|
||||||
case Checkbox:
|
|
||||||
return "Checkbox"
|
|
||||||
case Dropdown:
|
|
||||||
return "Dropdown"
|
|
||||||
case Combobox:
|
|
||||||
return "Combobox"
|
|
||||||
case Label:
|
|
||||||
return "Label"
|
|
||||||
case Textbox:
|
|
||||||
return "Textbox"
|
|
||||||
case Slider:
|
|
||||||
return "Slider"
|
|
||||||
case Spinner:
|
|
||||||
return "Spinner"
|
|
||||||
case Separator:
|
|
||||||
return "Separator"
|
|
||||||
case Image:
|
|
||||||
return "Image"
|
|
||||||
case Area:
|
|
||||||
return "Area"
|
|
||||||
case Form:
|
|
||||||
return "Form"
|
|
||||||
case Font:
|
|
||||||
return "Font"
|
|
||||||
case Color:
|
|
||||||
return "Color"
|
|
||||||
case Dialog:
|
|
||||||
return "Dialog"
|
|
||||||
case Stdout:
|
|
||||||
return "Stdout"
|
|
||||||
case Unknown:
|
|
||||||
return "Unknown"
|
|
||||||
}
|
|
||||||
return "WidgetType.String() Error"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s ActionType) String() string {
|
|
||||||
switch s {
|
|
||||||
case Add:
|
|
||||||
return "Add"
|
|
||||||
case Delete:
|
|
||||||
return "Delete"
|
|
||||||
case Get:
|
|
||||||
return "Get"
|
|
||||||
case Set:
|
|
||||||
return "Set"
|
|
||||||
case GetText:
|
|
||||||
return "GetText"
|
|
||||||
case SetText:
|
|
||||||
return "SetText"
|
|
||||||
case AddText:
|
|
||||||
return "AddText"
|
|
||||||
case Show:
|
|
||||||
return "Show"
|
|
||||||
case Hide:
|
|
||||||
return "Hide"
|
|
||||||
case Enable:
|
|
||||||
return "Enable"
|
|
||||||
case Disable:
|
|
||||||
return "Disable"
|
|
||||||
case Margin:
|
|
||||||
return "Margin"
|
|
||||||
case Unmargin:
|
|
||||||
return "Unmargin"
|
|
||||||
case Pad:
|
|
||||||
return "Pad"
|
|
||||||
case Unpad:
|
|
||||||
return "Unpad"
|
|
||||||
case Append:
|
|
||||||
return "Append"
|
|
||||||
case Move:
|
|
||||||
return "Move"
|
|
||||||
case Dump:
|
|
||||||
return "Dump"
|
|
||||||
}
|
|
||||||
return "ActionType.String() Error"
|
|
||||||
}
|
|
39
watchdog.go
39
watchdog.go
|
@ -2,6 +2,8 @@ package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var watchtime time.Duration = 100 // in tenths of seconds
|
var watchtime time.Duration = 100 // in tenths of seconds
|
||||||
|
@ -16,43 +18,8 @@ var watchtime time.Duration = 100 // in tenths of seconds
|
||||||
func Watchdog() {
|
func Watchdog() {
|
||||||
var i = 1
|
var i = 1
|
||||||
for {
|
for {
|
||||||
log(logInfo, "gui.Watchdog() is alive. give me something to do.", i)
|
log.Verbose("gui.Watchdog() is alive. give me something to do.", i)
|
||||||
if (me.rootNode == nil) {
|
|
||||||
log(logInfo, "me.rootNode == nil", i)
|
|
||||||
} else {
|
|
||||||
if (logVerbose) {
|
|
||||||
me.rootNode.ListChildren(true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(watchtime * time.Second / 10)
|
time.Sleep(watchtime * time.Second / 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// https://www.reddit.com/r/golang/comments/12em87q/how_to_run_periodic_tasks/
|
|
||||||
/*
|
|
||||||
package main
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
|
||||||
ticker := time.NewTicker(time.Second)
|
|
||||||
defer ticker.Stop()
|
|
||||||
done := make(chan bool)
|
|
||||||
go func() {
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
done <- true
|
|
||||||
}()
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-done:
|
|
||||||
fmt.Println("Done!")
|
|
||||||
return
|
|
||||||
case t := <-ticker.C:
|
|
||||||
fmt.Println("Current time: ", t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
package gui
|
package gui
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"go.wit.com/gui/gui/toolkit"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/gui/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
// This routine creates a blank window with a Title and size (W x H)
|
// This routine creates a blank window with a Title and size (W x H)
|
||||||
|
@ -13,7 +14,7 @@ func (parent *Node) NewWindow(title string) *Node {
|
||||||
newNode = parent.newNode(title, toolkit.Window)
|
newNode = parent.newNode(title, toolkit.Window)
|
||||||
newNode.Custom = StandardExit
|
newNode.Custom = StandardExit
|
||||||
|
|
||||||
log(logInfo, "NewWindow()", title)
|
log.Info("NewWindow()", title)
|
||||||
|
|
||||||
a := newAction(newNode, toolkit.Add)
|
a := newAction(newNode, toolkit.Add)
|
||||||
sendAction(a)
|
sendAction(a)
|
||||||
|
|
Loading…
Reference in New Issue