add semi-working gocui

commit 947169df5a22c9f9b53f825764747f648c70ff1e
Author: Jeff Carr <jcarr@wit.com>
Date:   Wed Mar 29 22:44:08 2023 -0500

    ready for version v0.7.4

        start deprecating toolkit.Widget
        switch to variable name 'ParentId'
        use 'ActionType' and 'WidgetType'
        preliminary redraw()
        final definition of variables 'Name' and 'Text'
        more cleaning of the code
        remove lots of dumb code
        bind 'd' key press to dump out debugging info
        early color handling in gocui!

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

commit 6013fde8332e8ecbffaf1a0977ba2e1da8ea8775
Author: Jeff Carr <jcarr@wit.com>
Date:   Sun Mar 26 17:19:20 2023 -0500

    improvements towards a working dns control panel

        democui has the help menu
        try to add mouse support to gocui
        make a direct access method
        Margin() and Pad() tests
        add SPEW
        also push devel branch to github

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

commit 6f91f5e080e06cdc0f34b13d23e5fd16ea37259a
Author: Jeff Carr <jcarr@wit.com>
Date:   Fri Mar 24 20:14:18 2023 -0500

    starting to try safe chan and goroutines

        fix tab title's
        right before attempting to add chan goroutines
        removed "where" widget pointer
        box added to tab
        experiement with log as it's own repo

    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-29 23:03:04 -05:00
parent fa356841bf
commit b99e4425fa
70 changed files with 2063 additions and 1427 deletions

View File

@ -55,6 +55,7 @@ cmds-helloconsole:
github:
git push origin master
git push github master
git push github devel
git push github --tags
@echo
@echo check https://github.com/wit-go/gui

View File

