Squashed commit of the following:

commit 448abc843e2241bab6c399f7a836dccba1defc18
Author: Jeff Carr <jcarr@wit.com>
Date:   Sun Mar 12 08:35:28 2023 -0500

    this should probably be a new release now

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit a4064f7a6c5ac67437768aa2bc67c75dafc91c4c
Author: Jeff Carr <jcarr@wit.com>
Date:   Sat Mar 11 03:18:23 2023 -0600

    able to work on add 'Box' and play with 'Image'

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 6e59573d85e82ecb005805f50711dddc2df50480
Author: Jeff Carr <jcarr@wit.com>
Date:   Sat Mar 11 03:04:34 2023 -0600

    rearrange widget debugging

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit e0570de75c6eb1b4f49e541d9ef5d83ae4434d3d
Author: Jeff Carr <jcarr@wit.com>
Date:   Sat Mar 11 02:29:20 2023 -0600

    debugging is lots smarter

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit ece32a1e43d91cd197d0a8497ad2f034c46126e1
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 21:38:23 2023 -0600

    first pass on a node delete

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit c91cb0eddb0f73f8dea9b21a16cd76c7e2c19a33
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 21:06:29 2023 -0600

    can recreate window list

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 470f9dc26aefd3626b319264fe151aa48d4d5377
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 12:07:34 2023 -0600

    attempt to ressurect mouse in the console plugin

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 747bb53e06dda458cc8cd77b665f4d9d07f5e925
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 10:47:14 2023 -0600

    jesus. gocui actually builds and works again as a plugin

    it didn't take too much to change it

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 9283c65c8e9b8d2630b251ad952b6b52caddb307
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 07:26:53 2023 -0600

    show/hide/etc for window widgets

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 5724cd7ffd8595ae049a7c9c21cb2f1a993c4b76
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 06:40:36 2023 -0600

    compiles and runs

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 44a5e69ce17cb506adfe24ca72cc86caa9ebcc70
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 05:57:15 2023 -0600

    more debugging improvements

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit b86f145f0252e7545b2e7fa78e1d5960cacb7bad
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 10 03:42:32 2023 -0600

    set margin on tab's works

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit d2218c08cf44acd5f017a8faa1439ee6d2fd46d5
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 16:26:21 2023 -0600

    ignore all *.so files

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit e21934fff3cfea30b04df01bf0714f6927aa78f4
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 16:25:15 2023 -0600

    can't embed the toolkit/*.so files here

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit f1e6c5fc9c8ca36db3ad6109d64612b6850fa856
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 16:21:14 2023 -0600

    andlabs group widget has Show() and Hide()

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit e8487504aa76ca99c4891b777585a428fda0ef62
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 16:07:56 2023 -0600

    pass the node id into the plugin to use in channels

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 3667940a77af4e3855facb9247771d595477302f
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 14:20:21 2023 -0600

    fix SetText() on Label

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit 311d6be66db84b63fb7124df64e2e9be0f0b76a4
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 14:06:46 2023 -0600

    still compiles and runs

    Signed-off-by: Jeff Carr <jcarr@wit.com>

commit ee4e9b21ef59a97f902c6dae2a57ac7b3063fe3b
Author: Jeff Carr <jcarr@wit.com>
Date:   Thu Mar 9 11:02:34 2023 -0600

    compiles

    Signed-off-by: Jeff Carr <jcarr@wit.com>

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-03-12 08:47:16 -05:00
parent 7d1836390a
commit 9223ff18a2
60 changed files with 1953 additions and 779 deletions

3
.gitignore vendored
View File