@ -107,42 +107,6 @@ external things which might be useful
* [GO Style Guide]
```
version v1.3
I like things to be easy.
this means all the log settings are in one place. it should allow
things to be over-ridden externally to the library
but still allow command line --args to pass debugging settings
## I also have a generic sleep() and exit() in here because it's simple
Usage:
log("something", foo, bar)
var DEBUG bool = true
log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
## Variables
```golang
var INFO bool
```
```golang
var LOGOFF bool = false // turn this off, all logging stops
```
```golang
var SPEW spewt
```
```golang
var WARN bool
```
## Functions
### func [DebugWidgetWindow](/debugWidget.go#L52)
@ -155,11 +119,15 @@ var WARN bool
Creates a window helpful for debugging this package
### func [Indent](/debug.go#L130)
### func [ExampleCatcher](/chan.go#L37)
`func ExampleCatcher(f func())`
### func [Indent](/debug.go#L125)
`func Indent(b bool, a ...interface{})`
### func [InitPlugins](/main.go#L56)
### func [InitPlugins](/main.go#L58)
`func InitPlugins(names []string)`
@ -169,22 +137,15 @@ Creates a window helpful for debugging this package
loads and initializes a toolkit (andlabs/ui, gocui, etc)
### func [Main](/main.go#L97)
### func [Main](/main.go#L121)
`func Main(f func())`
This should not pass a function
### func [Queue](/main.go#L127)
### func [Redraw](/redraw.go#L9)
`func Queue(f func())`
Other goroutines must use this to access the GUI
You can not acess / process the GUI thread directly from
other goroutines. This is due to the nature of how
Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
For example: gui.Queue(NewWindow())
`func Redraw(s string)`
### func [SetDebug](/debug.go#L28)
@ -194,11 +155,11 @@ For example: gui.Queue(NewWindow())
`func SetFlag(s string, b bool)`
### func [ShowDebugValues](/debug.go#L86)
### func [ShowDebugValues](/debug.go#L79)
`func ShowDebugValues()`
### func [StandardExit](/main.go#L147)
### func [StandardExit](/main.go#L173)
`func StandardExit()`
@ -216,13 +177,13 @@ This goroutine can be used like a watchdog timer
## Types
### type [GuiArgs](/structs.go#L25)
### type [GuiArgs](/structs.go#L26)
`type GuiArgs struct { ... }`
This struct can be used with the go-arg package
### type [GuiConfig](/structs.go#L33)
### type [GuiConfig](/structs.go#L34)
`type GuiConfig struct { ... }`
@ -232,7 +193,7 @@ This struct can be used with the go-arg package
var Config GuiConfig
```
### type [Node](/structs.go#L57)
### type [Node](/structs.go#L58)
`type Node struct { ... }`
@ -287,12 +248,22 @@ func main() {
You get a window
```
#### func [Start](/main.go#L98)
`func Start() *Node`
#### func [StartS](/main.go#L107)
`func StartS(name string) *Node`
### type [Symbol](/plugin.go#L16)
`type Symbol any`
## Sub Packages
* [log](./log)
* [toolkit](./toolkit)
---

View File

@ -6,11 +6,15 @@ func (n *Node) NewButton(name string, custom func()) *Node {
newNode := n.New(name, toolkit.Button, custom)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
a.Name = name
a.Text = name
a.ActionType = toolkit.Add
a.Callback = callback
newaction(&a, newNode, n)
return newNode
}
func callback(i int) {
log(debugError, "button callback() i =", i)
}

32
chan.go
View File

@ -8,8 +8,10 @@ import (
// "regexp"
// "git.wit.org/wit/gui/toolkit"
"sync"
"runtime"
"github.com/sourcegraph/conc"
"github.com/sourcegraph/conc/stream"
"github.com/sourcegraph/conc/panics"
)
func makeConc() {
@ -17,14 +19,42 @@ func makeConc() {
defer wg.Wait()
startTheThing(&wg)
log(debugError, "panic?")
sleep(2)
log(debugError, "panic? after sleep(5)")
}
func startTheThing(wg *conc.WaitGroup) {
f := func() {
log(debugError, "startTheThing() == about to panic now")
panic("test conc.WaitGroup")
}
wg.Go(func() {
log(debugNow, "startTheThing()")
ExampleCatcher(f)
})
}
func ExampleCatcher(f func()) {
var pc panics.Catcher
i := 0
pc.Try(func() { i += 1 })
pc.Try(f)
pc.Try(func() { i += 1 })
recovered := pc.Recovered()
log(debugError, "panic.Recovered():", recovered.Value.(string))
frames := runtime.CallersFrames(recovered.Callers)
for {
frame, more := frames.Next()
log(debugError, "\t", frame.Function)
if !more {
break
}
}
}
func mapStream(
in chan int,
out chan int,

View File

@ -10,10 +10,9 @@ func (n *Node) NewCheckbox(name string) *Node {
newNode := n.New(name, toolkit.Checkbox, nil)
var a toolkit.Action
a.Type = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a, newNode, n)
a.ActionType = toolkit.Add
a.Name = name
a.Text = name
newaction(&a, newNode, n)
return newNode

View File

@ -8,7 +8,7 @@
run: build
# ./buttonplugin >/tmp/buttonplugin.log 2>&1
./buttonplugin
./buttonplugin >/tmp/witgui.log.stderr 2>&1
build-release:
go get -v -u -x .
@ -21,3 +21,7 @@ build:
update:
GO111MODULE="off" go get -v -u -x .
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

View File

@ -12,11 +12,7 @@ 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
@ -54,27 +50,49 @@ var counter int = 5
// This creates a window
func buttonWindow() {
var w, g *gui.Node
var w, t, g, more, more2 *gui.Node
gui.Config.Title = title
gui.Config.Width = 640
gui.Config.Height = 480
w = gui.NewWindow()
g = w.NewGroup("buttonGroup")
t = w.NewTab("buttonTab")
g = t.NewGroup("buttonGroup")
g.NewButton("this app is old", func () {
g.NewButton("this app is useful for plugin debuggin", func () {
})
g.NewLabel("STDOUT is set to: " + outfile)
g.NewButton("hello", func () {
log.Println("world")
})
more = g.NewGroup("more")
g.NewButton("NewButton()", func () {
g.NewButton("Load 'democui'", func () {
// this set the xterm and mate-terminal window title. maybe works generally?
fmt.Println("\033]0;" + title + "blah \007")
gui.StartS("democui")
})
g.NewButton("Redraw 'democui'", func () {
fmt.Println("\033]0;" + title + "blah2 \007")
gui.Redraw("democui")
})
g.NewButton("NewButton(more)", func () {
log.Println("new foobar 2. Adding button 'foobar 3'")
name := "foobar " + strconv.Itoa(counter)
counter += 1
g.NewButton(name, func () {
more.NewButton(name, func () {
log.Println("Got all the way to main() name =", name)
})
})
g.NewButton("NewButton(more2)", func () {
log.Println("new foobar 2. Adding button 'foobar 3'")
name := "foobar " + strconv.Itoa(counter)
counter += 1
more2.NewButton(name, func () {
log.Println("Got all the way to main() name =", name)
})
})
@ -83,30 +101,12 @@ func buttonWindow() {
log.Println("new foobar 2. Adding button 'foobar 3'")
name := "neat " + strconv.Itoa(counter)
counter += 1
g.NewGroup(name)
more.NewGroup(name)
})
g.NewButton("gui.DebugWindow()", func () {
gui.DebugWindow()
})
g.NewButton("LoadToolkit(andlabs)", func () {
gui.LoadToolkit("andlabs")
})
g.NewButton("LoadToolkit(gocui)", func () {
gui.LoadToolkit("gocui")
})
g.NewButton("Init()", func () {
log.Println("gui.Init() is deprecated(?)")
//gui.Init()
})
g.NewButton("Main()", func () {
go gui.Main(func () {
w := gui.NewWindow()
w.NewGroup("buttonGroup")
})
})
more2 = g.NewGroup("more2")
}

View File

@ -1,5 +1,6 @@
run: build
GOTRACEBACK=all ./textbox --gui-debug
# GOTRACEBACK=all ./textbox --gui-debug
GOTRACEBACK=all ./textbox --gui-debug >/tmp/witgui.log.stderr 2>&1
build-release:
go get -v -u -x .

View File

@ -24,7 +24,9 @@ func main() {
arg.MustParse(&args)
log.Println("Toolkit = ", args.Toolkit)
// gui.InitPlugins([]string{"andlabs"})
// gui.SetDebug(true)
// gui.InitPlugins([]string{"gocui"})
// gui.InitPlugins([]string{"democui"})
gui.Main(initGUI)
}
@ -68,10 +70,10 @@ func addDemoTab(window *gui.Node, title string) {
dd.AddDropdownName("more 2")
dd.AddDropdownName("more 3")
g.SetNext(3,1)
g1.NewLabel("label (3,1)")
g.SetNext(3,2)
g1.NewLabel("label (3,2)")
// g.SetNext(3,1)
// g1.NewLabel("label (3,1)")
// g.SetNext(3,2)
// g1.NewLabel("label (3,2)")
g2 := newNode.NewGroup("group 2")
tb := g2.NewTextbox("tb")

View File

@ -11,25 +11,25 @@ import (
func (n *Node) Show() {
var a toolkit.Action
a.Type = toolkit.Show
a.ActionType = toolkit.Show
newaction(&a, n, nil)
}
func (n *Node) Hide() {
var a toolkit.Action
a.Type = toolkit.Hide
a.ActionType = toolkit.Hide
newaction(&a, n, nil)
}
func (n *Node) Enable() {
var a toolkit.Action
a.Type = toolkit.Enable
a.ActionType = toolkit.Enable
newaction(&a, n, nil)
}
func (n *Node) Disable() {
var a toolkit.Action
a.Type = toolkit.Disable
a.ActionType = toolkit.Disable
newaction(&a, n, nil)
}
@ -37,7 +37,7 @@ func (n *Node) Add(str string) {
log(debugGui, "gui.Add() value =", str)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.S = str
// a.Widget = &n.widget
// action(&a)
@ -48,7 +48,7 @@ func (n *Node) AddText(str string) {
log(debugChange, "AddText() value =", str)
var a toolkit.Action
a.Type = toolkit.AddText
a.ActionType = toolkit.AddText
a.S = str
// a.Widget = &n.widget
// action(&a)
@ -59,7 +59,7 @@ func (n *Node) SetText(str string) {
log(debugChange, "SetText() value =", str)
var a toolkit.Action
a.Type = toolkit.SetText
a.ActionType = toolkit.SetText
a.S = str
// a.Widget = &n.widget
// action(&a)
@ -80,7 +80,7 @@ func (n *Node) SetNext(x int, y int) {
func (n *Node) Set(val any) {
log(debugChange, "Set() value =", val)
var a toolkit.Action
a.Type = toolkit.Set
a.ActionType = toolkit.Set
switch v := val.(type) {
case bool:
@ -100,7 +100,7 @@ func (n *Node) Set(val any) {
func (n *Node) AppendText(str string) {
var a toolkit.Action
a.Type = toolkit.SetText
a.ActionType = toolkit.SetText
tmp := n.widget.S + str
log(debugChange, "AppendText() value =", tmp)
a.S = tmp
@ -157,3 +157,50 @@ func commonCallback(n *Node) {
n.Custom()
}
}
func (n *Node) Margin() {
var a toolkit.Action
a.ActionType = toolkit.Margin
newaction(&a, n, nil)
}
func (n *Node) Unmargin() {
var a toolkit.Action
a.ActionType = toolkit.Unmargin
newaction(&a, n, nil)
}
func (n *Node) Pad() {
var a toolkit.Action
a.ActionType = toolkit.Pad
newaction(&a, n, nil)
}
func (n *Node) Unpad() {
var a toolkit.Action
a.ActionType = toolkit.Unpad
newaction(&a, n, nil)
}
func (n *Node) New2() *Node {
var newWin *Node
newWin = NewWindow()
log(debugError, "New2() END Main(f)")
return newWin
}
func (n *Node) Window(title string) *Node {
log(debugError, "Window()", n)
n.SetText(title)
return n
}
func (n *Node) Standard() *Node {
log(debugError, "Standard()")
return n
}
func (n *Node) DoMargin() *Node {
log(debugError, "DoMargin()")
return n
}

View File

@ -65,16 +65,9 @@ func SetFlag (s string, b bool) {
log(debugGui, "Can't set unknown flag", s)
}
// send the flag to the toolkit
// n := Config.flag
// log(debugChange, "Set() toolkit flag", s, "to", b)
// n.widget.Action = "Set"
// n.widget.S = s
// n.widget.B = b
// send(nil, n) // set flag in the plugin
var a toolkit.Action
a.Type = toolkit.SetFlag
a.ActionType = toolkit.Set
a.WidgetType = toolkit.Flag
a.S = s
a.B = b
// a.Widget = &newNode.widget
@ -109,9 +102,11 @@ func (n *Node) Dump(b bool) {
Indent(b, "Height = ", n.Height)
Indent(b, "(X,Y) = ", n.X, n.Y)
Indent(b, "Next (X,Y) = ", n.NextX, n.NextY)
/*
Indent(b, "Widget Name = ", n.widget.Name)
Indent(b, "Widget Type = ", n.widget.Type)
Indent(b, "Widget Id = ", n.widget.GetId())
Indent(b, "Widget Id = ", n.widget.Id)
*/
if (n.parent == nil) {
Indent(b, "parent = nil")

View File

@ -111,7 +111,7 @@ func DebugWidgetWindow(w *Node) {
activeWidget.Dump(true)
var a toolkit.Action
a.Type = toolkit.Dump
a.ActionType = toolkit.Dump
newaction(&a, activeWidget, nil)
})
@ -123,64 +123,53 @@ func DebugWidgetWindow(w *Node) {
g = bugWidget.NewGroup("change things")
g.NewButton("AddText()", func () {
var a toolkit.Action
a.Type = toolkit.AddText
a.ActionType = toolkit.AddText
a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
})
g.NewButton("SetText()", func () {
var a toolkit.Action
a.Type = toolkit.SetText
a.ActionType = toolkit.SetText
a.S = activeLabelNewName.widget.S
newaction(&a, activeWidget, nil)
})
g.NewButton("Margin()", func () {
var a toolkit.Action
a.Type = toolkit.Margin
a.ActionType = toolkit.Margin
newaction(&a, activeWidget, nil)
})
g.NewButton("Unmargin()", func () {
var a toolkit.Action
a.Type = toolkit.Unmargin
a.ActionType = toolkit.Unmargin
newaction(&a, activeWidget, nil)
})
g.NewButton("Pad()", func () {
var a toolkit.Action
a.Type = toolkit.Pad
a.ActionType = toolkit.Pad
newaction(&a, activeWidget, nil)
})
g.NewButton("Unpad()", func () {
var a toolkit.Action
a.Type = toolkit.Unpad
a.ActionType = toolkit.Unpad
newaction(&a, activeWidget, nil)
})
g.NewButton("Move(junk)", func () {
var a toolkit.Action
a.Type = toolkit.Move
a.ActionType = toolkit.Move
newaction(&a, activeWidget, activeJunk)
})
g.NewButton("Delete()", func () {
var a toolkit.Action
a.Type = toolkit.Delete
a.ActionType = toolkit.Delete
newaction(&a, activeWidget, activeJunk)
})
g = bugWidget.NewGroup("not working?")
g.NewButton("Dump Widget Values()", func () {
log("activeWidget.B =", activeWidget.widget.B)
log("activeWidget.I =", activeWidget.widget.I)
log("activeWidget.S =", activeWidget.widget.S)
log("activeWidget.X =", activeWidget.widget.X)
log("activeWidget.Y =", activeWidget.widget.Y)
log("activeWidget.Width =", activeWidget.widget.Width)
log("activeWidget.Height =", activeWidget.widget.Height)
log("activeWidget.Margin =", activeWidget.widget.Margin)
log("activeWidget.Expand =", activeWidget.widget.Expand)
})
activeJunk = bugWidget.NewGroup("junk:")
activeJunk.NewLabel("test junk")
if (activeWidget == nil) {
setActiveWidget(Config.master)
setActiveWidget(Config.rootNode)
}
}
@ -188,8 +177,7 @@ func (n *Node) debugAddWidgetButtons() {
n.NewButton("Dropdown", func () {
a := activeWidget.NewDropdown("tmp dropdown")
a.AddText("this is better than tcl/tk")
a.AddText("make something for tim")
a.AddText("for qflow")
a.AddText("make something for tim for qflow")
a.AddText("and for riscv")
a.Custom = func () {
log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id)
@ -198,7 +186,7 @@ func (n *Node) debugAddWidgetButtons() {
n.NewButton("Combobox", func () {
a := activeWidget.NewCombobox("tmp combobox")
a.AddText("mirrors.wit.com")
a.AddText("go.wit.org")
a.AddText("go.wit.com")
a.Custom = func () {
log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id)
}
@ -213,12 +201,14 @@ func (n *Node) debugAddWidgetButtons() {
// SetDebug(true)
debugGrid = activeWidget.NewGrid("tmp grid", 2, 3)
debugGridLabel = debugGrid.NewLabel("mirrors.wit.com")
/*
debugGrid.SetNext(0,1)
debugGrid.NewLabel("foo (0,1)")
debugGrid.SetNext(1,1)
debugGrid.NewLabel("foo (1,1)")
debugGrid.SetNext(2,1)
debugGrid.NewLabel("foo (2,1)")
*/
// SetDebug(false)
DebugWidgetWindow(debugGrid)
})
@ -316,7 +306,7 @@ func (n *Node) debugAddWidgetButton() {
newNode := activeWidget.New(name, toolkit.Label, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
newaction(&a, newNode, activeWidget)
// return newNode
// activeWidget.NewLabel(name)

View File

@ -74,15 +74,37 @@ func (n *Node) DebugTab(title string) *Node {
dropdownWindowWidgets(g1)
})
g2 := newN.NewGroup("node things")
g2 := newN.NewGroup("more things")
g2.NewButton("Node.ListChildren(true)", func () {
if (activeWidget == nil) {
activeWidget = Config.master
activeWidget = Config.rootNode
}
activeWidget.ListChildren(true)
})
g2.NewButton("test conc", func () {
makeConc()
})
g2.NewButton("List Plugins", func () {
for _, aplug := range allPlugins {
log("Loaded plugin:", aplug.name, aplug.filename)
}
})
g2.NewButton("load plugin 'gocui'", func () {
StartS("gocui")
})
g2.NewButton("load plugin 'democui'", func () {
StartS("democui")
})
g2.NewButton("Redraw(democui)", func () {
Redraw("democui")
})
return newN
}
@ -105,7 +127,7 @@ func dropdownWindow(p *Node) {
}
// var last = ""
for _, child := range Config.master.children {
for _, child := range Config.rootNode.children {
log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
dd.AddDropdownName(child.Name)
// last = child.Name
@ -145,5 +167,5 @@ func dropdownWindowWidgets(p *Node) {
}
// list everything in the binary tree
addDropdowns(Config.master)
addDropdowns(Config.rootNode)
}

View File

@ -23,7 +23,7 @@ func (n *Node) NewDropdown(name string) *Node {
newNode := n.New(name, toolkit.Dropdown, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)
@ -36,7 +36,7 @@ func (n *Node) NewCombobox(name string) *Node {
newNode := n.New(name, toolkit.Combobox, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)

View File

@ -22,7 +22,7 @@ func (n *Node) NewGrid(name string, x int, y int) *Node {
})
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.X = x
a.Y = y
newNode.X = x
@ -38,7 +38,9 @@ func (n *Node) NewBox(name string, b bool) *Node {
newNode := n.New(name, toolkit.Box, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.Name = name
a.Text = name
a.B = b
newaction(&a, newNode, n)

View File

@ -12,7 +12,7 @@ func (n *Node) NewGroup(name string) *Node {
newNode = n.New(name, toolkit.Group, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
newaction(&a, newNode, n)
newBox := newNode.NewBox("group vBox", false)

View File

@ -9,7 +9,7 @@ func (n *Node) NewImage(name string) *Node {
newNode = n.New(name, toolkit.Image, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)

View File

@ -8,7 +8,9 @@ func (n *Node) NewLabel(text string) *Node {
newNode := n.New(text, toolkit.Label, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.Name = text
a.Text = text
newaction(&a, newNode, n)
return newNode

130
log.go
View File

@ -1,125 +1,29 @@
//
// version v1.3
//
// I like things to be easy.
//
// this means all the log settings are in one place. it should allow
// things to be over-ridden externally to the library
// but still allow command line --args to pass debugging settings
//
// I also have a generic sleep() and exit() in here because it's simple
//
// Usage:
//
// log("something", foo, bar)
// var DEBUG bool = true
// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
//
package gui
import (
"os"
"runtime"
"runtime/pprof"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
// "net"
witlog "git.wit.org/wit/gui/log"
)
var LOGOFF bool = false // turn this off, all logging stops
var WARN bool
var INFO bool
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
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("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("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
*/
// var log interface{}
func log(a ...any) {
if (LOGOFF) {
return
}
if (a == nil) {
return
}
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
// golog.Println("\t a[0] = bool")
if (a[0] == false) {
return
}
a[0] = "WIT/GUI"
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
a = a[1:]
spew.Dump(a)
return
}
golog.Println(a...)
witlog.Where = "wit/gui"
witlog.Log(a...)
}
func loggo() {
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
witlog.Exit(a...)
}
// b bool, print if true
@ -135,5 +39,5 @@ func logindent(b bool, depth int, format string, a ...any) {
// array prepend(). Why isn't this a standard function. It should be:
// a.prepend(debugGui, newFormat)
a = append([]any{b, newFormat}, a...)
log(a...)
witlog.Log(a...)
}

149
log/log.go Normal file
View File

@ -0,0 +1,149 @@
package witlog
//
// version v1.2
//
// I like things to be easy.
//
// this means all the log settings are in one place. it should allow
// things to be over-ridden externally to the library
// but still allow command line --args to pass debugging settings
//
// I also have a generic sleep() and exit() in here because it's simple
//
// Usage:
//
// log("something", foo, bar)
// var DEBUG bool = true
// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
//
import (
"os"
"runtime"
"runtime/pprof"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
// "net"
)
// various debugging flags
var LogNow bool = true // useful for active development
var LogError bool = true
var LogWarn bool = false
var LogInfo bool = false
var LogVerbose bool = false
var LogSleep bool = false
var LOGOFF bool = false // turn this off, all logging stops
var debugToolkit bool = false // does spew stuff?
var Where string = "gui/log"
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(LogSleep, "sleep", a[0])
switch a[0].(type) {
case int:
time.Sleep(time.Duration(a[0].(int)) * time.Second)
case float64:
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
default:
Log("sleep a[0], type = ", a[0], reflect.TypeOf(a[0]))
}
}
/*
exit() # yep. exits. I guess everything must be fine
exit(3) # I guess 3 it is then
exit("dont like apples") # ok. I'll make a note of that
*/
func Exit(a ...any) {
Log(LogError, "exit", a)
//if (a) {
// os.Exit(a)
//}
os.Exit(0)
}
/*
I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever.
I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this
implementation is probably faster than all of those because you just set one bool to FALSE
and it all stops.
Sometimes I need to capture to stdout, sometimes stdout can't
work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread
over 8 million references in every .go file. I'm tapping out and putting
it in one place. here it is. Also, this makes having debug levels really fucking easy.
You can define whatever level of logging you want from anywhere (command line) etc.
log() # doesn't do anything
log(stuff) # sends it to whatever log you define in a single place. here is the place
*/
func Log(a ...any) {
if (LOGOFF) {
return
}
if (a == nil) {
return
}
var tbool bool
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) {
if (a[0] == false) {
return
}
a[0] = Where
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
// a = a[1:]
a[0] = Where
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
}
func loggo() {
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
}
func logindent(depth int, format string, a ...interface{}) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
}
// newFormat := tabs + strconv.Itoa(depth) + " " + format
newFormat := tabs + format
Log(debugToolkit, newFormat, a)
}
func SetOutput(f *os.File) {
golog.SetOutput(f)
}

38
main.go
View File

@ -2,7 +2,7 @@ package gui
import (
// "embed"
// "git.wit.org/wit/gui/toolkit"
"git.wit.org/wit/gui/toolkit"
)
// Windows doesn't support plugins. How can I keep andlabs and only compile it on windows?
@ -31,10 +31,12 @@ func init() {
Config.Height = 480
// Populates the top of the binary tree
Config.master = addNode("guiBinaryTree")
Config.rootNode = addNode("guiBinaryTree")
Config.rootNode.WidgetType = toolkit.Root
// used to pass debugging flags to the toolkit plugins
Config.flag = Config.master.New("flag", 0, nil)
Config.flag = Config.rootNode.New("flag", 0, nil)
Config.flag.WidgetType = toolkit.Flag
}
func doGuiChan() {
@ -57,7 +59,7 @@ func InitPlugins(names []string) {
log(debugGui, "Starting gui.Init()")
for _, aplug := range allPlugins {
log(debugGui, "gui.LoadToolkit() already loaded toolkit plugin =", aplug.name)
log(debugGui, "LoadToolkit() already loaded toolkit plugin =", aplug.name)
for _, name := range names {
if (name == aplug.name) {
return
@ -93,6 +95,28 @@ func InitPlugins(names []string) {
// StandardExit("golang wit/gui could not load a plugin TODO: do something to STDOUT (?)")
}
func Start() *Node {
log(logInfo, "Start() Main(f)")
f := func() {
}
go Main(f)
sleep(1)
return Config.rootNode
}
func StartS(name string) *Node {
log(logInfo, "Start() Main(f) for name =", name)
if (LoadToolkit(name) == false) {
return Config.rootNode
}
// will this really work on mswindows & macos?
f := func() {
}
go Main(f)
sleep(1) // temp hack until chan communication is setup
return Config.rootNode
}
// This should not pass a function
func Main(f func()) {
log(debugGui, "Starting gui.Main() (using gtk via andlabs/ui)")
@ -111,11 +135,12 @@ func Main(f func()) {
}
aplug.MainOk = true
aplug.Main(f)
// f()
}
// toolkit.Main(f)
}
/*
This is deprecated and will be implemented more correctly with waitgroups
// This should never be exposed(?)
// Other goroutines must use this to access the GUI
@ -135,6 +160,7 @@ func Queue(f func()) {
aplug.Queue(f)
}
}
*/
// The window is destroyed but the application does not quit
func (n *Node) StandardClose() {

View File

@ -9,6 +9,7 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
var newN *Node
newN = addNode(title)
newN.WidgetType = t
newN.widget.Type = t
// newN.widget.Action = "New"
newN.Custom = custom
@ -44,7 +45,7 @@ func addNode(title string) *Node {
n.Name = title
n.widget.Name = title
n.id = Config.counter
n.widget.SetId(n.id)
n.widget.Id = n.id
log(debugNode, "addNode = widget setid =", n.id)
Config.counter += 1
@ -55,9 +56,11 @@ 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)

View File

@ -29,12 +29,12 @@ type aplug struct {
// TODO: make Main() main() and never allow the user to call it
// run plugin.Main() when the plugin is loaded
Main func(func ()) // this never returns. Each plugin must have it's own goroutine
Queue func(func ()) // Should this return right away? Should it wait (can it wait?)
// Queue func(func ()) // Should this return right away? Should it wait (can it wait?)
Quit func()
// NewWindow func(*toolkit.Widget)
// simplifies passing to the plugin
Send func(*toolkit.Widget, *toolkit.Widget)
// Send func(*toolkit.Widget, *toolkit.Widget)
// should replace Send()
Action func(*toolkit.Action)
@ -74,16 +74,11 @@ func LoadToolkit(name string) bool {
newPlug.Main = loadFuncF(&newPlug, "Main")
// should send things to the goroutine above
newPlug.Queue = loadFuncF(&newPlug, "Queue")
// newPlug.Queue = loadFuncF(&newPlug, "Queue")
// unload the plugin and restore state
newPlug.Quit = loadFuncE(&newPlug, "Quit")
// Sends a widget (button, checkbox, etc) and it's parent widget
// This includes instructions like "Add", "Delete", "Disable", etc
// newPlug.Send = loadFunc2(&newPlug, "Send")
// This should replace Send()
// Sends instructions like "Add", "Delete", "Disable", etc
// Sends a widget (button, checkbox, etc) and it's parent widget
newPlug.Action = loadFuncA(&newPlug, "Action")
@ -190,7 +185,8 @@ func loadPlugin(p *aplug, name string) {
homeDir, err := os.UserHomeDir()
if err != nil {
exit(err)
log(logError, "loadPlugin() error. exiting here?")
return
}
// attempt to write out the file from the internal resource
@ -230,36 +226,6 @@ func loadfile(filename string) *plugin.Plugin {
return plug
}
/*
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
func send(p *Node, c *Node) {
for _, aplug := range allPlugins {
log(debugPlugin, "Send() aplug =", aplug.name, "type=", c.widget.Type, "action=", c.widget.Action, "name=", c.widget.Name)
if (aplug.Send == nil) {
log(debugPlugin, "Failed. Send() == nil for", aplug.name)
continue
}
aplug.Send(&c.parent.widget, &c.widget)
}
}
*/
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
/*
func action(a *toolkit.Action) {
for _, aplug := range allPlugins {
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.Type)
if (aplug.Action == nil) {
log(debugPlugin, "Failed Action() == nil for", aplug.name)
continue
}
aplug.Action(a)
}
}
*/
// Sends a widget and what to do with it to the plugin
// parent = n, child = c
@ -268,16 +234,19 @@ func action(a *toolkit.Action) {
func newaction(a *toolkit.Action, n *Node, where *Node) {
if (n != nil) {
a.Widget = &n.widget
a.WidgetId = n.id
a.WidgetType = n.widget.Type
a.ActionType = a.ActionType
}
// action(&a, newNode, n)
// newaction(&a, newNode, n)
if (where != nil) {
log(debugGui, "Action() START on where X,Y, Next X,Y =", where.Name, where.X, where.Y, where.NextX, where.NextY)
a.Where = &where.widget
a.ParentId = where.id
switch where.widget.Type {
case toolkit.Grid:
where.Dump(true)
// where.Dump(true)
log(debugGui, "Action() START on Grid (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
//
// fix values here if they are invalid. Index starts at 1
@ -288,15 +257,15 @@ func newaction(a *toolkit.Action, n *Node, where *Node) {
where.NextY = 1
}
//
a.Where.X = where.NextX
a.Where.Y = where.NextY
a.X = where.NextX
a.Y = where.NextY
log(debugGui, "Action() END on Grid (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
default:
}
}
for _, aplug := range allPlugins {
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.Type)
log(debugPlugin, "Action() aplug =", aplug.name, "Action type=", a.ActionType)
if (aplug.Action == nil) {
log(debugPlugin, "Failed Action() == nil for", aplug.name)
continue
@ -307,19 +276,19 @@ func newaction(a *toolkit.Action, n *Node, where *Node) {
if (where != nil) {
switch where.widget.Type {
case toolkit.Grid:
log(debugNow, "Action() START size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
log(logInfo, "Action() START size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
where.NextY += 1
if (where.NextY > where.Y) {
where.NextX += 1
where.NextY = 1
}
log(debugNow, "Action() END size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
log(logInfo, "Action() END size (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
where.Name = "jwc gridlaksdfjkl"
where.Width = 320
where.Height = 240
// where.NextX = 5
// where.NextY = 7
where.Dump(true)
// where.Dump(logInfo)
default:
}
}

59
redraw.go Normal file
View File

@ -0,0 +1,59 @@
package gui
import (
"git.wit.org/wit/gui/toolkit"
)
// This recreates the whole GUI for a plugin
func Redraw(s string) {
var p *aplug
log(logNow, "attempt to feed the binary tree to", s)
for _, aplug := range allPlugins {
log("Loaded plugin:", aplug.name, aplug.filename)
if (aplug.name == s) {
log("Found plugin:", aplug.name, aplug.filename)
p = aplug
}
}
if (p == nil) {
log("Plugin", s, "is not loaded")
return
}
Config.rootNode.Redraw(p)
}
// func (n *Node) ListChildren(dump bool, dropdown *Node, mapNodes map[string]*Node) {
func (n *Node) Redraw(p *aplug) {
if (n == nil) {
return
}
n.redo(p)
for _, child := range n.children {
child.Redraw(p)
}
return
}
func (n *Node) redo(p *aplug) {
log(logNow, "redo() on n.Widget")
var a *toolkit.Action
a = new(toolkit.Action)
a.Name = n.Name
a.Text = n.Text
a.ActionType = toolkit.Add
a.WidgetType = n.WidgetType
a.WidgetId = n.id
a.Width = n.Width
a.Height = n.Height
if (n.parent == nil) {
a.ParentId = 0
} else {
a.ParentId = n.parent.id
}
p.Action(a)
}

View File

@ -10,7 +10,7 @@ func (n *Node) NewSlider(name string, x int, y int) *Node {
})
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.X = x
a.Y = y
// a.Widget = &newNode.widget

View File

@ -10,7 +10,7 @@ func (n *Node) NewSpinner(name string, x int, y int) *Node {
})
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.X = x
a.Y = y
// a.Widget = &newNode.widget

View File

@ -2,6 +2,7 @@ package gui
import (
"git.wit.org/wit/gui/toolkit"
"sync"
)
//
@ -32,9 +33,9 @@ type GuiArgs struct {
type GuiConfig struct {
// This is the master node. The Binary Tree starts here
master *Node
rootNode *Node
// A node off of master for passing debugging flags
// A node off of rootNode for passing debugging flags
flag *Node
// These are shortcuts to pass default values to make a new window
@ -56,10 +57,16 @@ type GuiConfig struct {
// simply the name and the size of whatever GUI element exists
type Node struct {
id int
initOnce sync.Once
widget toolkit.Widget
WidgetType toolkit.WidgetType
Name string
// Title string // what is visable to the user
// Desc string // a name useful for programming
Text string // what is visable to the user
Name string // a name useful for programming
// used for Windows
Width int
@ -83,9 +90,4 @@ type Node struct {
parent *Node
children []*Node
// is keeping
// deprecate these things if they don't really need to exist
// checked bool
// text string
}

7
tab.go
View File

@ -11,8 +11,11 @@ func (n *Node) NewTab(text string) *Node {
newNode := n.New(text, toolkit.Tab, nil)
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
a.Name = text
a.Text = text
newaction(&a, newNode, n)
return newNode
newBox := newNode.NewBox(text, true)
return newBox
}

View File

@ -10,7 +10,7 @@ func (n *Node) NewTextbox(name string) *Node {
})
var a toolkit.Action
a.Type = toolkit.Add
a.ActionType = toolkit.Add
// a.Widget = &newNode.widget
// a.Where = &n.widget
// action(&a)

View File

@ -4,40 +4,40 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func show(w *toolkit.Widget) {
if (w == nil) {
func show(a *toolkit.Action) {
if (a == nil) {
log(debugError, "nil is probably already hidden")
return
}
log(debugError, "show()", w.Name)
log(debugError, "show()", a.WidgetId)
t := mapToolkits[w]
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugToolkit, "show() toolkit struct == nil. for", w.Name)
log(debugError, "show() toolkit struct == nil. for", a.WidgetId)
return
}
if (w.B) {
if (a.B) {
t.uiControl.Show()
} else {
t.uiControl.Hide()
}
}
func enable(w *toolkit.Widget) {
if (w == nil) {
func enable(a *toolkit.Action) {
if (a == nil) {
log(debugError, "nil is probably already hidden")
return
}
log(debugError, "enable()", w.Name)
log(debugError, "enable() name =", a.WidgetId)
t := mapToolkits[w]
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugToolkit, "enable() toolkit struct == nil. for", w.Name)
log(debugToolkit, "enable() toolkit struct == nil. for id =", a.WidgetId)
return
}
if (w.B) {
if (a.B) {
t.uiControl.Enable()
} else {
t.uiControl.Disable()
@ -45,21 +45,21 @@ func enable(w *toolkit.Widget) {
}
func pad(a *toolkit.Action) {
if (a.Widget == nil) {
if (a == nil) {
log(debugError, "pad() ERROR: nil is probably already hidden")
return
}
log(debugError, "pad()", a.Widget.Name)
log(debugError, "pad()")
t := mapToolkits[a.Widget]
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugToolkit, "pad() toolkit struct == nil. for", a.Widget.Name)
log(debugError, "pad() toolkit struct == nil. for", a.WidgetId)
return
}
switch a.Widget.Type {
switch t.Type {
case toolkit.Group:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
t.uiGroup.SetMargined(true)
case toolkit.Unmargin:
@ -70,7 +70,7 @@ func pad(a *toolkit.Action) {
t.uiGroup.SetMargined(false)
}
case toolkit.Tab:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
tabSetMargined(t.uiTab, true)
case toolkit.Unmargin:
@ -81,7 +81,7 @@ func pad(a *toolkit.Action) {
tabSetMargined(t.uiTab, false)
}
case toolkit.Window:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
t.uiWindow.SetMargined(true)
case toolkit.Unmargin:
@ -92,7 +92,7 @@ func pad(a *toolkit.Action) {
t.uiWindow.SetBorderless(true)
}
case toolkit.Grid:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
t.uiGrid.SetPadded(true)
case toolkit.Unmargin:
@ -103,7 +103,7 @@ func pad(a *toolkit.Action) {
t.uiGrid.SetPadded(false)
}
case toolkit.Box:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
t.uiBox.SetPadded(true)
case toolkit.Unmargin:
@ -114,128 +114,120 @@ func pad(a *toolkit.Action) {
t.uiBox.SetPadded(false)
}
case toolkit.Textbox:
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.Type)
log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.ActionType)
default:
log(debugError, "TODO: implement pad() for", a.Type)
log(debugError, "TODO: implement pad() for", a.ActionType)
}
}
func move(a *toolkit.Action) {
if (a.Where == nil) {
log(debugError, "move() ERROR: can not move to nil")
return
}
if (a.Widget == nil) {
log(debugError, "move() ERROR: can not move nil")
return
}
log(debugNow, "move()", a.Widget.Name, "to", a.Where.Name)
log(debugNow, "move()", a.WidgetId, "to", a.ParentId)
tWidget := mapToolkits[a.Widget]
tWidget := andlabs[a.WidgetId]
if (tWidget == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.Widget.Name)
log(debugError, "move() ERROR: toolkit struct == nil. for", a.WidgetId)
return
}
tWhere := mapToolkits[a.Where]
if (tWhere == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.Where.Name)
tParent := andlabs[a.ParentId]
if (tParent == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.ParentId)
return
}
switch a.Where.Type {
switch tParent.Type {
case toolkit.Group:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
tWhere.uiGroup.SetMargined(true)
tParent.uiGroup.SetMargined(true)
}
case toolkit.Tab:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true)
// tabSetMargined(tParent.uiTab, true)
}
case toolkit.Window:
switch a.Type {
switch a.ActionType {
case toolkit.Pad:
// t.uiWindow.SetBorderless(false)
}
case toolkit.Grid:
switch a.Type {
switch a.ActionType {
case toolkit.Pad:
// t.uiGrid.SetPadded(true)
}
case toolkit.Box:
log(debugNow, "TODO: move() for a =", a.Type)
log(debugNow, "TODO: move() where =", a.Where.Type)
log(debugNow, "TODO: move() for widget =", a.Widget.Type)
log(debugNow, "TODO: move() for a =", a.ActionType)
log(debugNow, "TODO: move() where =", a.ParentId)
log(debugNow, "TODO: move() for widget =", a.WidgetId)
stretchy = true
tWhere.uiBox.Append(tWidget.uiControl, stretchy)
// log(debugNow, "is there a tWhere parent? =", tWhere.parent)
// tWhere.uiBox.Delete(0)
tParent.uiBox.Append(tWidget.uiControl, stretchy)
// log(debugNow, "is there a tParent parent? =", tParent.parent)
// tParent.uiBox.Delete(0)
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
default:
log(debugError, "TODO: need to implement move() for a =", a.Type)
log(debugError, "TODO: need to implement move() for where =", a.Where.Type)
log(debugError, "TODO: need to implement move() for widget =", a.Widget.Type)
log(debugError, "TODO: need to implement move() for a =", a.ActionType)
log(debugError, "TODO: need to implement move() for where =", a.ParentId)
log(debugError, "TODO: need to implement move() for widget =", a.WidgetId)
}
}
func uiDelete(a *toolkit.Action) {
if (a.Where == nil) {
if (andlabs[a.ParentId] == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete to nil")
return
}
if (a.Widget == nil) {
if (andlabs[a.WidgetId] == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete nil")
return
}
log(debugNow, "uiDelete()", a.Widget.Name, "to", a.Where.Name)
log(debugNow, "uiDelete()", a.WidgetId, "to", a.ParentId)
tWidget := mapToolkits[a.Widget]
tWidget := andlabs[a.WidgetId]
if (tWidget == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.Widget.Name)
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.WidgetId)
return
}
tWhere := mapToolkits[a.Where]
if (tWhere == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.Where.Name)
tParent := andlabs[a.ParentId]
if (tParent == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.ParentId)
return
}
switch a.Where.Type {
switch tParent.Type {
case toolkit.Group:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
tWhere.uiGroup.SetMargined(true)
tParent.uiGroup.SetMargined(true)
}
case toolkit.Tab:
switch a.Type {
switch a.ActionType {
case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true)
// tabSetMargined(tParent.uiTab, true)
}
case toolkit.Window:
switch a.Type {
switch a.ActionType {
case toolkit.Pad:
// t.uiWindow.SetBorderless(false)
}
case toolkit.Grid:
switch a.Type {
switch a.ActionType {
case toolkit.Pad:
// t.uiGrid.SetPadded(true)
}
case toolkit.Box:
log(debugNow, "tWidget.boxC =", tWhere.Name)
log(debugNow, "is there a tWhere parent? =", tWhere.parent)
log(debugNow, "tWidget.boxC =", tParent.Name)
log(debugNow, "is there a tParent parent? =", tParent.parent)
if (tWidget.boxC < 1) {
log(debugNow, "Can not delete from Box. already empty. tWidget.boxC =", tWhere.boxC)
log(debugNow, "Can not delete from Box. already empty. tWidget.boxC =", tParent.boxC)
return
}
tWidget.uiBox.Delete(0)
@ -244,10 +236,10 @@ func uiDelete(a *toolkit.Action) {
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
// tWhere.uiBox.Append(tWidget.uiControl, stretchy)
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
default:
log(debugError, "TODO: need to implement uiDelete() for a =", a.Type)
log(debugError, "TODO: need to implement uiDelete() for where =", a.Where.Type)
log(debugError, "TODO: need to implement uiDelete() for widget =", a.Widget.Type)
log(debugError, "TODO: need to implement uiDelete() for a =", a.ActionType)
log(debugError, "TODO: need to implement uiDelete() for where =", a.ParentId)
log(debugError, "TODO: need to implement uiDelete() for widget =", a.WidgetId)
}
}

View File

@ -8,40 +8,46 @@ import (
)
func actionDump(b bool, a *toolkit.Action) {
log(b, "dump() Widget.Type =", a.Type)
log(b, "dump() Widget.S =", a.S)
log(b, "dump() Widget.I =", a.I)
log(b, "dump() Widget =", a.Widget)
log(b, "dump() Where =", a.Where)
log(b, "actionDump() Widget.Type =", a.ActionType)
log(b, "actionDump() Widget.S =", a.S)
log(b, "actionDump() Widget.I =", a.I)
log(b, "actionDump() WidgetId =", a.WidgetId)
log(b, "actionDump() ParentId =", a.ParentId)
}
func add(a *toolkit.Action) {
if (a.Widget == nil) {
log(debugError, "add() error. w.Widget == nil")
if (andlabs[a.WidgetId] != nil) {
log(debugError, "add() error. can't make a widget that already exists. id =", a.WidgetId)
actionDump(debugError, a)
return
}
if (a.WidgetId == 0) {
log(debugError, "add() error. w.WidgetId == 0")
actionDump(debugError, a)
return
}
// for now, window gets handled without checking where == nil)
if (a.Widget.Type == toolkit.Window) {
if (a.WidgetType == toolkit.Window) {
doWindow(a)
return
}
t := mapToolkits[a.Where]
if (t == nil) {
if (andlabs[a.ParentId] == nil) {
// listMap(debugError) // memory corruption?
log(debugError, "add() Widget.Name =", a.Widget.Name, a.Widget.Type)
// log(debugError, "add() Where.Name =", a.Where.Name)
log(debugError, "ERROR add() ERROR a.Where map to t == nil.")
log(debugError, "add() Widget.Name =", a.Name)
log(debugError, "add() Widget.Type =", a.WidgetType)
log(debugError, "ERROR add() ERROR a.Parent map to t == nil. WidgetId =", a.WidgetId, "ParentId =", a.ParentId)
exit("can not add()")
return
}
switch a.Widget.Type {
switch a.WidgetType {
case toolkit.Window:
doWindow(a)
return
case toolkit.Tab:
doTab(a)
newTab(a)
return
case toolkit.Label:
newLabel(a)
@ -80,7 +86,7 @@ func add(a *toolkit.Action) {
newImage(a)
return
default:
log(debugError, "add() error TODO: ", a.Widget.Type, a.Widget.Name)
log(debugError, "add() error TODO: ", a.WidgetType, a.Name)
}
}
@ -109,18 +115,34 @@ func add(a *toolkit.Action) {
// -- (0,1) -- (1,1) -- (1,1) --
// -----------------------------
func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
log(debugAction, "place() START", a.Widget.Type, a.Widget.Name)
log(debugAction, "place() START", a.WidgetType, a.Name)
// add the structure to the array
if (andlabs[a.WidgetId] == nil) {
log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId)
andlabs[a.WidgetId] = newt
newt.Type = a.WidgetType
} else {
log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId)
log(debugError, "THIS IS BAD")
}
if (newt.uiControl == nil) {
log(debugError, "place() ERROR uiControl == nil", a.Where.Type, a.Where.Name)
log(debugError, "place() ERROR uiControl == nil", a.ParentId)
return false
}
switch a.Where.Type {
where := andlabs[a.ParentId]
if (where == nil) {
log(debugError, "place() ERROR where == nil", a.ParentId)
return false
}
switch where.Type {
case toolkit.Grid:
log(debugGrid, "add() Grid try at Where X,Y =", a.Where.X, a.Where.Y)
newt.gridX = a.Where.X
newt.gridY = a.Where.Y
log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y)
newt.gridX = a.X
newt.gridY = a.Y
log(debugGrid, "add() Grid try at gridX,gridY", newt.gridX, newt.gridY)
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
t.uiGrid.Append(newt.uiControl,
@ -130,14 +152,14 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
case toolkit.Group:
if (t.uiBox == nil) {
t.uiGroup.SetChild(newt.uiControl)
log(debugGrid, "add() hack Group to use this as the box?", a.Widget.Name, a.Widget.Type)
log(debugGrid, "add() hack Group to use this as the box?", a.Name, a.WidgetType)
t.uiBox = newt.uiBox
} else {
t.uiBox.Append(newt.uiControl, stretchy)
}
return true
case toolkit.Tab:
t.uiBox.Append(newt.uiControl, stretchy)
t.uiTab.Append(a.Text, newt.uiControl)
t.boxC += 1
return true
case toolkit.Box:
@ -148,7 +170,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
t.uiWindow.SetChild(newt.uiControl)
return true
default:
log(debugError, "add() how?", a.Where.Type)
log(debugError, "add() how?", a.ParentId)
}
return false
}

View File

@ -9,19 +9,17 @@ import (
// make new Box here
func newBox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newBox()", w.Name)
log(debugToolkit, "newBox()", a.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "newBox() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newBox() toolkit struct == nil. name=", a.Name)
listMap(debugToolkit)
}
newt := t.rawBox(w.Name, a.B)
newt := t.rawBox(a.Text, a.B)
newt.boxC = 0
place(a, t, newt)
mapWidgetsToolkits(a, newt)
andlabs[a.WidgetId] = newt
}
// make new Box using andlabs/ui

View File

@ -10,27 +10,27 @@ import (
func newButton(a *toolkit.Action) {
var t, newt *andlabsT
var b *ui.Button
w := a.Widget
log(debugToolkit, "newButton()", w.Name)
log(debugToolkit, "newButton()", a.Name)
t = mapToolkits[a.Where]
t = andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "newButton() toolkit struct == nil. name=", a.Where.Name, w.Name)
log(debugToolkit, "newButton() toolkit struct == nil. name=", a.Name)
return
}
newt = new(andlabsT)
b = ui.NewButton(w.Name)
b = ui.NewButton(a.Text)
newt.uiButton = b
newt.uiControl = b
newt.tw = w
newt.tw = a.Widget
newt.Type = a.WidgetType
newt.parent = t
b.OnClicked(func(*ui.Button) {
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
place(a, t, newt)
mapWidgetsToolkits(a, newt)
// mapWidgetsToolkits(a, newt)
}

View File

@ -6,10 +6,13 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
log(debugToolkit, "newCheckbox()", w.Name, w.Type)
func (t *andlabsT) newCheckbox(a *toolkit.Action) *andlabsT {
var newt andlabsT
w := a.Widget
log(debugToolkit, "newCheckbox()", w.Name, w.Type)
newt.tw = w
newt.Type = w.Type
newt.wId = a.WidgetId
newt.uiCheckbox = ui.NewCheckbox(w.Name)
newt.uiControl = newt.uiCheckbox
@ -17,7 +20,7 @@ func (t *andlabsT) newCheckbox(w *toolkit.Widget) *andlabsT {
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
newt.tw.B = newt.checked()
log(debugChange, "val =", newt.tw.B)
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
return &newt
@ -28,16 +31,13 @@ func (t *andlabsT) checked() bool {
}
func newCheckbox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCheckbox()", w.Name)
log(debugToolkit, "newCheckbox()", a.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
listMap(debugError)
return
}
newt := t.newCheckbox(w)
newt := t.newCheckbox(a)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -6,11 +6,14 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func (t *andlabsT) newCombobox(w *toolkit.Widget) *andlabsT {
func (t *andlabsT) newCombobox(a *toolkit.Action) *andlabsT {
var newt andlabsT
w := a.Widget
log(debugToolkit, "newCombobox() START", w.Name)
newt.tw = w
newt.wId = a.WidgetId
newt.Type = w.Type
s := ui.NewEditableCombobox()
newt.uiEditableCombobox = s
newt.uiControl = s
@ -21,7 +24,7 @@ func (t *andlabsT) newCombobox(w *toolkit.Widget) *andlabsT {
s.OnChanged(func(spin *ui.EditableCombobox) {
newt.tw.S = spin.Text()
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
return &newt
@ -42,17 +45,14 @@ func (t *andlabsT) AddComboboxName(title string) {
}
func newCombobox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCombobox()", w.Name)
log(debugToolkit, "newCombobox()", a.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", a.Name)
listMap(debugToolkit)
return
}
newt := t.newCombobox(w)
newt := t.newCombobox(a)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -4,7 +4,7 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func (t *andlabsT) commonChange(tw *toolkit.Widget) {
func (t *andlabsT) commonChange(tw *toolkit.Widget, wId int) {
log(debugChange, "commonChange() START widget =", t.tw.Name, t.tw.Type)
if (tw == nil) {
log(true, "commonChange() What the fuck. there is no widget t.tw == nil")
@ -15,23 +15,21 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget) {
return
}
tw.Custom()
if (andlabs[wId] == nil) {
log(debugError, "commonChange() ERROR: wId map == nil", wId)
return
}
sendToChan(wId)
log(debugChange, "commonChange() END Widget.Custom()", t.tw.Name, t.tw.Type)
}
func dump(p *toolkit.Widget, c *toolkit.Widget, b bool) {
log(b, "Parent:")
pt := mapToolkits[p]
if (pt == nil) {
log(b, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
func sendToChan(i int) {
if (callback == nil) {
log(debugError, "commonChange() SHOULD SEND int back here, but callback == nil", i)
return
}
pt.Dump(b)
log(b, "Child:")
ct := mapToolkits[c]
if (ct == nil) {
log(b, "Trying to do something on a widget that doesn't work or doesn't exist or something", c)
return
}
ct.Dump(b)
log(debugError, "commonChange() Running callback() i =", i)
callback(i)
}

View File

@ -90,6 +90,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
return
}
/*
log(b, "widget.Name =", w.Name)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
@ -99,6 +100,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
*/
}
/*

View File

@ -6,21 +6,21 @@ 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)
func destroy(pId int, cId int) {
log(true, "delete()", pId, cId)
pt := mapToolkits[p]
ct := mapToolkits[c]
pt := andlabs[pId]
ct := andlabs[cId]
if (ct == nil) {
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", c.Name, c.Type)
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", pId, cId)
// this pukes out a whole universe of shit
// listMap()
return
}
switch ct.tw.Type {
switch ct.Type {
case toolkit.Button:
log(true, "Should delete Button here:", c.Name)
log(true, "Should delete Button here:", ct.Name)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
@ -38,16 +38,15 @@ func destroy(p *toolkit.Widget, c *toolkit.Widget) {
}
case toolkit.Window:
log(true, "Should delete Window here:", c.Name)
log(true, "Should delete Window here:", ct.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.tw.Type, pt.tw.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.tw.Type, ct.tw.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)
log(true, "Fuckit, let's destroy a button")
if (ct.uiButton != nil) {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()

View File

@ -6,11 +6,14 @@ import (
"git.wit.org/wit/gui/toolkit"
)
func (t *andlabsT) newDropdown(w *toolkit.Widget) *andlabsT {
func (t *andlabsT) newDropdown(a *toolkit.Action) *andlabsT {
var newt andlabsT
log(debugToolkit, "gui.Toolbox.newDropdown() START", w.Name)
w := a.Widget
log(debugToolkit, "gui.Toolbox.newDropdown() START", a.Name)
newt.tw = w
newt.Type = w.Type
newt.wId = a.WidgetId
s := ui.NewCombobox()
newt.uiCombobox = s
newt.uiControl = s
@ -26,7 +29,7 @@ func (t *andlabsT) newDropdown(w *toolkit.Widget) *andlabsT {
newt.text = "error"
}
newt.tw.S = newt.val[i]
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
return &newt
@ -53,9 +56,9 @@ func (t *andlabsT) SetDropdown(i int) {
}
func AddDropdownName(a *toolkit.Action) {
log(debugToolkit, "gui.andlabs.AddDropdownName()", a.Widget.Name, "add:", a.S)
log(debugToolkit, "gui.andlabs.AddDropdownName()", a.WidgetId, "add:", a.S)
t := mapToolkits[a.Widget]
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", a.Widget.Name, a.S)
listMap(debugToolkit)
@ -64,31 +67,30 @@ func AddDropdownName(a *toolkit.Action) {
t.AddDropdownName(a.S)
}
func SetDropdownName(w *toolkit.Widget, s string) {
log(debugChange, "gui.andlabs.SetDropdown()", w.Name, ",", s)
func SetDropdownName(a *toolkit.Action, s string) {
log(debugChange, "gui.andlabs.SetDropdown()", a.WidgetId, ",", s)
t := mapToolkits[w]
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugError, "ERROR: SetDropdown() FAILED mapToolkits[w] == nil. name=", w.Name, s)
log(debugError, "ERROR: SetDropdown() FAILED mapToolkits[w] == nil. name=", a.WidgetId, s)
listMap(debugError)
return
}
t.SetDropdown(1)
// TODO: send back to wit/gui goroutine with the chan
t.tw.S = s
}
func newDropdown(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "gui.andlabs.newDropdown()", w.Name)
log(debugToolkit, "gui.andlabs.newDropdown()", a.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "go.andlabs.newDropdown() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "go.andlabs.newDropdown() toolkit struct == nil. name=", a.WidgetId)
listMap(debugToolkit)
return
}
newt := t.newDropdown(w)
newt := t.newDropdown(a)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
// mapWidgetsToolkits(a, newt)
}

View File

@ -14,9 +14,7 @@ import (
// -----------------------------
func newGrid(a *toolkit.Action) {
var newt *andlabsT
log(debugToolkit, "newGrid()", a.Widget.Name, "to", a.Where.Type)
t := mapToolkits[a.Where]
log(debugToolkit, "newGrid()", a.WidgetId, "to", a.ParentId)
newt = new(andlabsT)
@ -24,9 +22,10 @@ func newGrid(a *toolkit.Action) {
newt.uiGrid = c
newt.uiControl = c
newt.tw = a.Widget
newt.Type = toolkit.Grid
newt.gridX = 0
newt.gridY = 0
t := andlabs[a.ParentId]
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -9,17 +9,15 @@ import (
func newGroup(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "NewGroup()", w.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "NewGroup() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "NewGroup() toolkit struct == nil. name=", w.Name)
listMap(debugToolkit)
}
newt := t.rawGroup(w.Name)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}
// make new Group here
@ -34,13 +32,5 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
newt.uiGroup = g
newt.uiControl = g
// hbox := ui.NewVerticalBox()
// hbox.SetPadded(padded)
// g.SetChild(hbox)
// newt.uiBox = hbox
// newt.uiWindow = t.uiWindow
// newt.uiTab = t.uiTab
return &newt
}

View File

@ -10,17 +10,15 @@ import (
// make new Image here
func newImage(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newImage()", w.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "newImage() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newImage() toolkit struct == nil. name=", w.Name)
listMap(debugToolkit)
}
newt := t.rawImage(w.Name)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}
// make new Image using andlabs/ui

View File

@ -12,7 +12,7 @@ func newLabel(a *toolkit.Action) {
w := a.Widget
log(debugToolkit, "NewLabel()", w.Name)
t := mapToolkits[a.Where]
t := andlabs[a.ParentId]
if (t == nil) {
listMap(debugError)
log(debugError, "ERROR newLabel() listMap()")
@ -30,5 +30,4 @@ func newLabel(a *toolkit.Action) {
newt.uiControl = c
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -1,137 +1,25 @@
//
// version v1.2
//
// I like things to be easy.
//
// this means all the log settings are in one place. it should allow
// things to be over-ridden externally to the library
// but still allow command line --args to pass debugging settings
//
// I also have a generic sleep() and exit() in here because it's simple
//
// Usage:
//
// log("something", foo, bar)
// var DEBUG bool = true
// log(DEBUG, "something else", someOtherVariable) # if DEBUG == false, return doing nothing
// log(SPEW, "something else", someOtherVariable) # this get's sent to spew.Dump(). Very useful for debugging!
//
package main
import (
"os"
"runtime"
"runtime/pprof"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
// "net"
witlog "git.wit.org/wit/gui/log"
)
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
*/
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
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/Andlabs"
}
if (reflect.TypeOf(a[0]) == reflect.TypeOf(SPEW)) {
// a = a[1:]
a[0] = "GUI/Toolkit/Andlabs"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
witlog.Where = "wit/gui/andlabs"
witlog.Log(a...)
}
func loggo() {
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
func sleep(a ...any) {
witlog.Sleep(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 exit(a ...any) {
witlog.Exit(a...)
}

View File

@ -2,7 +2,7 @@ package main
import (
"embed"
"git.wit.org/wit/gui/toolkit"
// "git.wit.org/wit/gui/toolkit"
"github.com/andlabs/ui"
// the _ means we only need this for the init()
@ -43,8 +43,10 @@ func Init() {
// log(debugToolkit, "gui/toolkit init() Setting defaultBehavior = true")
setDefaultBehavior(true)
mapWidgets = make(map[*andlabsT]*toolkit.Widget)
mapToolkits = make(map[*toolkit.Widget]*andlabsT)
// mapWidgets = make(map[*andlabsT]*toolkit.Widget)
// mapToolkits = make(map[*toolkit.Widget]*andlabsT)
andlabs = make(map[int]*andlabsT)
}
// TODO: properly exit the plugin since Quit() doesn't do it

View File

@ -31,43 +31,55 @@ func Action(a *toolkit.Action) {
rawAction(a)
}
if (callback == nil) {
if (a.Callback != nil) {
log(debugNow, "setting Callback", a.Callback)
callback = a.Callback
}
}
// f()
Queue(f)
}
func rawAction(a *toolkit.Action) {
log(debugAction, "Action() START a.Type =", a.Type)
log(debugAction, "Action() START a.ActionType =", a.ActionType)
log(debugAction, "Action() START a.S =", a.S)
log(debugAction, "Action() START a.Widget =", a.Widget)
switch a.Type {
log(logInfo, "Action() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
switch a.WidgetType {
case toolkit.Flag:
flag(a)
return
}
switch a.ActionType {
case toolkit.Add:
add(a)
case toolkit.Show:
a.Widget.B = true
show(a.Widget)
show(a)
case toolkit.Hide:
a.Widget.B = false
show(a.Widget)
show(a)
case toolkit.Enable:
a.Widget.B = true
enable(a.Widget)
enable(a)
case toolkit.Disable:
a.Widget.B = false
enable(a.Widget)
enable(a)
case toolkit.Get:
setText(a)
case toolkit.GetText:
switch a.Widget.Type {
case toolkit.Textbox:
t := mapToolkits[a.Widget]
t := andlabs[a.WidgetId]
a.S = t.s
}
case toolkit.Set:
setText(a)
case toolkit.SetFlag:
flag(a)
case toolkit.SetText:
setText(a)
case toolkit.AddText:
@ -82,15 +94,13 @@ func rawAction(a *toolkit.Action) {
pad(a)
case toolkit.Delete:
uiDelete(a)
case toolkit.Flag:
flag(a)
case toolkit.Move:
log(debugNow, "attempt to move() =", a.Type, a.Widget)
log(debugNow, "attempt to move() =", a.ActionType, a.Widget)
move(a)
default:
log(debugError, "Action() Unknown =", a.Type, a.Widget)
log(debugError, "Action() Unknown =", a.ActionType, a.Widget)
}
log(debugAction, "Action() END =", a.Type, a.Widget)
log(debugAction, "Action() END =", a.ActionType, a.Widget)
}
func flag(a *toolkit.Action) {
@ -122,70 +132,70 @@ func flag(a *toolkit.Action) {
}
func setText(a *toolkit.Action) {
w := a.Widget
if (w == nil) {
log(debugError, "setText error. w.Widget == nil")
t := andlabs[a.WidgetId]
if (t == nil) {
log(debugError, "setText error. andlabs[id] == nil", a.WidgetId)
actionDump(debugError, a)
return
}
t := mapToolkits[w]
log(debugChange, "setText() Attempt on", w.Type, "with", a.S)
log(debugChange, "setText() Attempt on", t.Type, "with", a.S)
switch w.Type {
switch t.Type {
case toolkit.Window:
t.uiWindow.SetTitle(a.S)
case toolkit.Tab:
case toolkit.Group:
t.uiGroup.SetTitle(a.S)
case toolkit.Checkbox:
switch a.Type {
switch a.ActionType {
case toolkit.SetText:
t.uiCheckbox.SetText(a.S)
case toolkit.Get:
w.B = t.uiCheckbox.Checked()
t.tw.B = t.uiCheckbox.Checked()
case toolkit.Set:
t.uiCheckbox.SetChecked(a.B)
w.B = a.B
// TODO: commented out while working on chan
// t.uiCheckbox.SetChecked(a.B)
t.tw.B = a.B
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
case toolkit.Textbox:
switch a.Type {
switch a.ActionType {
case toolkit.Set:
t.uiMultilineEntry.SetText(a.S)
case toolkit.SetText:
t.uiMultilineEntry.SetText(a.S)
case toolkit.Get:
w.S = t.s
t.tw.S = t.s
case toolkit.GetText:
w.S = t.s
t.tw.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
case toolkit.Label:
t.uiLabel.SetText(a.S)
case toolkit.Button:
t.uiButton.SetText(a.S)
case toolkit.Slider:
switch a.Type {
switch a.ActionType {
case toolkit.Get:
w.I = t.uiSlider.Value()
t.tw.I = t.uiSlider.Value()
case toolkit.Set:
t.uiSlider.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
case toolkit.Spinner:
switch a.Type {
switch a.ActionType {
case toolkit.Get:
w.I = t.uiSpinbox.Value()
t.tw.I = t.uiSpinbox.Value()
case toolkit.Set:
t.uiSpinbox.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
case toolkit.Dropdown:
switch a.Type {
switch a.ActionType {
case toolkit.AddText:
AddDropdownName(a)
case toolkit.Set:
@ -199,7 +209,7 @@ func setText(a *toolkit.Action) {
log(debugChange, "i, s", i, s)
if (a.S == s) {
t.uiCombobox.SetSelected(i)
log(debugChange, "setText() Dropdown worked.", w.S)
log(debugChange, "setText() Dropdown worked.", t.tw.S)
return
}
}
@ -213,14 +223,14 @@ func setText(a *toolkit.Action) {
t.uiCombobox.SetSelected(i)
}
case toolkit.Get:
w.S = t.s
t.tw.S = t.s
case toolkit.GetText:
w.S = t.s
t.tw.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
case toolkit.Combobox:
switch a.Type {
switch a.ActionType {
case toolkit.AddText:
t.AddComboboxName(a.S)
case toolkit.Set:
@ -230,13 +240,13 @@ func setText(a *toolkit.Action) {
t.uiEditableCombobox.SetText(a.S)
t.s = a.S
case toolkit.Get:
w.S = t.s
t.tw.S = t.s
case toolkit.GetText:
w.S = t.s
t.tw.S = t.s
default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name)
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
}
default:
log(debugError, "plugin Send() Don't know how to setText on", w.Type, "yet", a.Type)
log(debugError, "plugin Send() Don't know how to setText on", t.tw.Type, "yet", a.ActionType)
}
}

View File

@ -7,19 +7,21 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
// make new node here
log(debugToolkit, w.Name, w.Type, w.X, w.Y)
func (t *andlabsT) newSlider(a *toolkit.Action) *andlabsT {
var newt andlabsT
w := a.Widget
// log(debugToolkit, w.Name, w.Type, w.X, w.Y)
s := ui.NewSlider(w.X, w.Y)
s := ui.NewSlider(a.X, a.Y)
newt.uiSlider = s
newt.uiControl = s
newt.tw = w
newt.Type = toolkit.Slider
newt.wId = a.WidgetId
s.OnChanged(func(spin *ui.Slider) {
newt.tw.I = newt.uiSlider.Value()
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
return &newt
@ -28,17 +30,15 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
func newSlider(a *toolkit.Action) {
var newt *andlabsT
w := a.Widget
parentW := a.Where
log(debugToolkit, "newSlider()", w.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugError, "newSlider() ERROR toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugError, "newSlider() ERROR toolkit struct == nil. name=", w.Name)
return
}
w.X = a.X
w.Y = a.Y
newt = t.newSlider(w)
// w.X = a.X
// w.Y = a.Y
newt = t.newSlider(a)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -7,19 +7,21 @@ import (
_ "github.com/andlabs/ui/winmanifest"
)
func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
// make new node here
log(debugToolkit, "newSpinner()", w.X, w.Y)
func (t *andlabsT) newSpinner(a *toolkit.Action) *andlabsT {
var newt andlabsT
w := a.Widget
// log(debugToolkit, "newSpinner()", w.X, w.Y)
s := ui.NewSpinbox(w.X, w.Y)
s := ui.NewSpinbox(a.X, a.Y)
newt.uiSpinbox = s
newt.uiControl = s
newt.tw = w
newt.wId = a.WidgetId
newt.Type = toolkit.Spinner
s.OnChanged(func(s *ui.Spinbox) {
newt.tw.I = newt.uiSpinbox.Value()
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
})
return &newt
@ -28,16 +30,12 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
func newSpinner(a *toolkit.Action) {
var newt *andlabsT
w := a.Widget
parentW := a.Where
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugError, "NewSpinner() toolkit struct == nil. name=", w.Name)
return
}
w.X = a.X
w.Y = a.Y
newt = t.newSpinner(w)
newt = t.newSpinner(a)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -5,14 +5,19 @@ import "git.wit.org/wit/gui/toolkit"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
var andlabs map[int]*andlabsT
var callback func(int)
// stores the raw toolkit internals
type andlabsT struct {
id string
wId int // widget ID
Type toolkit.WidgetType
Name string
// Type toolkit.WidgetType
Width int
Height int
tw *toolkit.Widget
parent *andlabsT

View File

@ -19,36 +19,43 @@ import (
once there is one. If you send a Window here, it will replace
any existing tabs rather than adding a new one
*/
func (t *andlabsT) newTab(name string) *andlabsT {
func (t *andlabsT) newTab(a *toolkit.Action) {
// var w *ui.Window
var newt *andlabsT
log(debugToolkit, "gui.toolkit.AddTab()")
if (t.uiWindow == nil) {
log(debugToolkit, "gui.Toolkit.UiWindow == nil. I can't add a toolbar without window")
return nil
}
log(debugToolkit, "newTab() START", a.WidgetId, a.ParentId)
if (t.uiTab == nil) {
if (t.uiWindow == nil) {
log(debugToolkit, "newTab() uiWindow == nil. I can't add a toolbar without window", a.WidgetId, a.ParentId)
return
}
// this means you have to make a new tab
log(debugToolkit, "gui.toolkit.NewTab() GOOD. This should be the first tab:", name)
newt = rawTab(t.uiWindow, name)
log(debugToolkit, "newTab() GOOD. This should be the first tab:", a.WidgetId, a.ParentId)
newt = rawTab(t.uiWindow, a.Text)
t.uiTab = newt.uiTab
} else {
// this means you have to append a tab
log(debugToolkit, "gui.toolkit.NewTab() GOOD. This should be an additional tab:", name)
newt = t.appendTab(name)
log(debugToolkit, "newTab() GOOD. This should be an additional tab:", a.WidgetId, a.ParentId)
newt = t.appendTab(a.Text)
}
newt.Name = name
// add the structure to the array
if (andlabs[a.WidgetId] == nil) {
log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId)
andlabs[a.WidgetId] = newt
newt.Type = a.Widget.Type
} else {
log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId)
log(debugError, "THIS IS BAD")
}
newt.Name = a.Name
log(debugToolkit, "t:")
t.Dump(debugToolkit)
log(debugToolkit, "newt:")
newt.Dump(debugToolkit)
return newt
}
// This sets _all_ the tabs to Margin = true
@ -64,29 +71,21 @@ func tabSetMargined(tab *ui.Tab, b bool) {
func rawTab(w *ui.Window, name string) *andlabsT {
var newt andlabsT
log(debugToolkit, "gui.toolkit.NewTab() ADD", name)
log(debugToolkit, "rawTab() START", name)
if (w == nil) {
log(debugToolkit, "gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
log(debugToolkit, "gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
log(debugToolkit, "gui.toolkit.NewTab() node.UiWindow == nil. I can't add a tab without a window")
log(debugError, "UiWindow == nil. I can't add a tab without a window")
log(debugError, "UiWindow == nil. I can't add a tab without a window")
log(debugError, "UiWindow == nil. I can't add a tab without a window")
sleep(1)
return nil
}
log(debugToolkit, "gui.toolkit.AddTab() START name =", name)
tab := ui.NewTab()
w.SetMargined(margin)
hbox := ui.NewHorizontalBox() // this makes everything go along the horizon
hbox.SetPadded(padded)
tab.Append(name, hbox)
tabSetMargined(tab, margin) // TODO: run this in the right place(?)
w.SetChild(tab)
newt.uiWindow = w
newt.uiTab = tab
newt.uiControl = tab
newt.uiBox = hbox
log(debugToolkit, "rawTab() END", name)
return &newt
}
@ -120,20 +119,14 @@ func (t *andlabsT) appendTab(name string) *andlabsT {
}
func newTab(a *toolkit.Action) {
parentW := a.Where
w := a.Widget
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
// w := a.Widget
log(debugToolkit, "newTab()", a.ParentId)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "go.andlabs.NewTab() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newTab() parent toolkit == nil. new tab can not be made =", a.ParentId)
log(debugToolkit, "look for a window? check for an existing tab?")
return
}
newt = t.newTab(w.Name)
mapWidgetsToolkits(a, newt)
}
func doTab(a *toolkit.Action) {
newTab(a)
t.newTab(a)
}

View File

@ -17,6 +17,7 @@ func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
newt.Name = w.Name
newt.tw = w
newt.Type = toolkit.Textbox
c.OnChanged(func(spin *ui.MultilineEntry) {
t.s = spin.Text()
@ -29,16 +30,14 @@ func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
func newTextbox(a *toolkit.Action) {
w := a.Widget
parentW := a.Where
log(debugToolkit, "newCombobox()", w.Name)
t := mapToolkits[parentW]
t := andlabs[a.ParentId]
if (t == nil) {
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", parentW.Name, w.Name)
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", w.Name)
listMap(debugToolkit)
return
}
newt := t.newTextbox(w)
place(a, t, newt)
mapWidgetsToolkits(a, newt)
}

View File

@ -1,69 +1,24 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
// "git.wit.org/wit/gui/toolkit"
)
// This is a map between the widgets in wit/gui and the internal structures of gocui
var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT
// var mapWidgets map[*andlabsT]*toolkit.Widget
// var mapToolkits map[*toolkit.Widget]*andlabsT
// This lists out the known mappings
// deprecate and use instead the GUI interface
func listMap(b bool) {
log(b, "listMap() disabled HERE. output too big")
return
for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name)
}
log(b, "listMap() HERE mapToolkits()")
for w, t := range mapToolkits {
log(b, "andlabs =", t, "widget =", w.Name)
for i, t := range andlabs {
log(b, "andlabs =", t, "widgetId =", i)
t.Dump(b)
}
log(b, "listMap() HERE mapWidgets()")
log(b, "listMap() HERE FIXME. output too big")
}
func mapWidgetsToolkits(a *toolkit.Action, t *andlabsT) {
w := a.Widget
if ((mapToolkits[w] == nil) && (mapWidgets[t] == nil)) {
log(debugToolkit, "map a new widget", w, t)
mapToolkits[w] = t
mapWidgets[t] = w
return
}
if (mapToolkits[w] != nil) {
tw := mapToolkits[w]
if (tw == nil) {
// logic corruption somewhere? Have you been deleting things recently?
log(true, "mapToolkits[w] is set, but mapWidgets[t] is nil")
panic("WTF mapWidgets[t] == nil")
}
log(debugToolkit, "mapToolkits[w] is", tw)
if (tw == nil) {
log(debugError, "BAD map? mapWidgets[w] tw == nil")
} else {
log(debugError, "BAD map? mapWidgets[w] is", tw)
tw.Dump(debugError)
}
}
if (mapWidgets[t] != nil) {
wt := mapWidgets[t]
if (mapToolkits[w] == nil) {
// logic corruption somewhere? Have you been deleting things recently?
log(true, "mapWidgets[t] is set, but mapToolkits[w] is nil")
panic("WTF mapToolkits[w] == nil")
}
if (wt == nil) {
log(debugError, "BAD map? mapWidgets[t] wt == nil")
} else {
log(debugError, "BAD map? mapWidgets[t] is", wt)
widgetDump(debugError, wt)
}
}
log(debugToolkit, "map of widget worked", w.Type, ",", w.Name)
}

View File

@ -19,7 +19,7 @@ func newWindow(a *toolkit.Action) {
w := a.Widget
var newt *andlabsT
log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
// log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
if (w == nil) {
log(debugToolkit, "wit/gui plugin error. widget == nil")
@ -27,13 +27,15 @@ func newWindow(a *toolkit.Action) {
}
newt = new(andlabsT)
newt.tw = w
newt.Type = toolkit.Window
newt.wId = a.WidgetId
// menubar bool is if the OS defined border on the window should be used
win := ui.NewWindow(w.Name, w.Width, w.Height, menubar)
win := ui.NewWindow(w.Name, a.Width, a.Height, menubar)
win.SetBorderless(canvas)
win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool {
newt.commonChange(newt.tw)
newt.commonChange(newt.tw, a.WidgetId)
return true
})
win.Show()
@ -42,16 +44,17 @@ func newWindow(a *toolkit.Action) {
// newt.UiWindowBad = win // deprecate this as soon as possible
newt.Name = w.Name
mapWidgetsToolkits(a, newt)
andlabs[a.WidgetId] = newt
return
}
func (t *andlabsT) SetWindowTitle(title string) {
log(debugToolkit, "toolkit NewWindow", t.Name, "title", title)
win := t.uiWindow
if (win != nil) {
win.SetTitle(title)
if (win == nil) {
log(debugError, "Error: no window", t.wId)
} else {
win.SetTitle(title)
log(debugToolkit, "Setting the window title", title)
}
}

191
toolkit/democui/, Normal file
View File

@ -0,0 +1,191 @@
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"errors"
"fmt"
"log"
"github.com/awesome-gocui/gocui"
)
func main() {
g, err := gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
log.Panicln(err)
}
defer g.Close()
g.Cursor = false
g.Mouse = true
g.SetManagerFunc(layout)
if err := keybindings(g); err != nil {
log.Panicln(err)
}
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
log.Panicln(err)
}
}
var initialMouseX, initialMouseY, xOffset, yOffset int
var globalMouseDown, msgMouseDown, movingMsg bool
func layout(g *gocui.Gui) error {
maxX, maxY := g.Size()
if _, err := g.View("msg"); msgMouseDown && err == nil {
moveMsg(g)
}
if v, err := g.SetView("global", -1, -1, maxX, maxY, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Frame = false
}
if v, err := g.SetView("but1", 2, 2, 22, 7, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 1 - line 1")
fmt.Fprintln(v, "Button 1 - line 2")
fmt.Fprintln(v, "Button 1 - line 3")
fmt.Fprintln(v, "Button 1 - line 4")
if _, err := g.SetCurrentView("but1"); err != nil {
return err
}
}
if v, err := g.SetView("but2", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
updateHighlightedView(g)
return nil
}
func keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
for _, n := range []string{"but1", "but2"} {
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
return err
}
}
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
return err
}
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, msgDown); err != nil {
return err
}
return nil
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
func showMsg(g *gocui.Gui, v *gocui.View) error {
var l string
var err error
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
maxX, maxY := g.Size()
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
}
return nil
}
func updateHighlightedView(g *gocui.Gui) {
mx, my := g.MousePosition()
for _, view := range g.Views() {
view.Highlight = false
}
if v, err := g.ViewByPosition(mx, my); err == nil {
v.Highlight = true
}
}
func moveMsg(g *gocui.Gui) {
mx, my := g.MousePosition()
if !movingMsg && (mx != initialMouseX || my != initialMouseY) {
movingMsg = true
}
g.SetView("msg", mx-xOffset, my-yOffset, mx-xOffset+20, my-yOffset+2, 0)
}
func msgDown(g *gocui.Gui, v *gocui.View) error {
initialMouseX, initialMouseY = g.MousePosition()
if vx, vy, _, _, err := g.ViewPosition("msg"); err == nil {
xOffset = initialMouseX - vx
yOffset = initialMouseY - vy
msgMouseDown = true
}
return nil
}
func globalDown(g *gocui.Gui, v *gocui.View) error {
mx, my := g.MousePosition()
if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil {
if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 {
return msgDown(g, v)
}
}
globalMouseDown = true
maxX, _ := g.Size()
msg := fmt.Sprintf("Mouse down at: %d,%d", mx, my)
x := mx - len(msg)/2
if x < 0 {
x = 0
} else if x+len(msg)+1 > maxX-1 {
x = maxX - 1 - len(msg) - 1
}
if v, err := g.SetView("globalDown", x, my-1, x+len(msg)+1, my+1, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.WriteString(msg)
}
return nil
}
func mouseUp(g *gocui.Gui, v *gocui.View) error {
if msgMouseDown {
msgMouseDown = false
if movingMsg {
movingMsg = false
return nil
} else {
g.DeleteView("msg")
}
} else if globalMouseDown {
globalMouseDown = false
g.DeleteView("globalDown")
}
return nil
}

View File

@ -9,3 +9,7 @@ plugin:
objdump:
objdump -t ../democui.so |less
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

49
toolkit/democui/click.go Normal file
View File

@ -0,0 +1,49 @@
package main
import (
"fmt"
"errors"
"strconv"
"github.com/awesome-gocui/gocui"
// "git.wit.org/wit/gui/toolkit"
)
func click(g *gocui.Gui, v *gocui.View) error {
var l string
var err error
log(logNow, "click() START", v.Name())
i, err := strconv.Atoi(v.Name())
if (err != nil) {
log(logNow, "click() Can't find widget. error =", err)
} else {
log(logNow, "click() Found widget id =", i)
if (me.widgets[i] != nil) {
w := me.widgets[i]
log(logNow, "click() Found widget =", w)
}
}
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
maxX, maxY := g.Size()
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
}
// this seems to delete the button(?)
// g.SetViewOnBottom(v.Name())
log(logNow, "click() END")
return nil
}

90
toolkit/democui/common.go Normal file
View File

@ -0,0 +1,90 @@
package main
import (
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func setupWidgetT(a *toolkit.Action) *cuiWidget {
var w *cuiWidget
w = new(cuiWidget)
w.name = a.Name
w.text = a.Text
w.widgetType = a.WidgetType
w.id = a.WidgetId
if (w.id > me.highest) {
me.highest = w.id
}
w.parentId = a.ParentId
me.widgets[w.id] = w
// w.showWidgetPlacement(logNow)
return w
}
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
// gocui.GetColor("#FFAA55") // Dark Purple
func (w *cuiWidget) SetDefaultWidgetColor() {
log(logInfo, "SetDefaultWidgetColor() on", w.widgetType, w.name)
if (w.v == nil) {
log(logError, "SetDefaultWidgetColor() failed on view == nil")
return
}
w.SetDefaultHighlight()
switch w.widgetType {
case toolkit.Button:
w.v.BgColor = gocui.ColorGreen
w.v.FrameColor = gocui.ColorGreen
case toolkit.Checkbox:
w.v.BgColor = gocui.GetColor("#FFAA55") // Dark Purple
w.v.FrameColor = gocui.GetColor("#FFEE11")
case toolkit.Dropdown:
w.v.BgColor = gocui.ColorCyan
w.v.FrameColor = gocui.ColorGreen
case toolkit.Textbox:
w.v.BgColor = gocui.ColorYellow
w.v.FrameColor = gocui.ColorGreen
case toolkit.Slider:
w.v.BgColor = gocui.GetColor("#FFAA55") // Dark Purple
w.v.FrameColor = gocui.ColorRed
case toolkit.Label:
w.v.FrameColor = gocui.ColorRed
default:
w.v.BgColor = gocui.ColorYellow
}
}
// SetColor("#FFAA55") // purple
func (w *cuiWidget) SetColor(c string) {
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorCyan
w.v.SelFgColor = gocui.ColorBlack
switch c {
case "Green":
w.v.BgColor = gocui.ColorGreen
case "Purple":
w.v.BgColor = gocui.GetColor("#FFAA55")
case "Yellow":
w.v.BgColor = gocui.ColorYellow
case "Blue":
w.v.BgColor = gocui.ColorBlue
case "Red":
w.v.BgColor = gocui.ColorRed
default:
w.v.BgColor = gocui.GetColor(c)
}
}
func (w *cuiWidget) SetDefaultHighlight() {
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorGreen
w.v.SelFgColor = gocui.ColorBlack
}

View File

@ -1,86 +1,46 @@
package main
import "git.wit.org/wit/gui/toolkit"
import (
"fmt"
"strconv"
var defaultBehavior bool = true
"git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
)
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
// 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
me.defaultBehavior = s
if (me.defaultBehavior) {
log(logInfo, "Setting this toolkit to use the default behavior.")
log(logInfo, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
me.stretchy = false
me.padded = true
me.menubar = true
me.margin = true
me.canvas = false
me.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.")
log(logInfo, "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 {
func actionDump(b bool, a *toolkit.Action) {
if (a == nil) {
log(b, "action = nil")
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)
log(b, "a.Name =", a.Name)
log(b, "a.Text =", a.Text)
log(b, "a.WidgetId =", a.WidgetId)
log(b, "a.ParentId =", a.ParentId)
log(b, "a.B =", a.B)
log(b, "a.S =", a.S)
widgetDump(b, a.Widget)
}
*/
func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) {
@ -88,6 +48,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
return
}
/*
log(b, "widget.Name =", w.Name)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
@ -97,10 +58,66 @@ func widgetDump(b bool, w *toolkit.Widget) {
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
*/
}
/*
func GetDebugToolkit () bool {
return debugToolkit
func dumpWidgets(g *gocui.Gui, v *gocui.View) {
for _, view := range g.Views() {
i, _ := strconv.Atoi(view.Name())
if (me.widgets[i] != nil) {
continue
}
log(logNow, "dump() not a widget. view.Name =", view.Name())
}
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
w.showWidgetPlacement(logNow, "")
if (w.v == nil) {
log(logError, "dump() ERROR w.v == nil")
} else {
if (strconv.Itoa(i) != w.v.Name()) {
log(logError, "dump() ERROR unequal str.Itoa(i) =", strconv.Itoa(i))
log(logError, "dump() ERROR unequal w.v.Name() =", w.v.Name())
}
}
}
}
func adjustWidgets() {
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
p := me.widgets[w.parentId]
if (p != nil) {
w.setParentLogical(p)
}
}
}
func (w *cuiWidget) showWidgetPlacement(b bool, s string) {
log(b, "dump()", s,
fmt.Sprintf("(wId,pId)=(%3d,%3d)", w.id, w.parentId),
fmt.Sprintf("real()=(%3d,%3d,%3d,%3d)", w.realSize.w0, w.realSize.h0, w.realSize.w1, w.realSize.h1),
"next()=(", w.nextX, ",", w.nextY, ")",
"logical()=(", w.logicalSize.w0, ",", w.logicalSize.h0, ",", w.logicalSize.w1, ",", w.logicalSize.h1, ")",
w.widgetType, ",", w.name)
if (w.realWidth != (w.realSize.w1 - w.realSize.w0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
if (w.realHeight != (w.realSize.h1 - w.realSize.h0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
}
*/

46
toolkit/democui/help.go Normal file
View File

@ -0,0 +1,46 @@
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"errors"
"fmt"
"github.com/awesome-gocui/gocui"
)
func addHelp() {
me.baseGui.SetManagerFunc(helplayout)
}
func helplayout(g *gocui.Gui) error {
var err error
maxX, _ := g.Size()
help, err := g.SetView("help", maxX-32, 0, maxX-1, 12, 0)
if err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
help.SelBgColor = gocui.ColorGreen
help.SelFgColor = gocui.ColorBlack
fmt.Fprintln(help, "KEYBINDINGS")
fmt.Fprintln(help, "Enter: Click Button")
fmt.Fprintln(help, "Tab/Space: Switch Buttons")
fmt.Fprintln(help, "")
fmt.Fprintln(help, "h: Help")
fmt.Fprintln(help, "Backspace: Delete Button")
fmt.Fprintln(help, "Arrow keys: Move Button")
fmt.Fprintln(help, "t: Move Button to the top")
fmt.Fprintln(help, "b: Move Button to the button")
fmt.Fprintln(help, "STDOUT: /tmp/witgui.log")
fmt.Fprintln(help, "Ctrl-C or Q: Exit")
if _, err := g.SetCurrentView("help"); err != nil {
return err
}
}
me.helpLabel = help
return nil
}

View File

@ -0,0 +1,45 @@
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"github.com/awesome-gocui/gocui"
)
func defaultKeybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
for _, n := range []string{"but1", "but2", "help", "but3"} {
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
return err
}
}
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
return err
}
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, msgDown); err != nil {
return err
}
addDebugKeys(g)
return nil
}
// dump out the widgets
func addDebugKeys(g *gocui.Gui) {
g.SetKeybinding("", 'd', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
dumpWidgets(g, v)
return nil
})
g.SetKeybinding("", 'r', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
adjustWidgets()
return nil
})
}

View File

@ -1,135 +1,30 @@
//
// 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"
witlog "git.wit.org/wit/gui/log"
)
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
*/
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
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...)
witlog.Where = "wit/democui"
witlog.Log(a...)
}
func logindent(depth int, format string, a ...interface{}) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
// newFormat := tabs + strconv.Itoa(depth) + " " + format
newFormat := tabs + format
log(debugToolkit, newFormat, a)
func exit(a ...any) {
witlog.Exit(a...)
}
func setOutput(f *os.File) {
golog.SetOutput(f)
witlog.SetOutput(f)
}

67
toolkit/democui/main.go Normal file
View File

@ -0,0 +1,67 @@
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
import (
"os"
)
/*
func OnExit(f func(string)) {
Custom = f
}
*/
func Init() {
log(logInfo, "Init() of democui")
me.widgets = make(map[int]*cuiWidget)
me.defaultWidth = 10
me.defaultHeight = 2
me.defaultBehavior = true
}
func Exit() {
// TODO: exit correctly
me.baseGui.Close()
}
/*
func mouseClick(name string) {
// output screws up the console. Need to fix this by redirecting all console output to a file from log.Println()
// log.Println("g.Close()")
// g.Close()
log("Found andlabs Running custom function for the mouse click")
Custom(name)
// panic("got andlabs")
}
*/
func Main(f func()) {
log("start Init()")
outf, err := os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
exit("error opening file: %v", err)
}
defer outf.Close()
setOutput(outf)
log("This is a test log entry")
MouseMain()
}
/*
func StartConsoleMouse() {
defer g.Close()
log("start Main()")
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
exit(err)
}
log("exit Main()")
}
*/

View File

@ -7,85 +7,54 @@ package main
import (
"errors"
"fmt"
"os"
"github.com/awesome-gocui/gocui"
)
var g *gocui.Gui
var err error
var Custom func(string)
func OnExit(f func(string)) {
Custom = f
}
func Exit() {
g.Close()
}
func mouseClick(name string) {
// output screws up the console. Need to fix this by redirecting all console output to a file from log.Println()
// log.Println("g.Close()")
// g.Close()
log("Found andlabs Running custom function for the mouse click")
Custom(name)
// panic("got andlabs")
}
func Init() {
log("start Init()")
f, err := os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
func MouseMain() {
g, err := gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
exit("error opening file: %v", err)
panic(err)
}
defer f.Close()
defer g.Close()
setOutput(f)
log("This is a test log entry")
g, err = gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
exit(err)
}
me.baseGui = g
g.Cursor = true
g.Mouse = true
g.SetManagerFunc(layout)
if err := keybindings(g); err != nil {
exit(err)
if err := defaultKeybindings(g); err != nil {
panic(err)
}
log("exit Init()")
}
func StartConsoleMouse() {
defer g.Close()
log("start Main()")
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
exit(err)
panic(err)
}
log("exit Main()")
}
func layout(g *gocui.Gui) error {
if v, err := g.SetView("but1", 2, 2, 22, 17, 0); err != nil {
maxX, maxY := g.Size()
if _, err := g.View("msg"); msgMouseDown && err == nil {
moveMsg(g)
}
if v, err := g.SetView("global", -1, -1, maxX, maxY, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Frame = false
}
if v, err := g.SetView("but1", 2, 2, 22, 7, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "andlabs")
fmt.Fprintln(v, "addDemoTab")
fmt.Fprintln(v, "DemoToolkitWindow")
fmt.Fprintln(v, "DebugWindow")
fmt.Fprintln(v, "do nothing")
fmt.Fprintln(v, "exit")
fmt.Fprintln(v, "Button 1 - line 1")
fmt.Fprintln(v, "Button 1 - line 2")
fmt.Fprintln(v, "Button 1 - line 3")
fmt.Fprintln(v, "Button 1 - line 4")
if _, err := g.SetCurrentView("but1"); err != nil {
return err
}
@ -94,59 +63,12 @@ func layout(g *gocui.Gui) error {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
if v, err := g.SetView("but3", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
if v, err := g.SetView("but4", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
if v, err := g.SetView("but5", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
return nil
}
func keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
for _, n := range []string{"but1", "but2"} {
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
return err
}
}
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, delMsg); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseRight, gocui.ModNone, delMsg); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseMiddle, gocui.ModNone, delMsg); err != nil {
return err
}
helplayout(g)
updateHighlightedView(g)
return nil
}
@ -168,18 +90,80 @@ func showMsg(g *gocui.Gui, v *gocui.View) error {
}
maxX, maxY := g.Size()
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
mouseClick(l)
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
}
return nil
}
func delMsg(g *gocui.Gui, v *gocui.View) error {
// Error check removed, because delete could be called multiple times with the above keybindings
g.DeleteView("msg")
func updateHighlightedView(g *gocui.Gui) {
mx, my := g.MousePosition()
for _, view := range g.Views() {
view.Highlight = false
}
if v, err := g.ViewByPosition(mx, my); err == nil {
v.Highlight = true
}
}
func moveMsg(g *gocui.Gui) {
mx, my := g.MousePosition()
if !movingMsg && (mx != initialMouseX || my != initialMouseY) {
movingMsg = true
}
g.SetView("msg", mx-xOffset, my-yOffset, mx-xOffset+20, my-yOffset+2, 0)
}
func msgDown(g *gocui.Gui, v *gocui.View) error {
initialMouseX, initialMouseY = g.MousePosition()
if vx, vy, _, _, err := g.ViewPosition("msg"); err == nil {
xOffset = initialMouseX - vx
yOffset = initialMouseY - vy
msgMouseDown = true
}
return nil
}
func globalDown(g *gocui.Gui, v *gocui.View) error {
mx, my := g.MousePosition()
if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil {
if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 {
return msgDown(g, v)
}
}
globalMouseDown = true
maxX, _ := g.Size()
msg := fmt.Sprintf("Mouse down at: %d,%d", mx, my)
x := mx - len(msg)/2
if x < 0 {
x = 0
} else if x+len(msg)+1 > maxX-1 {
x = maxX - 1 - len(msg) - 1
}
if v, err := g.SetView("globalDown", x, my-1, x+len(msg)+1, my+1, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.WriteString(msg)
}
return nil
}
func mouseUp(g *gocui.Gui, v *gocui.View) error {
if msgMouseDown {
msgMouseDown = false
if movingMsg {
movingMsg = false
return nil
} else {
g.DeleteView("msg")
}
} else if globalMouseDown {
globalMouseDown = false
g.DeleteView("globalDown")
}
return nil
}

View File

@ -4,112 +4,15 @@ 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()
me.baseGui.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.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")
}
func Action(a *toolkit.Action) {
log(logNow, "Action()", a)
w := setupWidgetT(a)
place(w, a)
log(logInfo, "Action() END")
}

127
toolkit/democui/structs.go Normal file
View File

@ -0,0 +1,127 @@
// LICENSE: same as the go language itself
// Copyright 2023 WIT.COM
// all structures and variables are local (aka lowercase)
// since the plugin should be isolated to access only
// by functions() to insure everything here is run
// inside a dedicated goroutine
package main
import (
"fmt"
"sync"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
// const delta = 1
// It's probably a terrible idea to call this 'me'
var me config
type config struct {
highest int // highest widgetId
baseGui *gocui.Gui // the main gocui handle
widgets map[int]*cuiWidget
callback func(int)
helpLabel *gocui.View
defaultBehavior bool
defaultWidth int
defaultHeight int
nextW int // where the next window or tab flag should go
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
canvas bool // if set to true, the windows are a raw canvas
menubar bool // for windows
stretchy bool // expand things like buttons to the maximum size
padded bool // add space between things like buttons
margin bool // add space around the frames of windows
}
/*
// 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
*/
var (
// g *gocui.Gui
// Custom func(string)
initialMouseX, initialMouseY, xOffset, yOffset int
globalMouseDown, msgMouseDown, movingMsg bool
// err error
)
// the gocui way
// the logical size of the widget
// corner starts at in the upper left corner
type rectType struct {
// this is the gocui way
w0, h0, w1, h1 int // left top right bottom
}
/*
type realSizeT struct {
width, height int
}
*/
type cuiWidget struct {
id int // widget ID
parentId int
widgetType toolkit.WidgetType
name string // a descriptive name of the widget
text string // the current text being displayed
visable bool // widget types like 'box' are 'false'
realWidth int // the real width
realHeight int // the real height
realSize rectType // the display size of this widget
logicalSize rectType // the logical size. Includes all the child widgets
nextX int
nextY int
// horizontal=true means layout widgets like books on a bookshelf
// horizontal=false means layout widgets like books in a stack
horizontal bool `default:false`
tainted bool
v *gocui.View
baseGui *gocui.Gui // use gogui.Manager ? as 'workspaces?'
// writeMutex protects locks the write process
writeMutex sync.Mutex
// deprecate
// logicalWidth int `default:8`
// logicalHeight int `default:2`
// rect rectType
// current rectType // the logical size. Includes all the child widgets
// width int
// height int
}
// from the gocui devs:
// Write appends a byte slice into the view's internal buffer. Because
// View implements the io.Writer interface, it can be passed as parameter
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
// be called to clear the view's buffer.
func (w *cuiWidget) Write(p []byte) (n int, err error) {
w.tainted = true
w.writeMutex.Lock()
defer w.writeMutex.Unlock()
// v.makeWriteable(v.wx, v.wy)
// v.writeRunes(bytes.Runes(p))
fmt.Fprintln(w.v, p)
log(logNow, "widget.Write()")
return len(p), nil
}

317
toolkit/democui/view.go Normal file
View File

@ -0,0 +1,317 @@
package main
import (
"fmt"
"errors"
"strconv"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
var adjusted bool = false
// expands the logical size of the parents
func (w *cuiWidget) setParentLogical(p *cuiWidget) {
if (w.visable) {
// expand the parent logicalsize to include the widget realSize
if (p.logicalSize.w0 > w.realSize.w0) {
p.logicalSize.w0 = w.realSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.realSize.h0) {
p.logicalSize.h0 = w.realSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.realSize.w1) {
p.logicalSize.w1 = w.realSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.realSize.h1) {
p.logicalSize.h1 = w.realSize.h1
adjusted = true
}
} else {
// expand the parent logicalsize to include the widget logicalsize
if (p.logicalSize.w0 > w.logicalSize.w0) {
p.logicalSize.w0 = w.logicalSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.logicalSize.h0) {
p.logicalSize.h0 = w.logicalSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.logicalSize.w1) {
p.logicalSize.w1 = w.logicalSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.logicalSize.h1) {
p.logicalSize.h1 = w.logicalSize.h1
adjusted = true
}
}
if (w.visable) {
// adjust the widget realSize to the top left corner of the logicalsize
if (w.logicalSize.w0 > w.realSize.w0) {
w.realSize.w0 = w.logicalSize.w0
w.realSize.w1 = w.realSize.w0 + w.realWidth
adjusted = true
}
if (w.logicalSize.h0 > w.realSize.h0) {
w.realSize.h0 = w.logicalSize.h0
w.realSize.h1 = w.realSize.h0 + w.realHeight
adjusted = true
}
}
w.showWidgetPlacement(logNow, "setParentLogical() widget")
p.showWidgetPlacement(logNow, "setParentLogical() parent")
if (w.id == 0) || (p.id == 0) {
// stop resizing when you hit the root widget
return
}
// pass the logical resizing up
pP := me.widgets[p.parentId]
if (pP != nil) {
p.setParentLogical(pP)
}
}
var fakeStartWidth int = 80
var fakeStartHeight int = 0
func (w *cuiWidget) setFake() {
if (w.visable) {
return
}
// setup fake labels for non-visable things off screen
w.realWidth = me.defaultWidth
w.realHeight = me.defaultHeight
w.realSize.w0 = fakeStartWidth
w.realSize.h0 = fakeStartHeight
w.realSize.w1 = w.realSize.w0 + me.defaultWidth
w.realSize.h1 = w.realSize.h0 + me.defaultHeight
fakeStartHeight += 2
w.showWidgetPlacement(logNow, "setFake()")
}
func drawView(w *cuiWidget) *gocui.View {
var newName string = ""
newName = strconv.Itoa(w.id)
if (me.baseGui == nil) {
log(logError, "drawView() me.baseGui == nil")
return nil
}
a := w.realSize.w0
b := w.realSize.h0
c := w.realSize.w1
d := w.realSize.h1
v, err := me.baseGui.SetView(newName, a, b, c, d, 0)
if err == nil {
log(logError, "drawView() internal plugin error err = nil")
return nil
}
if !errors.Is(err, gocui.ErrUnknownView) {
log(logError, "drawView() internal plugin error error.IS()", err)
return nil
}
w.v = v
return v
}
func boxedPlace(w *cuiWidget) {
t := len(w.name)
if (w.id == 0) {
w.realWidth = 0
w.realHeight = 0
return
}
p := me.widgets[w.parentId]
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
switch p.widgetType {
case toolkit.Box:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = p.nextX + w.realWidth
w.realSize.h1 = p.nextY + w.realHeight
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX + w.realWidth
w.logicalSize.h1 = p.nextY + w.realHeight
w.nextX = p.nextX
w.nextY = p.nextY
if (w.horizontal) {
log(logNow, "PARENT BOX IS HORIZONTAL")
p.nextX += w.realWidth
} else {
log(logNow, "PARENT BOX IS VERTICAL")
p.nextY += w.realHeight
}
case toolkit.Group:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = p.nextX + w.realWidth
w.realSize.h1 = p.nextY + w.realHeight
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX + w.realWidth
w.logicalSize.h1 = p.nextY + w.realHeight
w.nextX = w.logicalSize.w0 + 3 // default group padding
w.nextY = w.logicalSize.h1
// increment parent
p.nextY += w.realHeight
default:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realSize.h0 + w.realHeight
// increment parent
p.nextY += w.realHeight
}
p.showWidgetPlacement(logNow, "bP parent")
w.showWidgetPlacement(logNow, "bP widget")
}
func findPlace(w *cuiWidget, a *toolkit.Action) {
t := len(w.name)
w.visable = true
switch w.widgetType {
case toolkit.Root:
w.visable = false
w.setFake()
w.showWidgetPlacement(logNow, "Root:")
case toolkit.Flag:
w.visable = false
w.setFake()
w.showWidgetPlacement(logNow, "Flag:")
case toolkit.Window:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = me.nextW
w.realSize.h0 = 0
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = me.nextW
w.logicalSize.h0 = 0
w.logicalSize.w1 = w.logicalSize.w0 + w.realWidth
w.logicalSize.h1 = w.realHeight
w.nextX = w.logicalSize.w0 + t // default group padding
w.nextY = w.logicalSize.h1
me.nextW += w.realWidth
w.showWidgetPlacement(logNow, "window:")
case toolkit.Tab:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = me.nextW
w.realSize.h0 = 0
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = me.nextW
w.logicalSize.h0 = 0
w.logicalSize.w1 = w.logicalSize.w0 + w.realWidth
w.logicalSize.h1 = w.realHeight
w.nextX = w.logicalSize.w0 + t // default group padding
w.nextY = w.logicalSize.h1
me.nextW += w.realWidth
w.showWidgetPlacement(logNow, "tab:")
case toolkit.Grid:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "grid:")
case toolkit.Box:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "box:")
case toolkit.Group:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "group:")
default:
boxedPlace(w)
}
}
func place(w *cuiWidget, a *toolkit.Action) {
log(logInfo, "place() START")
findPlace(w, a)
v := drawView(w)
if (v == nil) {
log(logError, "place() drawView(w) returned nil")
return
}
me.baseGui.SetKeybinding(v.Name(), gocui.MouseLeft, gocui.ModNone, click)
v.Wrap = true
fmt.Fprintln(v, " " + w.name)
w.SetDefaultWidgetColor()
log(logInfo, "place() END")
return
}

View File

@ -88,6 +88,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
return
}
/*
log(b, "widget.Name =", w.Name)
// log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type)
@ -98,6 +99,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
*/
}
/*

View File

@ -1,135 +1,22 @@
//
// 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"
witlog "git.wit.org/wit/gui/log"
)
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...)
witlog.Log(a...)
}
func logindent(depth int, format string, a ...interface{}) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
// newFormat := tabs + strconv.Itoa(depth) + " " + format
newFormat := tabs + format
log(debugToolkit, newFormat, a)
func exit(a ...any) {
witlog.Exit(a...)
}
func setOutput(f *os.File) {
golog.SetOutput(f)
witlog.SetOutput(f)
}

View File

@ -7,6 +7,8 @@ type ActionType int
//
// All Toolkit interactions should be done via a channel or Queue()
// TODO: FIGURE OUT HOW TO IMPLEMENT THIS
// https://ieftimov.com/post/golang-datastructures-trees/
// TODO: protobuf ?
//
// This is the only thing that is passed between the toolkit plugin
//
@ -18,7 +20,6 @@ type ActionType int
// Could a protobuf be used here? (Can functions be passed?)
type Widget struct {
Name string
// Action string // "New", "Delete", "Set", aka something to do
Type WidgetType
// This function is how you interact with the toolkit
@ -29,7 +30,7 @@ type Widget struct {
Callback func()
// re-adding an id to test channels
id int
Id int
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
@ -39,32 +40,22 @@ type Widget struct {
// 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
// We are not laying out PDF's here
// This is used for things like a slider(0,100)
Width int
Height int
X int
Y int
// Put space around elements to improve look & feel
Margin bool
// Make widgets fill up the space available
Expand bool
}
type Action struct {
Type ActionType
ActionType ActionType
WidgetType WidgetType
WidgetId int
ParentId int
Text string // what is visable to the user
Name string // a name useful for programming
// this should be the widget
// if the action is New, Hide, Enable, etc
Widget *Widget
// this is the widget
// where the other one should be put on New, Move, etc
Where *Widget
Callback func(int)
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
@ -90,31 +81,30 @@ type Action struct {
Expand bool
}
// https://ieftimov.com/post/golang-datastructures-trees/
// TODO: protobuf ?
const (
Unknown WidgetType = iota
Window
Tab // internally, this should be a window (?)
Frame // should windows and tab's be frames (?)
Grid // a grid of frames ?
Group // internally, this should be a grid (?)
Box // internally, this should be a grid (?)
Root // the master 'root' node of the binary tree
Flag // used to send configuration values to plugins
Window // in certain gui's (ncurses), these are tabs
Tab // internally, this is a window
Frame // deprecate?
Grid // like drawers in a chest
Group // like the 'Appetizers' section on a menu
Box // a vertical or horizontal stack of widgets
Button
Checkbox
Checkbox // select 'on' or 'off'
Dropdown
Combobox // dropdown with edit=true (?)
Combobox // dropdown with edit=true
Label
Textbox // is this a Label with edit=true?
Slider
Spinner
Image
Area
Form
Font
Color
Dialog
Textbox // is this a Label with edit=true
Slider // like a progress bar
Spinner // like setting the oven temperature
Image // TODO
Area // TODO
Form // TODO
Font // TODO
Color // TODO
Dialog // TODO
)
const (
@ -122,7 +112,6 @@ const (
Delete
Get
Set
SetFlag
GetText
SetText
AddText
@ -137,11 +126,14 @@ const (
Append
Move
Dump
Flag
)
func (s WidgetType) String() string {
switch s {
case Root:
return "Root"
case Flag:
return "Flag"
case Window:
return "Window"
case Tab:
@ -185,7 +177,7 @@ func (s WidgetType) String() string {
case Unknown:
return "Unknown"
}
return "Widget.Type.String() Error"
return "WidgetType.String() Error"
}
func (s ActionType) String() string {
@ -198,8 +190,6 @@ func (s ActionType) String() string {
return "Get"
case Set:
return "Set"
case SetFlag:
return "SetFlag"
case GetText:
return "GetText"
case SetText:
@ -226,22 +216,8 @@ func (s ActionType) String() string {
return "Append"
case Move:
return "Move"
case Flag:
return "Flag"
case Dump:
return "Dump"
}
return "Action.Type.String() Error"
}
// 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
return "ActionType.String() Error"
}

View File

@ -34,16 +34,15 @@ func NewWindow() *Node {
}
}
// Windows are created off of the master node of the Binary Tree
newNode = Config.master.New(Config.Title, toolkit.Window, custom)
newNode = Config.rootNode.New(Config.Title, toolkit.Window, custom)
newNode.widget.Width = Config.Width
newNode.widget.Height = Config.Height
log(debugGui, "Window()", Config.Title)
log(logInfo, "NewWindow()", Config.Title)
var a toolkit.Action
a.Type = toolkit.Add
newaction(&a, newNode, Config.master)
a.ActionType = toolkit.Add
a.Width = Config.Width
a.Height = Config.Height
newaction(&a, newNode, Config.rootNode)
return newNode
}