@ -1,13 +1,14 @@
*.swp
# ignore compiled plugins
toolkit/*.so
*.so
cmds/buttonplugin/buttonplugin
cmds/console-ui-helloworld/console-ui-helloworld
cmds/debug/debug
cmds/helloworld/helloworld
cmds/textbox/textbox
cmds/*/helloconsole
# temporary files when building debian packages
/*.deb

View File

@ -9,6 +9,9 @@ all: README.md
make clean
make plugins
build-dep:
apt install -f libgtk-3-dev
# should update every go dependancy (?)
update:
git pull
@ -16,13 +19,14 @@ update:
deb:
cd debian && make
dpkg-deb -c go-wit-gui*.deb
-wit mirrors
examples: \
all \
cmds-helloworld \
cmds-buttonplugin \
cmds-console-ui-helloworld \
cmds-helloworld \
cmds-textbox \
cmds-debug
@ -32,6 +36,7 @@ cmds-buttonplugin:
cmds-console-ui-helloworld:
make -C cmds/console-ui-helloworld
# this is the most basic one. This syntax should always work
cmds-helloworld:
make -C cmds/helloworld
@ -41,6 +46,9 @@ cmds-debug:
cmds-textbox:
make -C cmds/textbox
cmds-helloconsole:
make -C cmds/plugin-consoleonly
# sync repo to the github backup
# git remote add github git@github.com:witorg/gui.git
# git remote add github2 git@github.com:wit-go/gui.git
@ -64,11 +72,14 @@ clean:
rm -f toolkit/*.so
cd debian && make clean
plugins: plugins-gocui plugins-andlabs
plugins: plugins-gocui plugins-democui plugins-andlabs
plugins-gocui:
make -C toolkit/gocui
plugins-democui:
make -C toolkit/democui
plugins-andlabs:
cd toolkit/andlabs/ && GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so
# make -C toolkit/andlabs

View File

@ -145,11 +145,11 @@ var WARN bool
## Functions
### func [DebugWidgetWindow](/debugWidget.go#L107)
### func [DebugWidgetWindow](/debugWidget.go#L56)
`func DebugWidgetWindow(w *Node)`
### func [DebugWindow](/debugWindow.go#L9)
### func [DebugWindow](/debugWindow.go#L21)
`func DebugWindow()`
@ -159,11 +159,11 @@ Creates a window helpful for debugging this package
`func Delete(c *Node)`
### func [Indent](/debug.go#L101)
### func [Indent](/debug.go#L116)
`func Indent(a ...interface{})`
### func [InitPlugins](/main.go#L50)
### func [InitPlugins](/main.go#L56)
`func InitPlugins(names []string)`
@ -173,13 +173,13 @@ Creates a window helpful for debugging this package
loads and initializes a toolkit (andlabs/ui, gocui, etc)
### func [Main](/main.go#L91)
### func [Main](/main.go#L97)
`func Main(f func())`
This should not pass a function
### func [Queue](/main.go#L121)
### func [Queue](/main.go#L127)
`func Queue(f func())`
@ -190,23 +190,24 @@ other goroutines. This is due to the nature of how
Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
For example: gui.Queue(NewWindow())
### func [SetDebug](/debug.go#L27)
### func [SetDebug](/debug.go#L26)
`func SetDebug(s bool)`
### func [SetFlag](/debug.go#L41)
### func [SetFlag](/debug.go#L42)
`func SetFlag(s string, b bool)`
### func [ShowDebugValues](/debug.go#L62)
### func [ShowDebugValues](/debug.go#L75)
`func ShowDebugValues()`
### func [StandardExit](/main.go#L140)
### func [StandardExit](/main.go#L147)
`func StandardExit()`
The window is destroyed but the application does not quit
The window is destroyed and the application exits
TODO: properly exit the plugin since Quit() doesn't do it
### func [Watchdog](/watchdog.go#L15)

View File

@ -27,7 +27,11 @@ func init() {
arg.MustParse(&args)
fmt.Println(args.Foo, args.Bar, args.User)
f1, err = os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
log.Println()
log.Println("STDOUT is now at /tmp/guilogfile")
log.Println("STDOUT is now at /tmp/guilogfile")
log.Println()
f1, err = os.OpenFile(outfile, os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
}

View File

@ -10,13 +10,18 @@ import (
)
var title string = "Demo Plugin Window"
var outfile string = "/tmp/guilogfile"
// this is broken. delete this
func main() {
// this set the xterm and mate-terminal window title. maybe works generally?
fmt.Println("\033]0;" + title + "\007")
// time.Sleep(5 * time.Second)
// var w *gui.Node
// this doesn't seem to work
captureSTDOUT()
// captureSTDOUT()
// gui.LoadToolkit("default")
// panic("WTF gocui not happening")
@ -57,6 +62,10 @@ func buttonWindow() {
w = gui.NewWindow()
g = w.NewGroup("buttonGroup")
g.NewButton("this app is old", func () {
})
g.NewLabel("STDOUT is set to: " + outfile)
g.NewButton("hello", func () {
log.Println("world")
})

View File

@ -0,0 +1,14 @@
run: build
./helloconsole
build-release:
go get -v -u -x .
go install -v -o helloconsole
helloconsole
build:
GO111MODULE="off" go get -v -x .
GO111MODULE="off" go build -v -o helloconsole
update:
GO111MODULE="off" go get -v -u -x .

View File

@ -0,0 +1,31 @@
// This creates a simple hello world window
package main
import (
"log"
"git.wit.org/wit/gui"
arg "github.com/alexflint/go-arg"
)
type LogOptions struct {
LogFile string
Verbose bool
User string `arg:"env:USER"`
}
var args struct {
LogOptions
gui.GuiArgs
}
func init() {
arg.MustParse(&args)
log.Println("Toolkit = ", args.Toolkit)
if (args.GuiDebug) {
gui.DebugWindow()
}
if (args.GuiVerbose) {
gui.SetDebug(true)
}
}

View File

@ -0,0 +1,34 @@
// This is a simple example
package main
import (
"log"
"git.wit.org/wit/gui"
)
func main() {
gui.InitPlugins([]string{"gocui"})
// gui.InitPlugins([]string{"democui"})
gui.Main(helloworld)
}
// This creates a window
func helloworld() {
var w *gui.Node
gui.Config.Title = "helloworld golang wit/gui window"
gui.Config.Width = 640
gui.Config.Height = 480
w = gui.NewWindow()
w.NewButton("hello", func () {
log.Println("world")
})
w.NewButton("Flags", func () {
log.Println("the debugging flags window")
w.DebugFlags(false)
})
w.NewButton("Widgets", func () {
w.DebugWidgets(false)
log.Println("debug the widgets window")
})
}

View File

@ -17,7 +17,7 @@ func (n *Node) Add(str string) {
func (n *Node) SetText(str string) bool {
log(debugChange, "gui.SetText() value =", str)
n.widget.Action = "Set"
n.widget.Action = "SetText"
n.widget.S = str
send(n.parent, n)
return true

View File

@ -17,7 +17,6 @@ var debugTabs bool = false
var debugFlags bool = false
var debugChange bool = false // shows user events like mouse and keyboard
var debugPlugin bool = false
var debugToolkit bool = false
// for printing out the binary tree
var listChildrenParent *Node
@ -26,28 +25,42 @@ var defaultPadding = " "
func SetDebug (s bool) {
debugGui = s
debugDump = s
debugTabs = s
debugPlugin = s
debugNode = s
debugToolkit = s
SetFlag("Node", s)
SetFlag("Tabs", s)
SetFlag("Dump", s)
SetFlag("Flags", s)
SetFlag("Toolkit", 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":
// print them here? For now, just used to print settings in the plugins
// ShowDebugValues() // print them here?
default:
log(debugError, "Can't set unknown flag", s)
log(debugGui, "Can't set unknown flag", s)
}
// send the flag to the toolkit
@ -69,7 +82,6 @@ func ShowDebugValues() {
log(true, "DebugTabs =", debugTabs)
log(true, "DebugPlugin =", debugPlugin)
log(true, "DebugNode =", debugNode)
log(true, "DebugToolkit =", debugToolkit)
SetFlag("Show", true)
}
@ -83,6 +95,9 @@ func (n *Node) Dump() {
Indent("Name = ", n.Name)
Indent("Width = ", n.Width)
Indent("Height = ", n.Height)
Indent("Widget Name = ", n.widget.Name)
Indent("Widget Type = ", n.widget.Type)
Indent("Widget Id = ", n.widget.GetId())
if (n.parent == nil) {
Indent("parent = nil")
@ -102,8 +117,8 @@ func Indent(a ...interface{}) {
logindent(listChildrenDepth, defaultPadding, a...)
}
func (n *Node) dumpWidget() {
var info string
func (n *Node) dumpWidget() string {
var info, d string
info = n.widget.Type.String()
@ -115,18 +130,33 @@ func (n *Node) dumpWidget() {
info += " = " + strconv.FormatBool(n.widget.B)
}
d = strconv.Itoa(n.id) + " " + info
var tabs string
for i := 0; i < listChildrenDepth; i++ {
tabs = tabs + defaultPadding
}
d = tabs + d
logindent(listChildrenDepth, defaultPadding, n.id, info)
return d
}
func (n *Node) ListChildren(dump bool) {
n.dumpWidget()
func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
s := n.dumpWidget()
if (dropdown != nil) {
dropdown.AddDropdownName(s)
if (mapNodes != nil) {
mapNodes[s] = n
}
}
if (dump == true) {
n.Dump()
}
if len(n.children) == 0 {
if (n.parent == nil) {
} else {
return
}
log(debugNode, "\t\t\tparent =",n.parent.id)
if (listChildrenParent != nil) {
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
@ -135,7 +165,6 @@ func (n *Node) ListChildren(dump bool) {
exit("parent.child does not match child.parent")
}
}
}
log(debugNode, "\t\t", n.id, "has no children")
return
}
@ -158,7 +187,7 @@ func (n *Node) ListChildren(dump bool) {
}
listChildrenParent = n
listChildrenDepth += 1
child.ListChildren(dump)
child.ListChildren(dump, dropdown, mapNodes)
listChildrenDepth -= 1
}
return

View File

@ -2,7 +2,7 @@ package gui
// 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(makeWindow bool) {
func (n *Node) DebugFlags(makeWindow bool) {
var w, g *Node
// Either:
@ -17,76 +17,68 @@ func (n *Node) debugFlags(makeWindow bool) {
} else {
w = n.NewTab("Flags")
}
w.Dump()
g = w.NewGroup("Debug Flags")
g = w.NewGroup("Show")
g.NewButton("Turn on all Debug Flags", func () {
g.NewButton("Dump Flags", func () {
ShowDebugValues()
})
g.NewButton("All On", func () {
SetDebug(true)
})
g.NewButton("Turn off all Debug Flags", func () {
g.NewButton("All Off", func () {
SetDebug(false)
})
g = w.NewGroup("List")
// generally useful debugging
cb1 := g.NewCheckbox("debugGui")
cb1 := g.NewCheckbox("debug Gui (like verbose=1)")
cb1.Custom = func() {
debugGui = cb1.widget.B
log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B)
}
// errors. by default these always output somewhere
cbE := g.NewCheckbox("debugError")
cbE := g.NewCheckbox("debug Error (bad things. default=true)")
cbE.Custom = func() {
debugError = cbE.widget.B
SetFlag("Error", debugError)
SetFlag("Error", cbE.widget.B)
}
// debugging that will show you things like mouse clicks, user inputing text, etc
// also set toolkit.DebugChange
cb2 := g.NewCheckbox("debugChange")
cb2 := g.NewCheckbox("debug Change (keyboard and mouse events)")
cb2.Custom = func() {
debugChange = cb2.widget.B
SetFlag("Change", debugChange)
log(debugGui, "Custom() n.widget =", cb2.widget.Name, cb2.widget.B)
SetFlag("Change", cb2.widget.B)
}
// supposed to tell if you are going to dump full variable output
cb3 := g.NewCheckbox("debugDump")
cb3 := g.NewCheckbox("debug Dump (show lots of output)")
cb3.Custom = func() {
debugDump = cb3.widget.B
log(debugGui, "Custom() n.widget =", cb3.widget.Name, cb3.widget.B)
SetFlag("Dump", cbE.widget.B)
}
cb4 := g.NewCheckbox("debugTabs")
cb4 := g.NewCheckbox("debug Tabs (tabs and windows)")
cb4.Custom = func() {
debugTabs = cb4.widget.B
log(debugGui, "Custom() n.widget =", cb4.widget.Name, cb4.widget.B)
SetFlag("Tabs", cb4.widget.B)
}
cb6 := g.NewCheckbox("debug Node (the binary tree)")
cb6.Custom = func() {
SetFlag("Plugin", cb6.widget.B)
}
// should show you when things go into or come back from the plugin
cb5 := g.NewCheckbox("debugPlugin")
cb5 := g.NewCheckbox("debug Plugin (plugin interaction)")
cb5.Custom = func() {
debugPlugin = cb5.widget.B
log(debugGui, "Custom() n.widget =", cb5.widget.Name, cb5.widget.B)
}
cb6 := g.NewCheckbox("debugNode")
cb6.Custom = func() {
debugNode = cb6.widget.B
log(debugGui, "Custom() n.widget =", cb6.widget.Name, cb6.widget.B)
SetFlag("Plugin", cb5.widget.B)
}
// turns on debugging inside the plugin toolkit
cb7 := g.NewCheckbox("debugToolkit")
cb7 := g.NewCheckbox("debug Toolkit (the plugin internals)")
cb7.Custom = func() {
// SetDebugToolkit(cb7.widget.B)
SetFlag("Toolkit", cb7.widget.B)
log(debugFlags, "Custom() n.widget =", cb7.widget.Name, cb7.widget.B)
}
g.NewButton("Dump Debug Flags", func () {
ShowDebugValues()
})
}

View File

@ -11,7 +11,7 @@ import (
var debugWG *sync.WaitGroup
var debugNumberChan chan int
func (n *Node) debugGoChannels(makeWindow bool) {
func (n *Node) DebugGoChannels(makeWindow bool) {
var w, g *Node
// Either:

View File

@ -9,7 +9,7 @@ import (
"runtime/pprof"
)
func (n *Node) debugGolangWindow(makeWindow bool) {
func (n *Node) DebugGolangWindow(makeWindow bool) {
var w, g, og, outputTextbox *Node
// Either:
@ -17,8 +17,8 @@ func (n *Node) debugGolangWindow(makeWindow bool) {
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "GO"
Config.Width = 300
Config.Height = 400
Config.Width = 1280
Config.Height = 720
w = NewWindow()
w.Custom = w.StandardClose
} else {
@ -32,7 +32,19 @@ func (n *Node) debugGolangWindow(makeWindow bool) {
tmp, _ := debug.ReadBuildInfo()
outputTextbox.SetText(tmp.String())
})
g.NewButton("debug.PrintStack()", func () {
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 () {
@ -40,11 +52,6 @@ func (n *Node) debugGolangWindow(makeWindow bool) {
pprof.Lookup("goroutine").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("pprof.Lookup(heap)", func () {
buf := new(bytes.Buffer)
pprof.Lookup("heap").WriteTo(buf, 1)
outputTextbox.SetText(buf.String())
})
g.NewButton("pprof.Lookup(block)", func () {
buf := new(bytes.Buffer)
pprof.Lookup("block").WriteTo(buf, 1)
@ -91,7 +98,9 @@ func (n *Node) debugGolangWindow(makeWindow bool) {
panic("test")
})
g.NewLabel("TODO:")
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
@ -114,13 +123,6 @@ func (n *Node) debugGolangWindow(makeWindow bool) {
g.NewButton("debug.SetTraceback('all')", func () {
debug.SetTraceback("all")
})
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()))
})
// deprecated (probably) by String() implementation within golang
g.NewButton("dumpModuleInfo() (deprecate)", func () {

View File

@ -2,179 +2,272 @@ package gui
import (
"strconv"
"git.wit.org/wit/gui/toolkit"
)
var debugGrid *Node
func (n *Node) debugWidgets(makeWindow bool) {
var w, gList, gShow *Node
// 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
// the label where the user can see which widget is active
var activeLabel *Node
var activeLabelType *Node
// tmp junk
var debugGrid *Node
var debugGridLabel *Node
var debugWidgetBut1, debugWidgetBut2 *Node
func setActiveWidget(w *Node) {
if (activeLabel == nil) {
// the debug window doesn't exist yet
// TODO: make a fake binary tree for this(?)
return
}
if (w == nil) {
log(debugError, "setActiveWidget() was sent nil !!!")
return
}
activeWidget = w
log(true, "The Widget is set to", w.id, w.Name)
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name
activeLabel.SetText(title)
activeLabelType.SetText("widget.Type = " + w.widget.Type.String())
// temporary stuff
if (w.widget.Type == toolkit.Window) {
debugWidgetBut1.widget.Action = "Enable"
send(debugWidgetBut1.parent, debugWidgetBut1)
debugWidgetBut2.widget.Action = "Enable"
send(debugWidgetBut2.parent, debugWidgetBut2)
} else {
debugWidgetBut1.widget.Action = "Disable"
send(debugWidgetBut1.parent, debugWidgetBut1)
debugWidgetBut2.widget.Action = "Disable"
send(debugWidgetBut2.parent, debugWidgetBut2)
}
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 (makeWindow) {
Config.Title = "Debug Widgets"
if (makeTabs) {
Config.Title = "Widgets"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w.Custom = w.StandardClose
bugWidget = NewWindow()
bugWidget.Custom = bugWidget.StandardClose
} else {
w = n.NewTab("Widgets")
bugWidget = bugWin.NewTab("Widgets")
}
w.Dump()
gList = w.NewGroup("Pick a widget to debug")
gShow = w.NewGroup("Added Widgets go here")
g := bugWidget.NewGroup("widget:")
gList.NewButton("Button", func () {
SetDebug(true)
a := gShow.NewButton("myButton", func () {
log("this code is more better")
activeLabel = g.NewLabel("undef")
activeLabelType = g.NewLabel("undef")
// common things that should work against each widget
g = bugWidget.NewGroup("common things")
g.NewButton("Disable()", func () {
activeWidget.widget.Action = "Disable"
send(activeWidget.parent, activeWidget)
})
SetDebug(false)
DebugWidgetWindow(a)
g.NewButton("Enable()", func () {
activeWidget.widget.Action = "Enable"
send(activeWidget.parent, activeWidget)
})
gList.NewButton("Checkbox", func () {
a := gShow.NewCheckbox("myCheckbox")
g.NewButton("Show()", func () {
activeWidget.widget.Action = "Show"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Hide()", func () {
activeWidget.widget.Action = "Hide"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Delete()", func () {
Delete(activeWidget)
})
g.NewButton("Dump()", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
activeWidget.Dump()
debugGui = g
debugDump = d
})
newG := bugWidget.NewGroup("add things")
newG.debugAddWidgetButtons()
g = bugWidget.NewGroup("change things")
g.NewButton("SetMargin(true)", func () {
activeWidget.widget.Action = "SetMargin"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
})
g.NewButton("SetMargin(false)", func () {
activeWidget.widget.Action = "SetMargin"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
})
g.NewButton("Value()", func () {
log("activeWidget.B =", activeWidget.widget.B)
log("activeWidget.I =", activeWidget.widget.I)
log("activeWidget.S =", activeWidget.widget.S)
})
g.NewButton("Set(true)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
})
g.NewButton("Set(false)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
})
g.NewButton("Set(20)", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.B = true
activeWidget.widget.I = 20
activeWidget.widget.S = "20"
send(activeWidget.parent, activeWidget)
})
g.NewButton("SetText('foo')", func () {
activeWidget.widget.Action = "Set"
activeWidget.widget.S = "foo"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Delete()", func () {
activeWidget.widget.Action = "Delete"
send(activeWidget.parent, activeWidget)
})
debugWidgetBut1 = g.NewButton("SetRaw(true)", func () {
activeWidget.widget.Action = "SetRaw"
activeWidget.widget.B = true
send(activeWidget.parent, activeWidget)
})
debugWidgetBut2 = g.NewButton("SetRaw(false)", func () {
activeWidget.widget.Action = "SetRaw"
activeWidget.widget.B = false
send(activeWidget.parent, activeWidget)
})
g = bugWidget.NewGroup("not working?")
g.NewButton("Add('foo')", func () {
activeWidget.widget.Action = "Add"
activeWidget.widget.S = "foo"
send(activeWidget.parent, activeWidget)
})
g.NewButton("Add button to (1,1)", func () {
activeWidget.widget.Action = "AddGrid"
activeWidget.widget.B = false
send(activeWidget, debugGridLabel)
// debugGrid = gShoactiveWidget.NewGrid("tmp grid", 2, 3)
})
setActiveWidget(g)
}
func (n *Node) debugAddWidgetButtons() {
n.NewButton("Button", func () {
a := activeWidget.NewButton("myButton", nil)
a.Custom = func () {
log("custom checkox func a =", a.widget.B, a.id)
log("this code is more better", a.widget.B, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Label", func () {
a := gShow.NewLabel("mylabel")
DebugWidgetWindow(a)
})
gList.NewButton("Textbox", func () {
a := gShow.NewTextbox("mytext")
n.NewButton("Checkbox", func () {
a := activeWidget.NewCheckbox("myCheckbox")
a.Custom = func () {
log("custom TextBox() a =", a.widget.S, a.id)
log("custom checkox func a=", a.widget.B, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Slider", func () {
a := gShow.NewSlider("tmp slider", 10, 55)
n.NewButton("Label", func () {
activeWidget.NewLabel("mylabel")
})
n.NewButton("Textbox", func () {
a := activeWidget.NewTextbox("mytext")
a.Custom = func () {
log("custom slider() a =", a.widget.I, a.id)
log("custom TextBox() a =", a.widget.S, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Spinner", func () {
a := gShow.NewSpinner("tmp spinner", 6, 32)
n.NewButton("Slider", func () {
a := activeWidget.NewSlider("tmp slider", 10, 55)
a.Custom = func () {
log("custom spinner() a =", a.widget.I, a.id)
log("custom slider() a =", a.widget.I, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Dropdown", func () {
a := gShow.NewDropdown("tmp dropdown")
n.NewButton("Spinner", func () {
a := activeWidget.NewSpinner("tmp spinner", 6, 32)
a.Custom = func () {
log("custom spinner() a =", a.widget.I, "id=", a.id)
}
})
n.NewButton("Dropdown", func () {
a := activeWidget.NewDropdown("tmp dropdown")
a.AddDropdownName("this is better than tcl/tk")
a.AddDropdownName("make something for tim")
a.AddDropdownName("for qflow")
a.Add("and for riscv")
a.Custom = func () {
log("custom dropdown() a =", a.widget.Name, a.widget.S)
log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Combobox", func () {
a := gShow.NewCombobox("tmp combobox")
n.NewButton("Combobox", func () {
a := activeWidget.NewCombobox("tmp combobox")
a.Add("mirrors.wit.com")
a.Add("go.wit.org")
a.Custom = func () {
log("custom combobox() a =", a.widget.Name, a.widget.S)
log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id)
}
DebugWidgetWindow(a)
})
gList.NewButton("Grid", func () {
n.NewButton("Grid", func () {
// Grid numbering by (X,Y)
// -----------------------------
// -- (1,1) -- (2,1) -- (3,1) --
// -- (1,2) -- (2,1) -- (3,1) --
// -----------------------------
SetDebug(true)
debugGrid = gShow.NewGrid("tmp grid", 2, 3)
debugGrid.NewLabel("mirrors.wit.com")
SetDebug(false)
// SetDebug(true)
debugGrid = activeWidget.NewGrid("tmp grid", 2, 3)
debugGridLabel = debugGrid.NewLabel("mirrors.wit.com")
// SetDebug(false)
DebugWidgetWindow(debugGrid)
})
gList.NewButton("Image", func () {
a := gShow.NewTextbox("image")
DebugWidgetWindow(a)
})
}
func DebugWidgetWindow(w *Node) {
var win, g *Node
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name
Config.Title = title
Config.Width = 300
Config.Height = 400
win = NewWindow()
win.Custom = w.StandardClose
g = win.NewGroup("Actions")
g.NewLabel(title)
g.NewButton("Dump()", func () {
w.Dump()
})
g.NewButton("Disable()", func () {
w.widget.Action = "Disable"
send(w.parent, w)
})
g.NewButton("Enable()", func () {
w.widget.Action = "Enable"
send(w.parent, w)
})
g.NewButton("Show()", func () {
w.widget.Action = "Show"
send(w.parent, w)
})
g.NewButton("Hide()", func () {
w.widget.Action = "Hide"
send(w.parent, w)
})
g.NewButton("Value()", func () {
log("w.B =", w.widget.B)
log("w.I =", w.widget.I)
log("w.S =", w.widget.S)
})
g.NewButton("Set Value(20)", func () {
w.widget.Action = "Set"
w.widget.B = true
w.widget.I = 20
w.widget.S = "Set Value(20)"
send(w.parent, w)
})
g.NewButton("Add('foo')", func () {
w.widget.Action = "Add"
w.widget.S = "foo"
send(w.parent, w)
})
g.NewButton("Delete('foo')", func () {
w.widget.Action = "Delete"
w.widget.S = "foo"
send(w.parent, w)
})
g.NewButton("SetMargin(true)", func () {
w.widget.Action = "SetMargin"
w.widget.B = true
send(w.parent, w)
})
g.NewButton("SetMargin(false)", func () {
w.widget.Action = "SetMargin"
w.widget.B = false
send(w.parent, w)
})
g.NewButton("Add button to (1,1)", func () {
w.widget.Action = "AddGrid"
w.widget.B = false
send(w.parent, w)
})
g.NewButton("Delete()", func () {
Delete(w)
n.NewButton("Image", func () {
activeWidget.NewImage("image")
})
n.NewButton("Tab", func () {
activeWidget.NewTab("myTab")
})
n.NewButton("Group", func () {
a := activeWidget.NewGroup("myGroup")
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
})
n.NewButton("Box(horizontal)", func () {
a := activeWidget.NewBox("hBox", true)
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
})
n.NewButton("Box(vertical)", func () {
a := activeWidget.NewBox("vBox", true)
a.Custom = func () {
log("this code is more better", a.widget.B, "id=", a.id)
}
})
}

View File

@ -1,7 +1,19 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
// TODO: move all this shit into somewhere not global
// main debugging window
var bugWin *Node
// if there should be new windows or just tabs
var makeTabs bool = true
var mapWindows map[string]*Node
var checkd, checkdn, checkdt, checkdtk, lb1, lb2 *Node
var myButton *Node
/*
Creates a window helpful for debugging this package
@ -15,120 +27,122 @@ func DebugWindow() {
bugWin.DebugTab("Debug Tab")
}
var checkd, checkdn, checkdt, checkdtk, lb1, lb2 *Node
var myButton *Node
func (n *Node) DebugTab(title string) *Node {
var newN, gog, g1, g2, g3, dd *Node
var newN, gog, g1 *Node
// time.Sleep(1 * time.Second)
newN = n.NewTab(title)
newN.Dump()
//////////////////////// main debug things //////////////////////////////////
gog = newN.NewGroup("Debugging")
gog = newN.NewGroup("Debugging Windows:")
// generally useful debugging
cb := gog.NewCheckbox("Seperate windows")
cb.Custom = func() {
makeTabs = cb.widget.B
log(debugGui, "Custom() n.widget =", cb.widget.Name, cb.widget.B)
}
makeTabs = false
cb.Set(false)
gog.NewButton("Debug Flags", func () {
newN.debugFlags(false)
newN.DebugFlags(makeTabs)
})
gog.NewButton("Debug Widgets", func () {
newN.debugWidgets(false)
DebugWidgetWindow(newN)
})
gog.NewButton("GO Language Internals", func () {
newN.debugGolangWindow(false)
newN.DebugGolangWindow(makeTabs)
})
gog.NewButton("GO Channels debug", func () {
newN.debugGoChannels(false)
newN.DebugGoChannels(makeTabs)
})
//////////////////////// window debugging things //////////////////////////////////
g1 = newN.NewGroup("Current Windows")
dd = g1.NewDropdown("Window Dropdown")
dd.Custom = func() {
name := dd.widget.S
bugWin = mapWindows[name]
log("The Window was set to", name)
}
log(debugGui, "dd =", dd)
gog.NewLabel("Force Quit:")
// initialize the windows map if it hasn't been
if (mapWindows == nil) {
mapWindows = make(map[string]*Node)
}
var dump = false
var last = ""
for _, child := range Config.master.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
if (child.parent != nil) {
log(debugGui, "\t\t\tparent =",child.parent.id)
} else {
log(debugGui, "\t\t\tno parent")
panic("no parent")
}
if (dump == true) {
child.Dump()
}
dd.AddDropdownName(child.Name)
last = child.Name
mapWindows[child.Name] = child
}
dd.SetDropdownName(last)
g2 = newN.NewGroup("Debug Window")
g2.NewButton("SetMargined(tab)", func () {
log(debugChange, "START SetMargined(tab)", g2.Name)
// name := dd.GetText()
name := dd.widget.S
log(true, "name =", name)
log(debugChange, "name =", name)
log(debugChange, "mapWindows[name] =", mapWindows[name])
/*
for s, n := range mapWindows {
log(debugChange, "\tname =", name)
log(debugChange, "\tmapWindows s =", s)
log(debugChange, "\tmapWindows[s] =", n)
}
*/
bugWin = mapWindows[name]
log(debugChange, "END dd.widget.S =", dd.widget.S)
// gw.UiTab.SetMargined(*gw.TabNumber, true)
})
g2.NewButton("Hide(tab)", func () {
log(debugChange, "\tclick() START", g2.Name)
// gw.UiTab.Hide()
})
g2.NewButton("Show(tab)", func () {
// gw.UiTab.Show()
})
g2.NewButton("Delete(tab)", func () {
// gw.UiTab.Delete(*gw.TabNumber)
})
g2.NewButton("change Title", func () {
// mainWindow.SetText("hello world")
})
g2.NewButton("Quit", func () {
gog.NewButton("os.Exit()", func () {
exit()
})
/////////////////////////////////////////////////////
g3 = newN.NewGroup("Node Debug")
//////////////////////// window debugging things //////////////////////////////////
g1 = newN.NewGroup("list things")
g3.NewButton("Node.Dump()", func () {
debugGui = true
debugDump = true
bugWin.Dump()
g1.NewButton("List Windows", func () {
dropdownWindow(g1)
})
g3.NewButton("Node.ListChildren(false)", func () {
debugGui = true
debugDump = true
bugWin.ListChildren(false)
g1.NewButton("List Window Widgets", func () {
dropdownWindowWidgets(g1)
})
g3.NewButton("Node.ListChildren(true)", func () {
g2 := newN.NewGroup("node things")
g2.NewButton("Actions Window", func () {
DebugWidgetWindow(activeWidget)
})
g2.NewButton("Node.ListChildren(false)", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
bugWin.ListChildren(true)
activeWidget.ListChildren(false, nil, nil)
debugGui = g
debugDump = d
})
g2.NewButton("Node.ListChildren(true)", func () {
g := debugGui
d := debugDump
debugGui = true
debugDump = true
activeWidget.ListChildren(true, nil, nil)
debugGui = g
debugDump = d
})
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.widget.S
activeWidget = mapWindows[name]
setActiveWidget(activeWidget)
log("The Window was set to", name)
}
log(debugGui, "dd =", dd)
// var last = ""
for _, child := range Config.master.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
// skip the fake "Flag" node
if (child.widget.Type == toolkit.Flag) {
continue
}
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.widget.S
activeWidget = mapWindows[name]
setActiveWidget(activeWidget)
}
log(debugGui, "dd =", dd)
activeWidget.ListChildren(true, dd, mapWindows)
}

View File

@ -1,5 +1,10 @@
package gui
// functions to create 'Dropdown' and 'Combobox'
// Combobox is a Dropdown you can edit
// Thererfore, AddDropdownName() is used on both combobox and dropdown nodes
// since it is the same. confusing names? maybe...
import (
"git.wit.org/wit/gui/toolkit"
)

14
go.mod
View File

@ -3,7 +3,21 @@ module git.wit.org/wit/gui
go 1.17
require (
github.com/alexflint/go-arg v1.4.3
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e
github.com/awesome-gocui/gocui v1.1.0
github.com/davecgh/go-spew v1.1.1
golang.org/x/image v0.0.0-20221017200508-ffcb3fe7d1bf
)
require (
github.com/alexflint/go-scalar v1.2.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.6.0 // indirect
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/rivo/uniseg v0.4.4 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/term v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
)

37
go.sum
View File

@ -1,7 +1,35 @@
github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/uo=
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/alexflint/go-scalar v1.2.0 h1:WR7JPKkeNpnYIOfHRa7ivM21aWAdHD0gEWHCx+WQBRw=
github.com/alexflint/go-scalar v1.2.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e h1:wSQCJiig/QkoUnpvelSPbLiZNWvh2yMqQTQvIQqSUkU=
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e/go.mod h1:5G2EjwzgZUPnnReoKvPWVneT8APYbyKkihDVAHUi0II=
github.com/awesome-gocui/gocui v1.1.0 h1:db2j7yFEoHZjpQFeE2xqiatS8bm1lO3THeLwE6MzOII=
github.com/awesome-gocui/gocui v1.1.0/go.mod h1:M2BXkrp7PR97CKnPRT7Rk0+rtswChPtksw/vRAESGpg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
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/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
github.com/gdamore/tcell/v2 v2.6.0 h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=
github.com/gdamore/tcell/v2 v2.6.0/go.mod h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis=
github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@ -22,14 +50,23 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

21
grid.go
View File

@ -14,3 +14,24 @@ func (n *Node) NewGrid(name string, x int, y int) *Node {
send(n, newNode)
return newNode
}
// a box is just a grid with a single set of widgets that are either horizontal or vertical
func (n *Node) NewBox(name string, horizontal bool) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Box, nil)
newNode.widget.X = 3
newNode.widget.Y = 1
newNode.widget.B = horizontal
send(n, newNode)
return newNode
}
func (n *Node) AddGrid(a *Node, x int, y int) {
n.widget.X = x
n.widget.Y = y
a.widget.Action = "AddGrid"
send(n, a)
}

View File

@ -4,8 +4,7 @@ import (
"git.wit.org/wit/gui/toolkit"
)
// TODO: which name is better. AddGroup or NewGroup ?
// first reaction is NewGroup
// TODO: treat a "Group" like a "Grid"
func (n *Node) NewGroup(name string) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Group, nil)

12
image.go Normal file
View File

@ -0,0 +1,12 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
func (n *Node) NewImage(name string) *Node {
var newNode *Node
newNode = n.New(name, toolkit.Image, nil)
send(n, newNode)
return newNode
}

18
main.go
View File

@ -1,7 +1,7 @@
package gui
import (
"embed"
// "embed"
"git.wit.org/wit/gui/toolkit"
)
@ -12,9 +12,15 @@ import (
const Xaxis = 0 // stack things horizontally
const Yaxis = 1 // stack things vertically
// may this plugin work when all other plugins fail
//go:embed toolkit/gocui.so
var res embed.FS
/*
// TODO: 2023/03/03 rethink how to get a plugin or figure out how
// golang packages can include a binary. Pull from /usr/go/go-gui/ ?
// may this plugin work when all other plugins fail
// if this is in the plugin, the packages can't work with go.mod builds
# don't do this in the plugin // go:embed /usr/lib/go-gui/toolkit/gocui.so
# don't do this in the plugin var res embed.FS
*/
func init() {
log("init() has been run")
@ -136,7 +142,8 @@ func (n *Node) StandardClose() {
log(debugGui, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
}
// The window is destroyed but the application does not quit
// The window is destroyed and the application exits
// TODO: properly exit the plugin since Quit() doesn't do it
func StandardExit() {
log("wit/gui Standard Window Exit. running os.Exit()")
log("gui.Node.StandardExit() attempt to exit each toolkit plugin")
@ -146,6 +153,5 @@ func StandardExit() {
aplug.Quit()
}
}
exit(0)
}

41
node.go
View File

@ -16,6 +16,12 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
// TODO: This should not be defined for each widget. This has to be stupid
// or wait a second, is this where I send something to a channel?
newN.widget.Custom = func() {
log(debugChange, "Trying to find Window Close. widget.Action =", newN.widget.Action)
log(debugChange, "Trying to find Window Close. widget.Type =", newN.widget.Type)
if (newN.widget.Type == toolkit.Window) {
log(debugChange, "Need to delete newN here")
n.Delete(newN)
}
if (newN.Custom == nil) {
log(debugChange, "newT.Custom() == nil. Not doing anything. SEND SOMETHING TO THE CHANNEL")
return
@ -38,9 +44,40 @@ func addNode(title string) *Node {
n := new(Node)
n.Name = title
n.widget.Name = title
n.id = Config.counter
Config.counter += 1
n.widget.SetId(n.id)
log(debugNode, "addNode = widget setid =", n.id)
Config.counter += 1
return n
}
func (n *Node) Parent() *Node {
return n.parent
}
func (n *Node) Window() *Node {
return n.parent
}
func (n *Node) Append(child *Node) {
n.children = append(n.children, child)
if (debugNode) {
log(debugNode, "child node:")
child.Dump()
log(debugNode, "parent node:")
n.Dump()
}
}
func (n *Node) Delete(d *Node) {
for i, child := range n.children {
log(debugNode, "\t", i, child.id, child.Width, child.Height, child.Name)
if (child.id == d.id) {
log(debugNode, "\t\t Deleting this")
n.children = append(n.children[:i], n.children[i+1:]...)
return
}
}
log(debugError, "did not find node to delete", d.id, d.Width, d.Height, d.Name)
}

View File

@ -205,7 +205,7 @@ func loadfile(filename string) *plugin.Plugin {
// parent = n, child = c
func send(p *Node, c *Node) {
for _, aplug := range allPlugins {
log(debugPlugin, "Send() aplug =", aplug.name, "name =", c.widget.Name)
log(debugPlugin, "Send() aplug =", aplug.name, "type=", c.widget.Type, "action=", c.widget.Action, "name=", c.widget.Name)
if (aplug.Send == nil) {
log(debugPlugin, "\tSend() failed (aplug.Selete = nil) for", aplug.name)
continue

View File

@ -75,21 +75,3 @@ type Node struct {
// checked bool
// text string
}
func (n *Node) Parent() *Node {
return n.parent
}
func (n *Node) Window() *Node {
return n.parent
}
func (n *Node) Append(child *Node) {
n.children = append(n.children, child)
if (debugGui) {
log(debugNode, "child node:")
child.Dump()
log(debugNode, "parent node:")
n.Dump()
}
}

View File

@ -7,12 +7,10 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
// make new Group here
func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
if (newt.tw != nil) {
if (newt.tw.Type == toolkit.Grid) {
log(true, "doAppend() going to attempt uiGrid")
// move all the append code here
func (t *andlabsT) doAppend(kind toolkit.WidgetType, newt *andlabsT, c *ui.Control) {
if (kind == toolkit.Grid) {
log(debugToolkit, "doAppend() attempt to append a ui.Control into a uiGrid")
// hack to add shit to a grid
button1 := ui.NewButton("a(0,2)")
newt.uiGrid.Append(button1,
@ -24,7 +22,7 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
false, ui.AlignFill, false, ui.AlignFill)
if (t.uiBox != nil) {
log(true, "doAppend() on uiGrid to a uiBox")
log(debugToolkit, "doAppend() on uiGrid to a uiBox")
if (newt.Name == "output") {
t.uiBox.Append(newt.uiGrid, true)
} else {
@ -32,16 +30,12 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
}
return
}
log(true, "doAppend() on uiGrid failed")
log(debugToolkit, "doAppend() on uiGrid failed")
return
}
} else {
log(true, "doAppend() newt.tw == nil ERROR on newt.Name =", newt.Name)
}
// hack to pass a group
if (c == nil) {
log(true, "attempting to doAppend() on a uiGroup")
if (kind == toolkit.Group) {
log(debugToolkit, "doAppend() attempt a uiGroup")
if (t.uiBox != nil) {
if (newt.Name == "output") {
t.uiBox.Append(newt.uiGroup, true)
@ -52,20 +46,19 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
}
if (t.uiWindow != nil) {
log(true, "This is a raw window without a box. probably make a box here and add the group to that")
t.Dump(true)
newt.Dump(true)
log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that")
newt.Dump(debugToolkit)
t.uiBox = ui.NewHorizontalBox()
t.uiWindow.SetChild(t.uiBox)
log(true, "tried to make a box", t.uiBox)
log(debugToolkit, "tried to make a box", t.uiBox)
if (newt.Name == "output") {
log(true, "tried to t.uiBox.Append(*c, true)")
log(debugToolkit, "tried to t.uiBox.Append(*c, true)")
if (t.uiBox == nil) {
log(true, "tried to t.uiBox.Append(*c, true)")
log(debugToolkit, "tried to t.uiBox.Append(*c, true)")
}
t.uiBox.Append(newt.uiGroup, true)
} else {
log(true, "tried to t.uiBox.Append(*c, stretchy)")
log(debugToolkit, "tried to t.uiBox.Append(*c, stretchy)")
t.uiBox.Append(newt.uiGroup, stretchy)
}
return
@ -75,7 +68,13 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
if (t.uiBox != nil) {
if (kind == toolkit.Textbox) {
if (t.uiBox == nil) {
log(debugError, "NewTextbox() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
// TODO: temporary hack to make the output textbox 'fullscreen'
if (newt.Name == "output") {
t.uiBox.Append(*c, true)
@ -84,11 +83,12 @@ func (t *andlabsT) doAppend(newt *andlabsT, c *ui.Control) {
}
return
}
if (t.uiWindow != nil) {
log(true, "This is a raw window without a box. probably make a box here and add the group to that")
log(debugToolkit, "This is a raw window without a box. probably make a box here and add the group to that")
t.uiBox = ui.NewHorizontalBox()
t.uiWindow.SetChild(t.uiBox)
log(true, "tried to make a box")
log(debugToolkit, "tried to make a box")
if (newt.Name == "output") {
t.uiBox.Append(*c, true)
} else {

View File

@ -10,11 +10,11 @@ import (
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
var t, newt *andlabsT
var b *ui.Button
log(debugToolkit, "gui.andlabs.NewButton()", w.Name)
log(debugToolkit, "newButton()", w.Name)
t = mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewButton() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newButton() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
@ -32,22 +32,32 @@ func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
newt.commonChange(newt.tw)
})
log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box parent t:", w.Name)
log(debugToolkit, "gui.Toolbox.NewButton() about to append to Box new t:", w.Name)
log(debugToolkit, "newButton() about to append to Box parent t:", w.Name)
log(debugToolkit, "newButton() about to append to Box new t:", w.Name)
if (debugToolkit) {
ShowDebug ()
}
if (t.uiBox != nil) {
t.uiBox.Append(b, stretchy)
} else if (t.uiWindow != nil) {
t.uiWindow.SetChild(b)
} else {
log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
log(debugToolkit, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
log(debugError, "ERROR: wit/gui andlabs couldn't place this button in a box or a window")
return
}
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doButton(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
@ -58,18 +68,18 @@ func doButton(p *toolkit.Widget, c *toolkit.Widget) {
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Button() ct.broken", ct)
log(debugError, "Button() ct.broken", ct)
return
}
if (ct.uiButton == nil) {
log(true, "Button() uiButton == nil", ct)
log(debugError, "Button() uiButton == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
log(debugToolkit, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiButton.Enable()
@ -82,6 +92,6 @@ func doButton(p *toolkit.Widget, c *toolkit.Widget) {
case "Set":
ct.uiButton.SetText(c.S)
default:
log(true, "Can't do", c.Action, "to a Button")
log(debugError, "Can't do", c.Action, "to a Button")
}
}

View File

@ -70,7 +70,7 @@ func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "checkbox() uiCheckbox == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiCheckbox.Enable()
@ -80,10 +80,11 @@ func doCheckbox(p *toolkit.Widget, c *toolkit.Widget) {
ct.uiCheckbox.Show()
case "Hide":
ct.uiCheckbox.Hide()
case "Set":
case "SetText":
ct.uiCheckbox.SetText(c.S)
case "Set":
ct.uiCheckbox.SetChecked(c.B)
default:
log(true, "Can't do", c.Action, "to a checkbox")
log(debugError, "Can't do", c.Action, "to a checkbox")
}
}

View File

@ -80,7 +80,7 @@ func doCombobox(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "Combobox() uiEditableCombobox == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Add":
ct.AddComboboxName(c.S)
@ -95,6 +95,6 @@ func doCombobox(p *toolkit.Widget, c *toolkit.Widget) {
case "Set":
ct.uiEditableCombobox.SetText(c.S)
default:
log(true, "Can't do", c.Action, "to a Combobox")
log(debugError, "Can't do", c.Action, "to a Combobox")
}
}

View File

@ -2,16 +2,9 @@ package main
import (
"git.wit.org/wit/gui/toolkit"
"github.com/davecgh/go-spew/spew"
// "github.com/davecgh/go-spew/spew"
)
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func init() {
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
// log(debugToolkit, "gui/toolkit init() Setting defaultBehavior = true")
setDefaultBehavior(true)
}
func (t *andlabsT) commonChange(tw *toolkit.Widget) {
log(debugChange, "commonChange() START widget =", t.Name, t.Type)
if (tw == nil) {
@ -30,6 +23,7 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget) {
// TODO: probably this should not panic unless it's running in devel mode (?)
// TODO: redo this now that WidgetType is used and send() is used to package plugins
func (t *andlabsT) broken() bool {
/*
if (t.parent != nil) {
return false
}
@ -52,6 +46,7 @@ func (t *andlabsT) broken() bool {
t.Dump(debugToolkit)
return false
}
*/
return false
}
func broken(w *toolkit.Widget) bool {
@ -79,123 +74,3 @@ func dump(p *toolkit.Widget, c *toolkit.Widget, b bool) {
}
ct.Dump(b)
}
func setMarginNew(w *toolkit.Widget, b bool) {
wt := mapToolkits[w]
log(true, "START setMarginNew", w.Name)
if (wt == nil) {
return
}
if (wt.uiGroup != nil) {
log(true, "uiGroup.SetMargined(true)")
wt.uiGroup.SetMargined(b)
}
if (wt.uiTab != nil) {
i := wt.uiTab.NumPages()
log(true, "tab.NumPages() =", i)
for i > 0 {
i -= 1
log(true, "uiTab.SetMargined(true) for i =", i)
wt.uiTab.SetMargined(i, b)
}
} else {
log(true, "no uitab")
}
if (wt.uiWindow != nil) {
log(true, "uiWindow.SetMargined(true)")
wt.uiWindow.SetMargined(b)
}
log(true, "END setMarginNew", w.Name)
}
func setMargin(p *toolkit.Widget, c *toolkit.Widget, b bool) {
log(true, "Starting to implement SetMargin here")
dump(p, c, true)
setMarginNew(c, b)
setMarginNew(p, b)
}
func (t *andlabsT) String() string {
return t.GetText()
}
func (t *andlabsT) GetText() string {
log(debugToolkit, "GetText() Enter debugToolkit=", debugToolkit)
if (t.uiEntry != nil) {
log(debugToolkit, "uiEntry.Text() =", t.uiEntry.Text())
return t.uiEntry.Text()
}
if (t.uiMultilineEntry != nil) {
log(debugToolkit, "uiMultilineEntry.Text() =", t.uiMultilineEntry.Text())
text := t.uiMultilineEntry.Text()
log(debugToolkit, "uiMultilineEntry.Text() =", text)
t.text = text
return text
}
if (t.uiCombobox != nil) {
log(debugToolkit, "uiCombobox() =", t.text)
return t.text
}
return ""
}
func (t *andlabsT) SetText(s string) bool {
log(debugToolkit, "Text() SetText() Enter")
if (t.uiEntry != nil) {
log(debugToolkit, "Value() =", t.uiEntry.Text)
t.uiEntry.SetText(s)
return true
}
if (t.uiMultilineEntry != nil) {
log(debugToolkit, "Value() =", t.uiMultilineEntry.Text)
t.uiMultilineEntry.SetText(s)
return true
}
return false
}
func sanity(t *andlabsT) bool {
if (debugToolkit) {
log(debugToolkit, "Value() Enter")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t.uiEntry == nil) {
log(debugToolkit, "Value() =", t.uiEntry.Text)
return false
}
return true
}
func (t *andlabsT) SetValue(i int) bool {
log(debugToolkit, "SetValue() START")
if (sanity(t)) {
return false
}
t.Dump(debugToolkit)
// panic("got to toolkit.SetValue")
return true
}
func (t *andlabsT) Value() int {
if (debugToolkit) {
log(debugToolkit, "Value() Enter")
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(t)
}
if (t == nil) {
log(debugToolkit, "Value() can not get value t == nil")
return 0
}
if (t.uiSlider != nil) {
log(debugToolkit, "Value() =", t.uiSlider.Value)
return t.uiSlider.Value()
}
if (t.uiSpinbox != nil) {
log(debugToolkit, "Value() =", t.uiSpinbox.Value)
return t.uiSpinbox.Value()
}
log(debugToolkit, "Value() Could not find a ui element to get a value from")
return 0
}

View File

@ -2,8 +2,6 @@ package main
import "git.wit.org/wit/gui/toolkit"
// import "github.com/davecgh/go-spew/spew"
var defaultBehavior bool = true
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
@ -16,9 +14,8 @@ var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugFlag bool
var debugFlags bool
var debugError bool = true
// var DebugToolkit bool
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func setDefaultBehavior(s bool) {
@ -37,24 +34,12 @@ func setDefaultBehavior(s bool) {
}
}
/*
func SetDebugToolkit (s bool) {
debugToolkit = s
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
}
func SetDebugChange (s bool) {
debugChange = s
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
}
*/
func ShowDebug () {
log(true, "debugToolkit =", debugToolkit)
log(true, "debugError =", debugError)
log(true, "debugChange =", debugChange)
log(true, "debugPlugin =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugError =", debugError)
}
func (t *andlabsT) Dump(b bool) {

56
toolkit/andlabs/delete.go Normal file
View File

@ -0,0 +1,56 @@
package main
// if you include more than just this import
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
import "git.wit.org/wit/gui/toolkit"
// delete the child widget from the parent
// p = parent, c = child
func destroy(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "delete()", c.Name, c.Type)
pt := mapToolkits[p]
ct := mapToolkits[c]
if (ct == nil) {
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type)
// this pukes out a whole universe of shit
// listMap()
return
}
switch ct.Type {
case toolkit.Button:
log(true, "Should delete Button here:", c.Name)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
if (pt.uiBox == nil) {
log(true, "Don't know how to destroy this")
} else {
log(true, "Fuck it, destroy the whole box", pt.Name)
// pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent.
pt.uiBox.SetPadded(false)
pt.uiBox.Delete(4)
ct.uiButton.Disable()
// ct.uiButton.Hide()
ct.uiButton.Destroy()
}
case toolkit.Window:
log(true, "Should delete Window here:", c.Name)
default:
log(true, "Don't know how to delete c =", c.Type, c.Name)
log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
log(true, "Fuckit, let's destroy a button", c.Name, c.Type)
if (ct.uiButton != nil) {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()
}
}
}

View File

@ -48,7 +48,7 @@ func (t *andlabsT) AddDropdownName(title string) {
// If this is the first menu added, set the dropdown to it
if (t.c == 0) {
log(debugChange, "THIS IS THE FIRST Dropdown", title)
t.uiCombobox.SetSelected(1)
t.uiCombobox.SetSelected(0)
}
t.c = t.c + 1
}
@ -105,18 +105,18 @@ func doDropdown(p *toolkit.Widget, c *toolkit.Widget) {
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Dropdown() ct.broken", ct)
log(debugError, "Dropdown() ct.broken", ct)
return
}
if (ct.uiCombobox == nil) {
log(true, "Dropdown() uiCombobox == nil", ct)
log(debugError, "Dropdown() uiCombobox == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Add":
ct.AddDropdownName(c.S)
@ -131,7 +131,29 @@ func doDropdown(p *toolkit.Widget, c *toolkit.Widget) {
ct.uiCombobox.Hide()
case "Set":
ct.uiCombobox.SetSelected(1)
case "SetText":
var orig int
var i int = -1
var s string
orig = ct.uiCombobox.Selected()
log(debugError, "TODO: set a Dropdown by the name selected =", orig, ct.c, c.S)
// try to find the string
for i, s = range ct.val {
log(debugError, "i, s", i, s)
if (c.S == s) {
ct.uiCombobox.SetSelected(i)
return
}
}
// if i == -1, then there are not any things in the menu to select
if (i == -1) {
return
}
// if the string was never set, then set the dropdown to the last thing added to the menu
if (orig == -1) {
ct.uiCombobox.SetSelected(i)
}
default:
log(true, "Can't do", c.Action, "to a Dropdown")
log(debugError, "Can't do", c.Action, "to a Dropdown")
}
}

View File

@ -36,29 +36,7 @@ func newGrid(parentW *toolkit.Widget, w *toolkit.Widget) {
newt.uiGrid = c
newt.uiBox = t.uiBox
newt.tw = w
t.doAppend(newt, nil)
/*
if (defaultBehavior) {
t.uiBox.Append(c, stretchy)
}
button1 := ui.NewButton("a(0,0)")
c.Append(button1,
0, 0, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
button2 := ui.NewButton("a(1,0)")
c.Append(button2,
1, 0, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
*/
// Append(child Control,
// left, top int,
// xspan, yspan int,
// hexpand bool, halign Align,
// vexpand bool, valign Align) {
t.doAppend(toolkit.Grid, newt, nil)
mapWidgetsToolkits(w, newt)
}
@ -72,19 +50,18 @@ func doGrid(p *toolkit.Widget, c *toolkit.Widget) {
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Grid() ct.broken", ct)
log(debugError, "Grid() ct.broken", ct)
return
}
if (ct.uiGrid == nil) {
log(true, "Grid() uiGrid == nil", ct)
log(debugError, "Grid() uiGrid == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiGrid.Enable()
@ -93,10 +70,22 @@ func doGrid(p *toolkit.Widget, c *toolkit.Widget) {
case "Show":
ct.uiGrid.Show()
case "Hide":
log(debugError, "trying Hide on grid")
ct.uiGrid.Hide()
case "SetMargin":
log(debugError, "trying SetMargin on grid")
ct.uiGrid.SetPadded(c.B)
case "Set":
log(true, "Can I use 'Set' to place a *Node in a Grid?")
log(debugError, "Can I use 'Set' to place a *Node in a Grid?")
/*
case "AddGrid":
log(true, "how do I add a thing to a grid?")
dump(p, c, true)
newt.uiGrid.Append(button1,
0, 2, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
*/
default:
log(true, "Can't do", c.Action, "to a Grid")
log(debugError, "Can't do", c.Action, "to a Grid")
}
}

View File

@ -8,8 +8,7 @@ import (
)
func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
// log(debugToolkit, "gui.andlabs.NewGroup()", w.Name)
log(true, "NewGroup()", w.Name)
log(debugToolkit, "NewGroup()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
@ -31,31 +30,7 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
g.SetMargined(margin)
newt.uiGroup = g
t.doAppend(&newt, nil)
/*
if (t.uiBox != nil) {
// TODO: temporary hack to make the output textbox 'fullscreen'
if (newt.Name == "output") {
t.uiBox.Append(g, true)
} else {
t.uiBox.Append(g, stretchy)
}
} else if (t.uiWindow != nil) {
log(true, "This is a raw window without a box. probably make a box here and add the group to that")
t.uiBox = ui.NewHorizontalBox()
t.uiWindow.SetChild(t.uiBox)
log(true, "tried to make a box")
if (newt.Name == "output") {
t.uiBox.Append(g, true)
} else {
t.uiBox.Append(g, stretchy)
}
} else {
log(debugError, "NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
log(debugError, "probably could just make a box here?")
exit("internal wit/gui error")
}
*/
t.doAppend(toolkit.Group, &newt, nil)
hbox := ui.NewVerticalBox()
hbox.SetPadded(padded)
@ -67,3 +42,56 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
return &newt
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doGroup(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newGroup(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Group() ct.broken", ct)
return
}
if (ct.uiGroup == nil) {
log(debugError, "Label() uiGroup == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiGroup.Enable()
case "Disable":
ct.uiGroup.Disable()
case "Show":
ct.uiGroup.Show()
case "Hide":
ct.uiGroup.Hide()
case "Get":
c.S = ct.uiGroup.Title()
case "Set":
ct.uiGroup.SetTitle(c.S)
case "SetText":
ct.uiGroup.SetTitle(c.S)
case "SetMargin":
ct.uiGroup.SetMargined(c.B)
case "Destroy":
ct.uiGroup.Destroy()
default:
log(debugError, "Can't do", c.Action, "to a Group")
}
}

View File

@ -39,29 +39,36 @@ func newLabel(parentW *toolkit.Widget, w *toolkit.Widget) {
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doLabel(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newLabel(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Label() ct.broken", ct)
log(debugError, "Label() ct.broken", ct)
return
}
if (ct.uiLabel == nil) {
log(true, "Label() uiLabel == nil", ct)
log(debugError, "Label() uiLabel == nil", ct)
return
}
log(true, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiLabel.Enable()
@ -71,9 +78,11 @@ func doLabel(p *toolkit.Widget, c *toolkit.Widget) {
ct.uiLabel.Show()
case "Hide":
ct.uiLabel.Hide()
case "SetText":
ct.uiLabel.SetText(c.S)
case "Set":
ct.uiLabel.SetText(c.S)
default:
log(true, "Can't do", c.Action, "to a Label")
log(debugError, "Can't do", c.Action, "to a Label")
}
}

View File

@ -103,12 +103,12 @@ func log(a ...any) {
if (a[0] == false) {
return
}
a[0] = "WIT/GUI/Toolkit"
a[0] = "GUI/Toolkit/Andlabs"
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
// a = a[1:]
a[0] = "WIT/GUI/Toolkit"
a[0] = "GUI/Toolkit/Andlabs"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)

View File

@ -15,11 +15,6 @@ var res embed.FS
func Main(f func()) {
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
ui.Main( func() {
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
log(debugToolkit, "Starting gui.Main() (using gtk via andlabs/ui)")
// time.Sleep(1 * time.Second)
// NewWindow2("helloworld2", 200, 100)
@ -37,17 +32,22 @@ func Main(f func()) {
//
func Queue(f func()) {
log(debugToolkit, "Sending function to ui.QueueMain()")
log(true, "using gui.Queue() in this plugin DOES BREAK. TODO: wrap this")
log(debugPlugin, "using gui.Queue() in this plugin DOES BREAK. TODO: solve this with channels")
ui.QueueMain(f)
}
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func Init() {
log(debugToolkit, "Init()")
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
// log(debugToolkit, "gui/toolkit init() Setting defaultBehavior = true")
setDefaultBehavior(true)
mapWidgets = make(map[*andlabsT]*toolkit.Widget)
mapToolkits = make(map[*toolkit.Widget]*andlabsT)
}
// TODO: properly exit the plugin since Quit() doesn't do it
func Quit() {
log(debugToolkit, "Quit() TODO: close the toolkit cleanly")
}

View File

@ -26,31 +26,33 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
/*
if (c.Action == "SetMargin") {
log(true, "need to implement SetMargin here")
setMargin(p, c, c.B)
log(debugError, "need to implement SetMargin here")
setMargin(c, c.B)
return
}
*/
switch c.Type {
case toolkit.Window:
newWindow(c)
doWindow(c)
case toolkit.Tab:
newTab(p, c)
doTab(p, c)
case toolkit.Group:
newGroup(p, c)
doGroup(p, c)
case toolkit.Button:
doButton(p, c)
case toolkit.Checkbox:
doCheckbox(p, c)
case toolkit.Label:
newLabel(p, c)
doLabel(p, c)
case toolkit.Textbox:
doTextbox(p, c)
case toolkit.Slider:
newSlider(p, c)
doSlider(p, c)
case toolkit.Spinner:
newSpinner(p, c)
doSpinner(p, c)
case toolkit.Dropdown:
doDropdown(p, c)
case toolkit.Combobox:
@ -58,79 +60,32 @@ func Send(p *toolkit.Widget, c *toolkit.Widget) {
case toolkit.Grid:
doGrid(p, c)
case toolkit.Flag:
log(debugFlag, "plugin Send() flag parent =", p.Name, p.Type)
log(debugFlag, "plugin Send() flag child =", c.Name, c.Type)
log(debugFlag, "plugin Send() flag child.Action =", c.Action)
log(debugFlag, "plugin Send() flag child.S =", c.S)
log(debugFlag, "plugin Send() flag child.B =", c.B)
log(debugFlag, "plugin Send() what to flag?")
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch c.S {
case "Error":
debugError = c.B
case "Toolkit":
debugToolkit = c.B
case "Change":
debugChange = c.B
case "Plugin":
debugPlugin = c.B
case "Flags":
debugFlags = c.B
case "Error":
debugError = c.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", c.S)
}
default:
log(true, "plugin Send() unknown parent =", p.Name, p.Type)
log(true, "plugin Send() unknown child =", c.Name, c.Type)
log(true, "plugin Send() Don't know how to do", c.Type, "yet")
}
}
// delete the child widget from the parent
// p = parent, c = child
func destroy(p *toolkit.Widget, c *toolkit.Widget) {
log(true, "delete()", c.Name, c.Type)
pt := mapToolkits[p]
ct := mapToolkits[c]
if (ct == nil) {
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type)
// this pukes out a whole universe of shit
// listMap()
return
}
switch ct.Type {
case toolkit.Button:
log(true, "Should delete Button here:", c.Name)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
if (pt.uiBox == nil) {
log(true, "Don't know how to destroy this")
} else {
log(true, "Fuck it, destroy the whole box", pt.Name)
// pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent.
pt.uiBox.SetPadded(false)
pt.uiBox.Delete(4)
ct.uiButton.Disable()
// ct.uiButton.Hide()
ct.uiButton.Destroy()
}
case toolkit.Window:
log(true, "Should delete Window here:", c.Name)
default:
log(true, "Don't know how to delete c =", c.Type, c.Name)
log(true, "Don't know how to delete pt =", pt.Type, pt.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.Type, ct.Name, ct.uiButton)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
log(true, "Fuckit, let's destroy a button", c.Name, c.Type)
if (ct.uiButton != nil) {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()
}
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet")
}
}

View File

@ -35,13 +35,60 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
func newSlider(parentW *toolkit.Widget, w *toolkit.Widget) {
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
log(debugToolkit, "newSlider()", w.Name)
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugError, "newSlider() ERROR toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
newt = t.newSlider(w)
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doSlider(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newSlider(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Slider() ct.broken", ct)
return
}
if (ct.uiSlider == nil) {
log(debugError, "Label() uiSlider == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiSlider.Enable()
case "Disable":
ct.uiSlider.Disable()
case "Show":
ct.uiSlider.Show()
case "Hide":
ct.uiSlider.Hide()
case "Set":
ct.uiSlider.SetValue(c.I)
case "Get":
c.I = ct.uiSlider.Value()
default:
log(debugError, "Can't do", c.Action, "to a Slider")
}
}

View File

@ -36,9 +36,56 @@ func newSpinner(parentW *toolkit.Widget, w *toolkit.Widget) {
t := mapToolkits[parentW]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name)
return
}
newt = t.newSpinner(w)
mapWidgetsToolkits(w, newt)
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
func doSpinner(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
log(debugChange, "Going to attempt:", c.Action)
if (c.Action == "New") {
newSpinner(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Spinner() ct.broken", ct)
return
}
if (ct.uiSpinbox == nil) {
log(debugError, "Label() uiSpinbox == nil", ct)
return
}
switch c.Action {
case "Enable":
ct.uiSpinbox.Enable()
case "Disable":
ct.uiSpinbox.Disable()
case "Show":
ct.uiSpinbox.Show()
case "Hide":
ct.uiSpinbox.Hide()
case "Set":
ct.uiSpinbox.SetValue(c.I)
case "Get":
c.I = ct.uiSpinbox.Value()
default:
log(debugError, "Can't do", c.Action, "to a Spinbox")
}
}

View File

@ -130,3 +130,53 @@ func newTab(parentW *toolkit.Widget, w *toolkit.Widget) {
newt = t.newTab(w.Name)
mapWidgetsToolkits(w, newt)
}
func doTab(p *toolkit.Widget, c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newTab(p, c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(debugError, "Tab() ct.broken", ct)
return
}
if (ct.uiTab == nil) {
log(debugError, "Tab() uiTab == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Enable":
ct.uiTab.Enable()
case "Disable":
ct.uiTab.Disable()
case "Show":
ct.uiTab.Show()
case "Hide":
ct.uiTab.Hide()
case "Get":
c.I = ct.uiTab.NumPages()
case "Add":
log(true, "how do I add a tab here in doTab()?")
dump(p, c, true)
case "SetMargin":
i := ct.uiTab.NumPages()
log(true, "tab.NumPages() =", i)
for i > 0 {
i -= 1
log(true, "uiTab.SetMargined(true) for i =", i)
ct.uiTab.SetMargined(i, c.B)
}
default:
log(debugError, "Can't do", c.Action, "to a Tab")
}
}

View File

@ -95,11 +95,11 @@ func doTextbox(p *toolkit.Widget, c *toolkit.Widget) {
}
ct := mapToolkits[c]
if (ct == nil) {
log(true, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if ct.broken() {
log(true, "Textbox() ct.broken", ct)
log(debugError, "Textbox() ct.broken", ct)
return
}
if (ct.uiMultilineEntry == nil) {
@ -124,7 +124,7 @@ func (t *andlabsT) doSimpleAction() {
} else if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.Enable()
} else {
log(true, "don't know what to enable", t.Name)
log(debugError, "don't know what to enable", t.Name)
}
case "Disable":
if (t.uiEntry != nil) {
@ -132,12 +132,14 @@ func (t *andlabsT) doSimpleAction() {
} else if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.Disable()
} else {
log(true, "don't know what to disable", t.Name)
log(debugError, "don't know what to disable", t.Name)
}
case "Show":
t.uiMultilineEntry.Show()
case "Hide":
t.uiMultilineEntry.Hide()
case "SetText":
t.uiMultilineEntry.SetText(t.tw.S)
case "Set":
t.uiMultilineEntry.SetText(t.tw.S)
default:

View File

@ -16,7 +16,7 @@ func listMap(b bool) {
for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name)
}
log(debugToolkit, "listMap() HERE mapToolkits()")
log(b, "listMap() HERE mapToolkits()")
for w, t := range mapToolkits {
log(b, "andlabs =", t, "widget =", w.Name)
t.Dump(b)
@ -40,12 +40,12 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
log(true, "mapToolkits[w] is set, but mapWidgets[t] is nil")
panic("WTF mapWidgets[t] == nil")
}
log(true, "mapToolkits[w] is", tw)
log(debugToolkit, "mapToolkits[w] is", tw)
if (tw == nil) {
log(true, "BAD map? mapWidgets[w] tw == nil")
log(debugError, "BAD map? mapWidgets[w] tw == nil")
} else {
log(true, "BAD map? mapWidgets[w] is", tw)
tw.Dump(true)
log(debugError, "BAD map? mapWidgets[w] is", tw)
tw.Dump(debugError)
}
}
@ -57,10 +57,10 @@ func mapWidgetsToolkits(w *toolkit.Widget, t *andlabsT) {
panic("WTF mapToolkits[w] == nil")
}
if (wt == nil) {
log(true, "BAD map? mapWidgets[t] wt == nil")
log(debugError, "BAD map? mapWidgets[t] wt == nil")
} else {
log(true, "BAD map? mapWidgets[t] is", wt)
widgetDump(true, wt)
log(debugError, "BAD map? mapWidgets[t] is", wt)
widgetDump(debugError, wt)
}
}
log(debugToolkit, "map of widget worked", w.Type, ",", w.Name, ",", w.Action)

View File

@ -53,3 +53,47 @@ func (t *andlabsT) SetWindowTitle(title string) {
log(debugToolkit, "Setting the window title", title)
}
}
func doWindow(c *toolkit.Widget) {
if broken(c) {
return
}
if (c.Action == "New") {
newWindow(c)
return
}
ct := mapToolkits[c]
if (ct == nil) {
log(debugError, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
if (ct.uiWindow == nil) {
log(debugError, "Window() uiWindow == nil", ct)
return
}
log(debugChange, "Going to attempt:", c.Action)
switch c.Action {
case "Show":
ct.uiWindow.Show()
case "Hide":
ct.uiWindow.Hide()
case "Enable":
ct.uiWindow.Enable()
case "Disable":
ct.uiWindow.Disable()
case "Get":
c.S = ct.uiWindow.Title()
case "Set":
ct.uiWindow.SetTitle(c.S)
case "SetText":
ct.uiWindow.SetTitle(c.S)
case "SetMargin":
ct.uiWindow.SetMargined(c.B)
case "SetBorder":
ct.uiWindow.SetBorderless(c.B)
case "Delete":
ct.uiWindow.Destroy()
default:
log(debugError, "Can't do", c.Action, "to a Window")
}
}

11
toolkit/democui/Makefile Normal file
View File

@ -0,0 +1,11 @@
all: plugin
ldd ../democui.so
build:
GO111MODULE="off" go build
plugin:
GO111MODULE="off" go build -buildmode=plugin -o ../democui.so
objdump:
objdump -t ../democui.so |less

107
toolkit/democui/debug.go Normal file
View File

@ -0,0 +1,107 @@
package main
import "git.wit.org/wit/gui/toolkit"
var defaultBehavior bool = true
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
var canvas bool // if set to true, the windows are a raw canvas
var menubar bool // for windows
var stretchy bool // expand things like buttons to the maximum size
var padded bool // add space between things like buttons
var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugFlags bool
var debugError bool = true
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func setDefaultBehavior(s bool) {
defaultBehavior = s
if (defaultBehavior) {
log(debugToolkit, "Setting this toolkit to use the default behavior.")
log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
stretchy = false
padded = true
menubar = true
margin = true
canvas = false
bookshelf = true // 99% of the time, things make a vertical stack of objects
} else {
log(debugToolkit, "This toolkit is set to ignore the default behavior.")
}
}
func ShowDebug () {
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
log(true, "debugPlugin =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugError =", debugError)
}
/*
func (t *gocuiT) Dump(b bool) {
if ! b {
return
}
log(b, "Name = ", t.Name, t.Width, t.Height)
if (t.uiBox != nil) {
log(b, "uiBox =", t.uiBox)
}
if (t.uiButton != nil) {
log(b, "uiButton =", t.uiButton)
}
if (t.uiCombobox != nil) {
log(b, "uiCombobox =", t.uiCombobox)
}
if (t.uiWindow != nil) {
log(b, "uiWindow =", t.uiWindow)
}
if (t.uiTab != nil) {
log(b, "uiTab =", t.uiTab)
}
if (t.uiGroup != nil) {
log(b, "uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log(b, "uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
}
if (t.uiSlider != nil) {
log(b, "uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log(b, "uiCheckbox =", t.uiCheckbox)
}
widgetDump(b, t.tw)
}
*/
func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) {
log(b, "widget = nil")
return
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)
log(b, "widget.I =", w.I)
log(b, "widget.Width =", w.Width)
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
}
/*
func GetDebugToolkit () bool {
return debugToolkit
}
*/

135
toolkit/democui/log.go Normal file
View File

@ -0,0 +1,135 @@
//
// version v1.3
//
// I like things to be easy.
//
// combining logging inside of a gui made me do this
//
// 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
// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
//
package main
import (
"os"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
)
var LOGOFF bool = false // turn this off, all logging stops
var WARN bool
var INFO bool
type spewt struct {
a bool
}
var SPEW spewt
/*
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(true, "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(true, "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] = "GUI/Toolkit/gocui"
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
// a = a[1:]
a[0] = "GUI/Toolkit/gocui"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
}
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(f *os.File) {
golog.SetOutput(f)
}

View File

@ -2,12 +2,11 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package toolkit
package main
import (
"errors"
"fmt"
"log"
"os"
"github.com/awesome-gocui/gocui"
@ -30,26 +29,26 @@ func mouseClick(name string) {
// log.Println("g.Close()")
// g.Close()
log.Println("Found andlabs Running custom function for the mouse click")
log("Found andlabs Running custom function for the mouse click")
Custom(name)
// panic("got andlabs")
}
func Init() {
log.Println("start Init()")
log("start Init()")
f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
exit("error opening file: %v", err)
}
defer f.Close()
log.SetOutput(f)
log.Println("This is a test log entry")
setOutput(f)
log("This is a test log entry")
g, err = gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
log.Panicln(err)
exit(err)
}
g.Cursor = true
@ -58,19 +57,19 @@ func Init() {
g.SetManagerFunc(layout)
if err := keybindings(g); err != nil {
log.Panicln(err)
exit(err)
}
log.Println("exit Init()")
log("exit Init()")
}
func StartConsoleMouse() {
defer g.Close()
log.Println("start Main()")
log("start Main()")
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
log.Panicln(err)
exit(err)
}
log.Println("exit Main()")
log("exit Main()")
}
func layout(g *gocui.Gui) error {

113
toolkit/democui/plugin.go Normal file
View File

@ -0,0 +1,113 @@
package main
import (
// if you include more than just this import
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
"git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
)
// This is a map between the widgets in wit/gui and the internal structures of gocui
var viewWidget map[*gocui.View]*toolkit.Widget
var stringWidget map[string]*toolkit.Widget
func Quit() {
g.Close()
}
// This lists out the know mappings
func listMap() {
for v, w := range viewWidget {
log("view =", v.Name, "widget name =", w.Name)
}
for s, w := range stringWidget {
log("string =", s, "widget =", w)
}
}
//
// This should be called ?
// Pass() ?
// This handles all interaction between the wit/gui package (what golang knows about)
// and this plugin that talks to the OS and does scary and crazy things to make
// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses)
//
// Once you are here, you should be in a protected goroutine created by the golang wit/gui package
//
// TODO: make sure you can't escape this goroutine
//
func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) {
log(debugPlugin, "Send() parent = nil")
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
/*
if (c.Action == "SetMargin") {
log(debugError, "need to implement SetMargin here")
setMargin(c, c.B)
return
}
*/
switch c.Type {
/*
case toolkit.Window:
// doWindow(c)
case toolkit.Tab:
// doTab(p, c)
case toolkit.Group:
newGroup(p, c)
case toolkit.Button:
newButton(p, c)
case toolkit.Checkbox:
// doCheckbox(p, c)
case toolkit.Label:
// doLabel(p, c)
case toolkit.Textbox:
// doTextbox(p, c)
case toolkit.Slider:
// doSlider(p, c)
case toolkit.Spinner:
// doSpinner(p, c)
case toolkit.Dropdown:
// doDropdown(p, c)
case toolkit.Combobox:
// doCombobox(p, c)
case toolkit.Grid:
// doGrid(p, c)
*/
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch c.S {
case "Toolkit":
debugToolkit = c.B
case "Change":
debugChange = c.B
case "Plugin":
debugPlugin = c.B
case "Flags":
debugFlags = c.B
case "Error":
debugError = c.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", c.S)
}
default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet")
}
}

View File

@ -3,17 +3,15 @@ package main
import (
"errors"
"fmt"
"log"
"strings"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func NewButton(parentW *toolkit.Widget, w *toolkit.Widget) {
log.Println("gui.gocui.AddButton()", w.Name)
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
log(true, "AddButton()", w.Name)
addButton(w.Name)
// viewWidget[v] = w
stringWidget[w.Name] = w
listMap()
}
@ -25,11 +23,11 @@ func addButton(name string) *gocui.View {
}
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
if err == nil {
log.Println("wit/gui internal plugin error", err)
log("wit/gui internal plugin error", err)
return nil
}
if !errors.Is(err, gocui.ErrUnknownView) {
log.Println("wit/gui internal plugin error", err)
log("wit/gui internal plugin error", err)
return nil
}
@ -39,10 +37,10 @@ func addButton(name string) *gocui.View {
currentView, err := baseGui.SetCurrentView(name)
if err != nil {
log.Println("wit/gui internal plugin error", err)
log("wit/gui internal plugin error", err)
return nil
}
log.Println("wit/gui addbutton() current view name =", currentView.Name())
log("wit/gui addbutton() current view name =", currentView.Name())
views = append(views, name)
curView = len(views) - 1

107
toolkit/gocui/debug.go Normal file
View File

@ -0,0 +1,107 @@
package main
import "git.wit.org/wit/gui/toolkit"
var defaultBehavior bool = true
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
var canvas bool // if set to true, the windows are a raw canvas
var menubar bool // for windows
var stretchy bool // expand things like buttons to the maximum size
var padded bool // add space between things like buttons
var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugFlags bool
var debugError bool = true
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func setDefaultBehavior(s bool) {
defaultBehavior = s
if (defaultBehavior) {
log(debugToolkit, "Setting this toolkit to use the default behavior.")
log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
stretchy = false
padded = true
menubar = true
margin = true
canvas = false
bookshelf = true // 99% of the time, things make a vertical stack of objects
} else {
log(debugToolkit, "This toolkit is set to ignore the default behavior.")
}
}
func ShowDebug () {
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
log(true, "debugPlugin =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugError =", debugError)
}
/*
func (t *gocuiT) Dump(b bool) {
if ! b {
return
}
log(b, "Name = ", t.Name, t.Width, t.Height)
if (t.uiBox != nil) {
log(b, "uiBox =", t.uiBox)
}
if (t.uiButton != nil) {
log(b, "uiButton =", t.uiButton)
}
if (t.uiCombobox != nil) {
log(b, "uiCombobox =", t.uiCombobox)
}
if (t.uiWindow != nil) {
log(b, "uiWindow =", t.uiWindow)
}
if (t.uiTab != nil) {
log(b, "uiTab =", t.uiTab)
}
if (t.uiGroup != nil) {
log(b, "uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log(b, "uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
}
if (t.uiSlider != nil) {
log(b, "uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log(b, "uiCheckbox =", t.uiCheckbox)
}
widgetDump(b, t.tw)
}
*/
func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) {
log(b, "widget = nil")
return
}
log(b, "widget.Name =", w.Name)
log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)
log(b, "widget.I =", w.I)
log(b, "widget.Width =", w.Width)
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
}
/*
func GetDebugToolkit () bool {
return debugToolkit
}
*/

View File

@ -7,7 +7,6 @@ package main
import (
"errors"
"fmt"
"log"
"os"
"git.wit.org/wit/gui/toolkit"
@ -34,17 +33,20 @@ var (
func Init() {
baseGui, err = gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
log.Panicln(err)
exit(err)
}
baseGui.Highlight = true
baseGui.SelFgColor = gocui.ColorRed
baseGui.SelFrameColor = gocui.ColorRed
baseGui.Cursor = true
baseGui.Mouse = true
baseGui.SetManagerFunc(layout)
if err := initKeybindings(baseGui); err != nil {
log.Panicln(err)
exit(err)
}
viewWidget = make(map[*gocui.View]*toolkit.Widget)
@ -54,17 +56,17 @@ func Init() {
outf, err = os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
log.Fatalf("error opening file: %v", err)
exit("error opening file: %v", err)
}
// hmm. where to put this?
// defer outf.Close()
log.SetOutput(outf)
log.Println("This is a test log entry")
setOutput(outf)
log("This is a test log entry")
}
func Queue(f func()) {
log.Println("QUEUEEEEE")
log("QUEUEEEEE")
f()
}
@ -79,7 +81,7 @@ func Main(f func()) {
// addButton("test 3")
f()
if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
log.Panicln(err)
exit(err)
}
baseGui.Close()
os.Exit(0)

View File

@ -1,18 +1,16 @@
package main
import (
"log"
"git.wit.org/wit/gui/toolkit"
)
func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
if (parentW == nil) {
log.Println("wit/gui plugin error. parent widget == nil")
log(debugError, "plugin error. parent widget == nil")
return
}
if (w == nil) {
log.Println("wit/gui plugin error. widget == nil")
log(debugPlugin, "plugin error. widget == nil")
return
}
if (w.Name == "") {
@ -21,18 +19,18 @@ func NewGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
if (w.Name == "") {
w.Name = "nil newGroup"
}
log.Println("gui.gocui.AddGroup", w.Name)
log("AddGroup", w.Name)
addGroup(w.Name)
stringWidget[w.Name] = w
}
func addGroup(name string) {
log.Println("addGroup() START name =", name)
log.Println("addGroup() START groupSize =", groupSize, "currentY =", currentY, "currentX =", currentX)
log("addGroup() START name =", name)
log("addGroup() START groupSize =", groupSize, "currentY =", currentY, "currentX =", currentX)
currentY = 2
currentX += groupSize + 5
groupSize = 0
log.Println("addGroup() START, RESET Y = 3, RESET X = ", currentX)
log("addGroup() START, RESET Y = 3, RESET X = ", currentX)
}

View File

@ -5,17 +5,12 @@
package main
import (
// "errors"
// "fmt"
"log"
// "strings"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func initKeybindings(g *gocui.Gui) error {
log.Println("got to initKeybindings")
log("got to initKeybindings")
if err := g.SetKeybinding("", 'q', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
@ -54,7 +49,7 @@ func initKeybindings(g *gocui.Gui) error {
}
if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log.Println("tab", v.Name())
log("tab", v.Name())
return nextView(g, true)
}); err != nil {
return err
@ -73,27 +68,27 @@ func initKeybindings(g *gocui.Gui) error {
}
if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log.Println("down", v.Name())
log("down", v.Name())
return moveView(g, v, 0, delta)
}); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log.Println("up", v.Name())
log("up", v.Name())
return moveView(g, v, 0, -delta)
}); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log.Println("enter", v.Name())
log("enter", v.Name())
var w *toolkit.Widget
w = stringWidget[v.Name()]
if (w == nil) {
log.Println("COULD NOT FIND WIDGET", v.Name())
log("COULD NOT FIND WIDGET", v.Name())
} else {
log.Println("FOUND WIDGET!", w)
log("FOUND WIDGET!", w)
if (w.Custom != nil) {
w.Custom()
return nil
@ -123,14 +118,14 @@ func initKeybindings(g *gocui.Gui) error {
}
if err := g.SetKeybinding("", 'h', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log.Println("help", v.Name())
log("help", v.Name())
tmp, _ := g.SetViewOnTop("help")
log.Println("help 2", tmp.Name())
log("help 2", tmp.Name())
// g.SetView("help", 2, 2, 30, 15, 0);
g.SetCurrentView("help")
// moveView(g, tmp, 0, -delta)
if err := g.DeleteView("help"); err != nil {
log.Fatalln("gocui SetKeybinding()", err)
exit("gocui SetKeybinding()", err)
}
return nil
}); err != nil {

135
toolkit/gocui/log.go Normal file
View File

@ -0,0 +1,135 @@
//
// version v1.3
//
// I like things to be easy.
//
// combining logging inside of a gui made me do this
//
// 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
// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
//
package main
import (
"os"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
)
var LOGOFF bool = false // turn this off, all logging stops
var WARN bool
var INFO bool
type spewt struct {
a bool
}
var SPEW spewt
/*
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(true, "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(true, "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] = "GUI/Toolkit/gocui"
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
// a = a[1:]
a[0] = "GUI/Toolkit/gocui"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
}
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(f *os.File) {
golog.SetOutput(f)
}

View File

@ -1,8 +1,8 @@
package main
import (
"log"
// if you include more than just this import
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
"git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
@ -19,10 +19,97 @@ func Quit() {
// This lists out the know mappings
func listMap() {
for v, w := range viewWidget {
log.Println("view =", v.Name, "widget name =", w.Name)
log("view =", v.Name, "widget name =", w.Name)
}
for s, w := range stringWidget {
log.Println("string =", s, "widget =", w)
log("string =", s, "widget =", w)
}
}
//
// This should be called ?
// Pass() ?
// This handles all interaction between the wit/gui package (what golang knows about)
// and this plugin that talks to the OS and does scary and crazy things to make
// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses)
//
// Once you are here, you should be in a protected goroutine created by the golang wit/gui package
//
// TODO: make sure you can't escape this goroutine
//
func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) {
log(debugPlugin, "Send() parent = nil")
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Action, ",", c.Type)
/*
if (c.Action == "SetMargin") {
log(debugError, "need to implement SetMargin here")
setMargin(c, c.B)
return
}
*/
switch c.Type {
/*
case toolkit.Window:
// doWindow(c)
case toolkit.Tab:
// doTab(p, c)
*/
case toolkit.Group:
newGroup(p, c)
case toolkit.Button:
newButton(p, c)
/*
case toolkit.Checkbox:
// doCheckbox(p, c)
case toolkit.Label:
// doLabel(p, c)
case toolkit.Textbox:
// doTextbox(p, c)
case toolkit.Slider:
// doSlider(p, c)
case toolkit.Spinner:
// doSpinner(p, c)
case toolkit.Dropdown:
// doDropdown(p, c)
case toolkit.Combobox:
// doCombobox(p, c)
case toolkit.Grid:
// doGrid(p, c)
*/
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch c.S {
case "Toolkit":
debugToolkit = c.B
case "Change":
debugChange = c.B
case "Plugin":
debugPlugin = c.B
case "Flags":
debugFlags = c.B
case "Error":
debugError = c.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", c.S)
}
default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet")
}
}

View File

@ -7,7 +7,6 @@ package main
import (
"errors"
"fmt"
"log"
"strings"
"github.com/awesome-gocui/gocui"
@ -71,11 +70,11 @@ func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error {
if err != nil {
return err
}
log.Println(x0, y0, x1, y1)
log(x0, y0, x1, y1)
if _, err := g.SetView(name, x0+dx, y0+dy, x1+dx, y1+dy, 0); err != nil {
return err
}
x0, y0, x1, y1, err = g.ViewPosition(name)
log.Println(x0, y0, x1, y1)
log(x0, y0, x1, y1)
return nil
}

View File

@ -1,18 +1,16 @@
package main
import (
"log"
"git.wit.org/wit/gui/toolkit"
)
func NewWindow(w *toolkit.Widget) {
if (w == nil) {
log.Println("wit/gui plugin error. widget == nil")
log("wit/gui plugin error. widget == nil")
return
}
if (w.Name == "") {
w.Name = "nil newWindow"
}
log.Println("gui.gocui.AddWindow", w.Name)
log("gui.gocui.AddWindow", w.Name)
}

View File

@ -11,18 +11,26 @@ package toolkit
// Event() seems like a good name.
// Could a protobuf be used here? (Can functions be passed?)
type Widget struct {
Name string // "New", "Delete", "Set", aka something to do
Name string
Action string // "New", "Delete", "Set", aka something to do
// Type string // after lots of back and forth, a simple string
Type WidgetType
// This function is how you interact with the toolkit
// latest attempt. seems to work so far (2023/02/28)
// Hopefully this will be the barrier between the goroutines
// TODO: move this interaction to channels
Custom func()
// re-adding an id to test channels
id int
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
// The string is also used to set the button name
B bool
I int
// maybe safe if there is correctly working Custom() between goroutines
// (still probably not, almost certainly not)
// maybe safe if there is correctly working Custom() between goroutines?
// (still probably not, almost certainly not. not possible. layer violation?)
S string // not safe to have 'S'
// This GUI is intended for simple things
@ -38,10 +46,6 @@ type Widget struct {
// Make widgets fill up the space available
Expand bool
// latest attempt. seems to work so far (2023/02/28)
// Hopefully this will be the barrier between the goroutines
Custom func()
}
type WidgetType int
@ -62,6 +66,8 @@ const (
Slider
Spinner
Grid
Box
Image
Flag
)
@ -93,6 +99,10 @@ func (s WidgetType) String() string {
return "Spinner"
case Grid:
return "Grid"
case Box:
return "Box"
case Image:
return "Image"
case Flag:
return "Flag"
case Unknown:
@ -100,3 +110,15 @@ func (s WidgetType) String() string {
}
return "GuiToolkitTUndefinedType"
}
// this is hopefully just used in a very few places for
// debuging the interaction between go apps and the underlying
// toolkits. Hopefully this is less prone to problems and can
// detect memory leaks, threading problems, memory allocation & mapping errors, etc
func (w *Widget) GetId() int {
return w.id
}
func (w *Widget) SetId(i int) {
w.id = i
}