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: github:
git push origin master git push origin master
git push github master git push github master
git push github devel
git push github --tags git push github --tags
@echo @echo
@echo check https://github.com/wit-go/gui @echo check https://github.com/wit-go/gui

View File

@ -107,42 +107,6 @@ external things which might be useful
* [GO Style Guide] * [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 ## Functions
### func [DebugWidgetWindow](/debugWidget.go#L52) ### func [DebugWidgetWindow](/debugWidget.go#L52)
@ -155,11 +119,15 @@ var WARN bool
Creates a window helpful for debugging this package 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 Indent(b bool, a ...interface{})`
### func [InitPlugins](/main.go#L56) ### func [InitPlugins](/main.go#L58)
`func InitPlugins(names []string)` `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) loads and initializes a toolkit (andlabs/ui, gocui, etc)
### func [Main](/main.go#L97) ### func [Main](/main.go#L121)
`func Main(f func())` `func Main(f func())`
This should not pass a function This should not pass a function
### func [Queue](/main.go#L127) ### func [Redraw](/redraw.go#L9)
`func Queue(f func())` `func Redraw(s string)`
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 [SetDebug](/debug.go#L28) ### func [SetDebug](/debug.go#L28)
@ -194,11 +155,11 @@ For example: gui.Queue(NewWindow())
`func SetFlag(s string, b bool)` `func SetFlag(s string, b bool)`
### func [ShowDebugValues](/debug.go#L86) ### func [ShowDebugValues](/debug.go#L79)
`func ShowDebugValues()` `func ShowDebugValues()`
### func [StandardExit](/main.go#L147) ### func [StandardExit](/main.go#L173)
`func StandardExit()` `func StandardExit()`
@ -216,13 +177,13 @@ This goroutine can be used like a watchdog timer
## Types ## Types
### type [GuiArgs](/structs.go#L25) ### type [GuiArgs](/structs.go#L26)
`type GuiArgs struct { ... }` `type GuiArgs struct { ... }`
This struct can be used with the go-arg package This struct can be used with the go-arg package
### type [GuiConfig](/structs.go#L33) ### type [GuiConfig](/structs.go#L34)
`type GuiConfig struct { ... }` `type GuiConfig struct { ... }`
@ -232,7 +193,7 @@ This struct can be used with the go-arg package
var Config GuiConfig var Config GuiConfig
``` ```
### type [Node](/structs.go#L57) ### type [Node](/structs.go#L58)
`type Node struct { ... }` `type Node struct { ... }`
@ -287,12 +248,22 @@ func main() {
You get a window 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](/plugin.go#L16)
`type Symbol any` `type Symbol any`
## Sub Packages ## Sub Packages
* [log](./log)
* [toolkit](./toolkit) * [toolkit](./toolkit)
--- ---

View File

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

32
chan.go
View File

@ -8,8 +8,10 @@ import (
// "regexp" // "regexp"
// "git.wit.org/wit/gui/toolkit" // "git.wit.org/wit/gui/toolkit"
"sync" "sync"
"runtime"
"github.com/sourcegraph/conc" "github.com/sourcegraph/conc"
"github.com/sourcegraph/conc/stream" "github.com/sourcegraph/conc/stream"
"github.com/sourcegraph/conc/panics"
) )
func makeConc() { func makeConc() {
@ -17,14 +19,42 @@ func makeConc() {
defer wg.Wait() defer wg.Wait()
startTheThing(&wg) startTheThing(&wg)
log(debugError, "panic?")
sleep(2)
log(debugError, "panic? after sleep(5)")
} }
func startTheThing(wg *conc.WaitGroup) { func startTheThing(wg *conc.WaitGroup) {
f := func() {
log(debugError, "startTheThing() == about to panic now")
panic("test conc.WaitGroup")
}
wg.Go(func() { 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( func mapStream(
in chan int, in chan int,
out 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) newNode := n.New(name, toolkit.Checkbox, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
// a.Widget = &newNode.widget a.Name = name
// a.Where = &n.widget a.Text = name
// action(&a, newNode, n)
newaction(&a, newNode, n) newaction(&a, newNode, n)
return newNode return newNode

View File

@ -8,7 +8,7 @@
run: build run: build
# ./buttonplugin >/tmp/buttonplugin.log 2>&1 # ./buttonplugin >/tmp/buttonplugin.log 2>&1
./buttonplugin ./buttonplugin >/tmp/witgui.log.stderr 2>&1
build-release: build-release:
go get -v -u -x . go get -v -u -x .
@ -21,3 +21,7 @@ build:
update: update:
GO111MODULE="off" go get -v -u -x . 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 title string = "Demo Plugin Window"
var outfile string = "/tmp/guilogfile" var outfile string = "/tmp/guilogfile"
// this is broken. delete this
func main() { 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) // time.Sleep(5 * time.Second)
// var w *gui.Node // var w *gui.Node
@ -54,27 +50,49 @@ var counter int = 5
// This creates a window // This creates a window
func buttonWindow() { func buttonWindow() {
var w, g *gui.Node var w, t, g, more, more2 *gui.Node
gui.Config.Title = title gui.Config.Title = title
gui.Config.Width = 640 gui.Config.Width = 640
gui.Config.Height = 480 gui.Config.Height = 480
w = gui.NewWindow() 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.NewLabel("STDOUT is set to: " + outfile)
g.NewButton("hello", func () { g.NewButton("hello", func () {
log.Println("world") 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'") log.Println("new foobar 2. Adding button 'foobar 3'")
name := "foobar " + strconv.Itoa(counter) name := "foobar " + strconv.Itoa(counter)
counter += 1 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) 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'") log.Println("new foobar 2. Adding button 'foobar 3'")
name := "neat " + strconv.Itoa(counter) name := "neat " + strconv.Itoa(counter)
counter += 1 counter += 1
g.NewGroup(name) more.NewGroup(name)
}) })
g.NewButton("gui.DebugWindow()", func () { g.NewButton("gui.DebugWindow()", func () {
gui.DebugWindow() gui.DebugWindow()
}) })
g.NewButton("LoadToolkit(andlabs)", func () { more2 = g.NewGroup("more2")
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")
})
})
} }

View File

@ -1,5 +1,6 @@
run: build 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: build-release:
go get -v -u -x . go get -v -u -x .

View File

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

View File

@ -11,25 +11,25 @@ import (
func (n *Node) Show() { func (n *Node) Show() {
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Show a.ActionType = toolkit.Show
newaction(&a, n, nil) newaction(&a, n, nil)
} }
func (n *Node) Hide() { func (n *Node) Hide() {
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Hide a.ActionType = toolkit.Hide
newaction(&a, n, nil) newaction(&a, n, nil)
} }
func (n *Node) Enable() { func (n *Node) Enable() {
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Enable a.ActionType = toolkit.Enable
newaction(&a, n, nil) newaction(&a, n, nil)
} }
func (n *Node) Disable() { func (n *Node) Disable() {
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Disable a.ActionType = toolkit.Disable
newaction(&a, n, nil) newaction(&a, n, nil)
} }
@ -37,7 +37,7 @@ func (n *Node) Add(str string) {
log(debugGui, "gui.Add() value =", str) log(debugGui, "gui.Add() value =", str)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
a.S = str a.S = str
// a.Widget = &n.widget // a.Widget = &n.widget
// action(&a) // action(&a)
@ -48,7 +48,7 @@ func (n *Node) AddText(str string) {
log(debugChange, "AddText() value =", str) log(debugChange, "AddText() value =", str)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.AddText a.ActionType = toolkit.AddText
a.S = str a.S = str
// a.Widget = &n.widget // a.Widget = &n.widget
// action(&a) // action(&a)
@ -59,7 +59,7 @@ func (n *Node) SetText(str string) {
log(debugChange, "SetText() value =", str) log(debugChange, "SetText() value =", str)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.SetText a.ActionType = toolkit.SetText
a.S = str a.S = str
// a.Widget = &n.widget // a.Widget = &n.widget
// action(&a) // action(&a)
@ -80,7 +80,7 @@ func (n *Node) SetNext(x int, y int) {
func (n *Node) Set(val any) { func (n *Node) Set(val any) {
log(debugChange, "Set() value =", val) log(debugChange, "Set() value =", val)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Set a.ActionType = toolkit.Set
switch v := val.(type) { switch v := val.(type) {
case bool: case bool:
@ -100,7 +100,7 @@ func (n *Node) Set(val any) {
func (n *Node) AppendText(str string) { func (n *Node) AppendText(str string) {
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.SetText a.ActionType = toolkit.SetText
tmp := n.widget.S + str tmp := n.widget.S + str
log(debugChange, "AppendText() value =", tmp) log(debugChange, "AppendText() value =", tmp)
a.S = tmp a.S = tmp
@ -157,3 +157,50 @@ func commonCallback(n *Node) {
n.Custom() 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) 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 var a toolkit.Action
a.Type = toolkit.SetFlag a.ActionType = toolkit.Set
a.WidgetType = toolkit.Flag
a.S = s a.S = s
a.B = b a.B = b
// a.Widget = &newNode.widget // a.Widget = &newNode.widget
@ -109,9 +102,11 @@ func (n *Node) Dump(b bool) {
Indent(b, "Height = ", n.Height) Indent(b, "Height = ", n.Height)
Indent(b, "(X,Y) = ", n.X, n.Y) Indent(b, "(X,Y) = ", n.X, n.Y)
Indent(b, "Next (X,Y) = ", n.NextX, n.NextY) Indent(b, "Next (X,Y) = ", n.NextX, n.NextY)
/*
Indent(b, "Widget Name = ", n.widget.Name) Indent(b, "Widget Name = ", n.widget.Name)
Indent(b, "Widget Type = ", n.widget.Type) 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) { if (n.parent == nil) {
Indent(b, "parent = nil") Indent(b, "parent = nil")

View File

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

View File

@ -74,15 +74,37 @@ func (n *Node) DebugTab(title string) *Node {
dropdownWindowWidgets(g1) dropdownWindowWidgets(g1)
}) })
g2 := newN.NewGroup("node things") g2 := newN.NewGroup("more things")
g2.NewButton("Node.ListChildren(true)", func () { g2.NewButton("Node.ListChildren(true)", func () {
if (activeWidget == nil) { if (activeWidget == nil) {
activeWidget = Config.master activeWidget = Config.rootNode
} }
activeWidget.ListChildren(true) 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 return newN
} }
@ -105,7 +127,7 @@ func dropdownWindow(p *Node) {
} }
// var last = "" // 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) log(debugGui, "\t\t", child.id, child.Width, child.Height, child.Name)
dd.AddDropdownName(child.Name) dd.AddDropdownName(child.Name)
// last = child.Name // last = child.Name
@ -145,5 +167,5 @@ func dropdownWindowWidgets(p *Node) {
} }
// list everything in the binary tree // 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) newNode := n.New(name, toolkit.Dropdown, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
// a.Widget = &newNode.widget // a.Widget = &newNode.widget
// a.Where = &n.widget // a.Where = &n.widget
// action(&a) // action(&a)
@ -36,7 +36,7 @@ func (n *Node) NewCombobox(name string) *Node {
newNode := n.New(name, toolkit.Combobox, nil) newNode := n.New(name, toolkit.Combobox, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
// a.Widget = &newNode.widget // a.Widget = &newNode.widget
// a.Where = &n.widget // a.Where = &n.widget
// action(&a) // action(&a)

View File

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

View File

@ -12,7 +12,7 @@ func (n *Node) NewGroup(name string) *Node {
newNode = n.New(name, toolkit.Group, nil) newNode = n.New(name, toolkit.Group, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
newaction(&a, newNode, n) newaction(&a, newNode, n)
newBox := newNode.NewBox("group vBox", false) 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) newNode = n.New(name, toolkit.Image, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
// a.Widget = &newNode.widget // a.Widget = &newNode.widget
// a.Where = &n.widget // a.Where = &n.widget
// action(&a) // action(&a)

View File

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

126
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 package gui
import ( import (
"os" witlog "git.wit.org/wit/gui/log"
"runtime"
"runtime/pprof"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
// "net"
) )
var LOGOFF bool = false // turn this off, all logging stops // various debugging flags
var WARN bool var logNow bool = true // useful for active development
var INFO bool var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
type spewt struct { // var log interface{}
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
*/
func log(a ...any) { func log(a ...any) {
if (LOGOFF) { witlog.Where = "wit/gui"
return witlog.Log(a...)
} }
if (a == nil) { func sleep(a ...any) {
return witlog.Sleep(a...)
} }
var tbool bool func exit(a ...any) {
if (reflect.TypeOf(a[0]) == reflect.TypeOf(tbool)) { witlog.Exit(a...)
// 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...)
}
func loggo() {
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
golog.Println("runtime.NumGoroutine() = ", runtime.NumGoroutine())
} }
// b bool, print if true // 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: // array prepend(). Why isn't this a standard function. It should be:
// a.prepend(debugGui, newFormat) // a.prepend(debugGui, newFormat)
a = append([]any{b, newFormat}, a...) 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 ( import (
// "embed" // "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? // 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 Config.Height = 480
// Populates the top of the binary tree // 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 // 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() { func doGuiChan() {
@ -57,7 +59,7 @@ func InitPlugins(names []string) {
log(debugGui, "Starting gui.Init()") log(debugGui, "Starting gui.Init()")
for _, aplug := range allPlugins { 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 { for _, name := range names {
if (name == aplug.name) { if (name == aplug.name) {
return return
@ -93,6 +95,28 @@ func InitPlugins(names []string) {
// StandardExit("golang wit/gui could not load a plugin TODO: do something to STDOUT (?)") // 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 // This should not pass a function
func Main(f func()) { func Main(f func()) {
log(debugGui, "Starting gui.Main() (using gtk via andlabs/ui)") log(debugGui, "Starting gui.Main() (using gtk via andlabs/ui)")
@ -111,11 +135,12 @@ func Main(f func()) {
} }
aplug.MainOk = true aplug.MainOk = true
aplug.Main(f) aplug.Main(f)
// f()
} }
// toolkit.Main(f)
} }
/*
This is deprecated and will be implemented more correctly with waitgroups
// This should never be exposed(?) // This should never be exposed(?)
// Other goroutines must use this to access the GUI // Other goroutines must use this to access the GUI
@ -135,6 +160,7 @@ func Queue(f func()) {
aplug.Queue(f) aplug.Queue(f)
} }
} }
*/
// The window is destroyed but the application does not quit // The window is destroyed but the application does not quit
func (n *Node) StandardClose() { func (n *Node) StandardClose() {

View File

@ -9,6 +9,7 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
var newN *Node var newN *Node
newN = addNode(title) newN = addNode(title)
newN.WidgetType = t
newN.widget.Type = t newN.widget.Type = t
// newN.widget.Action = "New" // newN.widget.Action = "New"
newN.Custom = custom newN.Custom = custom
@ -44,7 +45,7 @@ func addNode(title string) *Node {
n.Name = title n.Name = title
n.widget.Name = title n.widget.Name = title
n.id = Config.counter n.id = Config.counter
n.widget.SetId(n.id) n.widget.Id = n.id
log(debugNode, "addNode = widget setid =", n.id) log(debugNode, "addNode = widget setid =", n.id)
Config.counter += 1 Config.counter += 1
@ -55,9 +56,11 @@ func (n *Node) Parent() *Node {
return n.parent return n.parent
} }
/*
func (n *Node) Window() *Node { func (n *Node) Window() *Node {
return n.parent return n.parent
} }
*/
func (n *Node) Append(child *Node) { func (n *Node) Append(child *Node) {
n.children = append(n.children, child) 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 // TODO: make Main() main() and never allow the user to call it
// run plugin.Main() when the plugin is loaded // run plugin.Main() when the plugin is loaded
Main func(func ()) // this never returns. Each plugin must have it's own goroutine 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() Quit func()
// NewWindow func(*toolkit.Widget) // NewWindow func(*toolkit.Widget)
// simplifies passing to the plugin // simplifies passing to the plugin
Send func(*toolkit.Widget, *toolkit.Widget) // Send func(*toolkit.Widget, *toolkit.Widget)
// should replace Send() // should replace Send()
Action func(*toolkit.Action) Action func(*toolkit.Action)
@ -74,16 +74,11 @@ func LoadToolkit(name string) bool {
newPlug.Main = loadFuncF(&newPlug, "Main") newPlug.Main = loadFuncF(&newPlug, "Main")
// should send things to the goroutine above // should send things to the goroutine above
newPlug.Queue = loadFuncF(&newPlug, "Queue") // newPlug.Queue = loadFuncF(&newPlug, "Queue")
// unload the plugin and restore state // unload the plugin and restore state
newPlug.Quit = loadFuncE(&newPlug, "Quit") 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 instructions like "Add", "Delete", "Disable", etc
// Sends a widget (button, checkbox, etc) and it's parent widget // Sends a widget (button, checkbox, etc) and it's parent widget
newPlug.Action = loadFuncA(&newPlug, "Action") newPlug.Action = loadFuncA(&newPlug, "Action")
@ -190,7 +185,8 @@ func loadPlugin(p *aplug, name string) {
homeDir, err := os.UserHomeDir() homeDir, err := os.UserHomeDir()
if err != nil { if err != nil {
exit(err) log(logError, "loadPlugin() error. exiting here?")
return
} }
// attempt to write out the file from the internal resource // attempt to write out the file from the internal resource
@ -230,36 +226,6 @@ func loadfile(filename string) *plugin.Plugin {
return plug 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 // Sends a widget and what to do with it to the plugin
// parent = n, child = c // parent = n, child = c
@ -268,16 +234,19 @@ func action(a *toolkit.Action) {
func newaction(a *toolkit.Action, n *Node, where *Node) { func newaction(a *toolkit.Action, n *Node, where *Node) {
if (n != nil) { if (n != nil) {
a.Widget = &n.widget a.Widget = &n.widget
a.WidgetId = n.id
a.WidgetType = n.widget.Type
a.ActionType = a.ActionType
} }
// action(&a, newNode, n) // action(&a, newNode, n)
// newaction(&a, newNode, n) // newaction(&a, newNode, n)
if (where != nil) { if (where != nil) {
log(debugGui, "Action() START on where X,Y, Next X,Y =", where.Name, where.X, where.Y, where.NextX, where.NextY) 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 { switch where.widget.Type {
case toolkit.Grid: 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) 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 // 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 where.NextY = 1
} }
// //
a.Where.X = where.NextX a.X = where.NextX
a.Where.Y = where.NextY 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) log(debugGui, "Action() END on Grid (X,Y)", where.X, where.Y, "put next thing at (X,Y) =", where.NextX, where.NextY)
default: default:
} }
} }
for _, aplug := range allPlugins { 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) { if (aplug.Action == nil) {
log(debugPlugin, "Failed Action() == nil for", aplug.name) log(debugPlugin, "Failed Action() == nil for", aplug.name)
continue continue
@ -307,19 +276,19 @@ func newaction(a *toolkit.Action, n *Node, where *Node) {
if (where != nil) { if (where != nil) {
switch where.widget.Type { switch where.widget.Type {
case toolkit.Grid: 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 where.NextY += 1
if (where.NextY > where.Y) { if (where.NextY > where.Y) {
where.NextX += 1 where.NextX += 1
where.NextY = 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.Name = "jwc gridlaksdfjkl"
where.Width = 320 where.Width = 320
where.Height = 240 where.Height = 240
// where.NextX = 5 // where.NextX = 5
// where.NextY = 7 // where.NextY = 7
where.Dump(true) // where.Dump(logInfo)
default: 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 var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
a.X = x a.X = x
a.Y = y a.Y = y
// a.Widget = &newNode.widget // 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 var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
a.X = x a.X = x
a.Y = y a.Y = y
// a.Widget = &newNode.widget // a.Widget = &newNode.widget

View File

@ -2,6 +2,7 @@ package gui
import ( import (
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
"sync"
) )
// //
@ -32,9 +33,9 @@ type GuiArgs struct {
type GuiConfig struct { type GuiConfig struct {
// This is the master node. The Binary Tree starts here // 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 flag *Node
// These are shortcuts to pass default values to make a new window // 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 // simply the name and the size of whatever GUI element exists
type Node struct { type Node struct {
id int id int
initOnce sync.Once
widget toolkit.Widget 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 // used for Windows
Width int Width int
@ -83,9 +90,4 @@ type Node struct {
parent *Node parent *Node
children []*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) newNode := n.New(text, toolkit.Tab, nil)
var a toolkit.Action var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
a.Name = text
a.Text = text
newaction(&a, newNode, n) 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 var a toolkit.Action
a.Type = toolkit.Add a.ActionType = toolkit.Add
// a.Widget = &newNode.widget // a.Widget = &newNode.widget
// a.Where = &n.widget // a.Where = &n.widget
// action(&a) // action(&a)

View File

@ -4,40 +4,40 @@ import (
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
) )
func show(w *toolkit.Widget) { func show(a *toolkit.Action) {
if (w == nil) { if (a == nil) {
log(debugError, "nil is probably already hidden") log(debugError, "nil is probably already hidden")
return return
} }
log(debugError, "show()", w.Name) log(debugError, "show()", a.WidgetId)
t := mapToolkits[w] t := andlabs[a.WidgetId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "show() toolkit struct == nil. for", w.Name) log(debugError, "show() toolkit struct == nil. for", a.WidgetId)
return return
} }
if (w.B) { if (a.B) {
t.uiControl.Show() t.uiControl.Show()
} else { } else {
t.uiControl.Hide() t.uiControl.Hide()
} }
} }
func enable(w *toolkit.Widget) { func enable(a *toolkit.Action) {
if (w == nil) { if (a == nil) {
log(debugError, "nil is probably already hidden") log(debugError, "nil is probably already hidden")
return return
} }
log(debugError, "enable()", w.Name) log(debugError, "enable() name =", a.WidgetId)
t := mapToolkits[w] t := andlabs[a.WidgetId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "enable() toolkit struct == nil. for", w.Name) log(debugToolkit, "enable() toolkit struct == nil. for id =", a.WidgetId)
return return
} }
if (w.B) { if (a.B) {
t.uiControl.Enable() t.uiControl.Enable()
} else { } else {
t.uiControl.Disable() t.uiControl.Disable()
@ -45,21 +45,21 @@ func enable(w *toolkit.Widget) {
} }
func pad(a *toolkit.Action) { func pad(a *toolkit.Action) {
if (a.Widget == nil) { if (a == nil) {
log(debugError, "pad() ERROR: nil is probably already hidden") log(debugError, "pad() ERROR: nil is probably already hidden")
return return
} }
log(debugError, "pad()", a.Widget.Name) log(debugError, "pad()")
t := mapToolkits[a.Widget] t := andlabs[a.WidgetId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "pad() toolkit struct == nil. for", a.Widget.Name) log(debugError, "pad() toolkit struct == nil. for", a.WidgetId)
return return
} }
switch a.Widget.Type { switch t.Type {
case toolkit.Group: case toolkit.Group:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
t.uiGroup.SetMargined(true) t.uiGroup.SetMargined(true)
case toolkit.Unmargin: case toolkit.Unmargin:
@ -70,7 +70,7 @@ func pad(a *toolkit.Action) {
t.uiGroup.SetMargined(false) t.uiGroup.SetMargined(false)
} }
case toolkit.Tab: case toolkit.Tab:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
tabSetMargined(t.uiTab, true) tabSetMargined(t.uiTab, true)
case toolkit.Unmargin: case toolkit.Unmargin:
@ -81,7 +81,7 @@ func pad(a *toolkit.Action) {
tabSetMargined(t.uiTab, false) tabSetMargined(t.uiTab, false)
} }
case toolkit.Window: case toolkit.Window:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
t.uiWindow.SetMargined(true) t.uiWindow.SetMargined(true)
case toolkit.Unmargin: case toolkit.Unmargin:
@ -92,7 +92,7 @@ func pad(a *toolkit.Action) {
t.uiWindow.SetBorderless(true) t.uiWindow.SetBorderless(true)
} }
case toolkit.Grid: case toolkit.Grid:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
t.uiGrid.SetPadded(true) t.uiGrid.SetPadded(true)
case toolkit.Unmargin: case toolkit.Unmargin:
@ -103,7 +103,7 @@ func pad(a *toolkit.Action) {
t.uiGrid.SetPadded(false) t.uiGrid.SetPadded(false)
} }
case toolkit.Box: case toolkit.Box:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
t.uiBox.SetPadded(true) t.uiBox.SetPadded(true)
case toolkit.Unmargin: case toolkit.Unmargin:
@ -114,128 +114,120 @@ func pad(a *toolkit.Action) {
t.uiBox.SetPadded(false) t.uiBox.SetPadded(false)
} }
case toolkit.Textbox: case toolkit.Textbox:
log(debugError, "TODO: implement expand for", a.Type) log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.Type) log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.Type) log(debugError, "TODO: implement expand for", a.ActionType)
log(debugError, "TODO: implement expand for", a.Type) log(debugError, "TODO: implement expand for", a.ActionType)
default: default:
log(debugError, "TODO: implement pad() for", a.Type) log(debugError, "TODO: implement pad() for", a.ActionType)
} }
} }
func move(a *toolkit.Action) { func move(a *toolkit.Action) {
if (a.Where == nil) { log(debugNow, "move()", a.WidgetId, "to", a.ParentId)
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)
tWidget := mapToolkits[a.Widget] tWidget := andlabs[a.WidgetId]
if (tWidget == nil) { 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 return
} }
tWhere := mapToolkits[a.Where] tParent := andlabs[a.ParentId]
if (tWhere == nil) { if (tParent == nil) {
log(debugError, "move() ERROR: toolkit struct == nil. for", a.Where.Name) log(debugError, "move() ERROR: toolkit struct == nil. for", a.ParentId)
return return
} }
switch a.Where.Type { switch tParent.Type {
case toolkit.Group: case toolkit.Group:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
tWhere.uiGroup.SetMargined(true) tParent.uiGroup.SetMargined(true)
} }
case toolkit.Tab: case toolkit.Tab:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true) // tabSetMargined(tParent.uiTab, true)
} }
case toolkit.Window: case toolkit.Window:
switch a.Type { switch a.ActionType {
case toolkit.Pad: case toolkit.Pad:
// t.uiWindow.SetBorderless(false) // t.uiWindow.SetBorderless(false)
} }
case toolkit.Grid: case toolkit.Grid:
switch a.Type { switch a.ActionType {
case toolkit.Pad: case toolkit.Pad:
// t.uiGrid.SetPadded(true) // t.uiGrid.SetPadded(true)
} }
case toolkit.Box: case toolkit.Box:
log(debugNow, "TODO: move() for a =", a.Type) log(debugNow, "TODO: move() for a =", a.ActionType)
log(debugNow, "TODO: move() where =", a.Where.Type) log(debugNow, "TODO: move() where =", a.ParentId)
log(debugNow, "TODO: move() for widget =", a.Widget.Type) log(debugNow, "TODO: move() for widget =", a.WidgetId)
stretchy = true stretchy = true
tWhere.uiBox.Append(tWidget.uiControl, stretchy) tParent.uiBox.Append(tWidget.uiControl, stretchy)
// log(debugNow, "is there a tWhere parent? =", tWhere.parent) // log(debugNow, "is there a tParent parent? =", tParent.parent)
// tWhere.uiBox.Delete(0) // tParent.uiBox.Delete(0)
// this didn't work: // this didn't work:
// tWidget.uiControl.Disable() // tWidget.uiControl.Disable()
// sleep(.8) // sleep(.8)
default: default:
log(debugError, "TODO: need to implement move() for a =", a.Type) log(debugError, "TODO: need to implement move() for a =", a.ActionType)
log(debugError, "TODO: need to implement move() for where =", a.Where.Type) log(debugError, "TODO: need to implement move() for where =", a.ParentId)
log(debugError, "TODO: need to implement move() for widget =", a.Widget.Type) log(debugError, "TODO: need to implement move() for widget =", a.WidgetId)
} }
} }
func uiDelete(a *toolkit.Action) { func uiDelete(a *toolkit.Action) {
if (a.Where == nil) { if (andlabs[a.ParentId] == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete to nil") log(debugError, "uiDelete() ERROR: can not uiDelete to nil")
return return
} }
if (a.Widget == nil) { if (andlabs[a.WidgetId] == nil) {
log(debugError, "uiDelete() ERROR: can not uiDelete nil") log(debugError, "uiDelete() ERROR: can not uiDelete nil")
return 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) { 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 return
} }
tWhere := mapToolkits[a.Where] tParent := andlabs[a.ParentId]
if (tWhere == nil) { if (tParent == nil) {
log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.Where.Name) log(debugError, "uiDelete() ERROR: toolkit struct == nil. for", a.ParentId)
return return
} }
switch a.Where.Type { switch tParent.Type {
case toolkit.Group: case toolkit.Group:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
tWhere.uiGroup.SetMargined(true) tParent.uiGroup.SetMargined(true)
} }
case toolkit.Tab: case toolkit.Tab:
switch a.Type { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
// tabSetMargined(tWhere.uiTab, true) // tabSetMargined(tParent.uiTab, true)
} }
case toolkit.Window: case toolkit.Window:
switch a.Type { switch a.ActionType {
case toolkit.Pad: case toolkit.Pad:
// t.uiWindow.SetBorderless(false) // t.uiWindow.SetBorderless(false)
} }
case toolkit.Grid: case toolkit.Grid:
switch a.Type { switch a.ActionType {
case toolkit.Pad: case toolkit.Pad:
// t.uiGrid.SetPadded(true) // t.uiGrid.SetPadded(true)
} }
case toolkit.Box: case toolkit.Box:
log(debugNow, "tWidget.boxC =", tWhere.Name) log(debugNow, "tWidget.boxC =", tParent.Name)
log(debugNow, "is there a tWhere parent? =", tWhere.parent) log(debugNow, "is there a tParent parent? =", tParent.parent)
if (tWidget.boxC < 1) { 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 return
} }
tWidget.uiBox.Delete(0) tWidget.uiBox.Delete(0)
@ -244,10 +236,10 @@ func uiDelete(a *toolkit.Action) {
// this didn't work: // this didn't work:
// tWidget.uiControl.Disable() // tWidget.uiControl.Disable()
// sleep(.8) // sleep(.8)
// tWhere.uiBox.Append(tWidget.uiControl, stretchy) // tParent.uiBox.Append(tWidget.uiControl, stretchy)
default: default:
log(debugError, "TODO: need to implement uiDelete() for a =", a.Type) log(debugError, "TODO: need to implement uiDelete() for a =", a.ActionType)
log(debugError, "TODO: need to implement uiDelete() for where =", a.Where.Type) log(debugError, "TODO: need to implement uiDelete() for where =", a.ParentId)
log(debugError, "TODO: need to implement uiDelete() for widget =", a.Widget.Type) 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) { func actionDump(b bool, a *toolkit.Action) {
log(b, "dump() Widget.Type =", a.Type) log(b, "actionDump() Widget.Type =", a.ActionType)
log(b, "dump() Widget.S =", a.S) log(b, "actionDump() Widget.S =", a.S)
log(b, "dump() Widget.I =", a.I) log(b, "actionDump() Widget.I =", a.I)
log(b, "dump() Widget =", a.Widget) log(b, "actionDump() WidgetId =", a.WidgetId)
log(b, "dump() Where =", a.Where) log(b, "actionDump() ParentId =", a.ParentId)
} }
func add(a *toolkit.Action) { func add(a *toolkit.Action) {
if (a.Widget == nil) { if (andlabs[a.WidgetId] != nil) {
log(debugError, "add() error. w.Widget == nil") log(debugError, "add() error. can't make a widget that already exists. id =", a.WidgetId)
actionDump(debugError, a) actionDump(debugError, a)
return 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) // for now, window gets handled without checking where == nil)
if (a.Widget.Type == toolkit.Window) { if (a.WidgetType == toolkit.Window) {
doWindow(a) doWindow(a)
return return
} }
t := mapToolkits[a.Where] if (andlabs[a.ParentId] == nil) {
if (t == nil) {
// listMap(debugError) // memory corruption? // listMap(debugError) // memory corruption?
log(debugError, "add() Widget.Name =", a.Widget.Name, a.Widget.Type) log(debugError, "add() Widget.Name =", a.Name)
// log(debugError, "add() Where.Name =", a.Where.Name) log(debugError, "add() Widget.Type =", a.WidgetType)
log(debugError, "ERROR add() ERROR a.Where map to t == nil.") log(debugError, "ERROR add() ERROR a.Parent map to t == nil. WidgetId =", a.WidgetId, "ParentId =", a.ParentId)
exit("can not add()")
return return
} }
switch a.Widget.Type { switch a.WidgetType {
case toolkit.Window: case toolkit.Window:
doWindow(a) doWindow(a)
return return
case toolkit.Tab: case toolkit.Tab:
doTab(a) newTab(a)
return return
case toolkit.Label: case toolkit.Label:
newLabel(a) newLabel(a)
@ -80,7 +86,7 @@ func add(a *toolkit.Action) {
newImage(a) newImage(a)
return return
default: 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) -- // -- (0,1) -- (1,1) -- (1,1) --
// ----------------------------- // -----------------------------
func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool { 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) { 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 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: case toolkit.Grid:
log(debugGrid, "add() Grid try at Where X,Y =", a.Where.X, a.Where.Y) log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y)
newt.gridX = a.Where.X newt.gridX = a.X
newt.gridY = a.Where.Y newt.gridY = a.Y
log(debugGrid, "add() Grid try at gridX,gridY", newt.gridX, newt.gridY) 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 // at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
t.uiGrid.Append(newt.uiControl, t.uiGrid.Append(newt.uiControl,
@ -130,14 +152,14 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
case toolkit.Group: case toolkit.Group:
if (t.uiBox == nil) { if (t.uiBox == nil) {
t.uiGroup.SetChild(newt.uiControl) 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 t.uiBox = newt.uiBox
} else { } else {
t.uiBox.Append(newt.uiControl, stretchy) t.uiBox.Append(newt.uiControl, stretchy)
} }
return true return true
case toolkit.Tab: case toolkit.Tab:
t.uiBox.Append(newt.uiControl, stretchy) t.uiTab.Append(a.Text, newt.uiControl)
t.boxC += 1 t.boxC += 1
return true return true
case toolkit.Box: case toolkit.Box:
@ -148,7 +170,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
t.uiWindow.SetChild(newt.uiControl) t.uiWindow.SetChild(newt.uiControl)
return true return true
default: default:
log(debugError, "add() how?", a.Where.Type) log(debugError, "add() how?", a.ParentId)
} }
return false return false
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -90,6 +90,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
return return
} }
/*
log(b, "widget.Name =", w.Name) log(b, "widget.Name =", w.Name)
log(b, "widget.Type =", w.Type) log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom) 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.Height =", w.Height)
log(b, "widget.X =", w.X) log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y) 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 // delete the child widget from the parent
// p = parent, c = child // p = parent, c = child
func destroy(p *toolkit.Widget, c *toolkit.Widget) { func destroy(pId int, cId int) {
log(true, "delete()", c.Name, c.Type) log(true, "delete()", pId, cId)
pt := mapToolkits[p] pt := andlabs[pId]
ct := mapToolkits[c] ct := andlabs[cId]
if (ct == nil) { 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 // this pukes out a whole universe of shit
// listMap() // listMap()
return return
} }
switch ct.tw.Type { switch ct.Type {
case toolkit.Button: case toolkit.Button:
log(true, "Should delete Button here:", c.Name) log(true, "Should delete Button here:", ct.Name)
log(true, "Parent:") log(true, "Parent:")
pt.Dump(true) pt.Dump(true)
log(true, "Child:") log(true, "Child:")
@ -38,16 +38,15 @@ func destroy(p *toolkit.Widget, c *toolkit.Widget) {
} }
case toolkit.Window: case toolkit.Window:
log(true, "Should delete Window here:", c.Name) log(true, "Should delete Window here:", ct.Name)
default: 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 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, "Don't know how to delete ct =", ct.tw.Type, ct.tw.Name, ct.uiButton)
log(true, "Parent:") log(true, "Parent:")
pt.Dump(true) pt.Dump(true)
log(true, "Child:") log(true, "Child:")
ct.Dump(true) 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) { if (ct.uiButton != nil) {
pt.uiBox.Delete(4) pt.uiBox.Delete(4)
ct.uiButton.Destroy() ct.uiButton.Destroy()

View File

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

View File

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

View File

@ -9,17 +9,15 @@ import (
func newGroup(a *toolkit.Action) { func newGroup(a *toolkit.Action) {
w := a.Widget w := a.Widget
parentW := a.Where
log(debugToolkit, "NewGroup()", w.Name) log(debugToolkit, "NewGroup()", w.Name)
t := mapToolkits[parentW] t := andlabs[a.ParentId]
if (t == nil) { 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) listMap(debugToolkit)
} }
newt := t.rawGroup(w.Name) newt := t.rawGroup(w.Name)
place(a, t, newt) place(a, t, newt)
mapWidgetsToolkits(a, newt)
} }
// make new Group here // make new Group here
@ -34,13 +32,5 @@ func (t *andlabsT) rawGroup(title string) *andlabsT {
newt.uiGroup = g newt.uiGroup = g
newt.uiControl = 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 return &newt
} }

View File

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

View File

@ -12,7 +12,7 @@ func newLabel(a *toolkit.Action) {
w := a.Widget w := a.Widget
log(debugToolkit, "NewLabel()", w.Name) log(debugToolkit, "NewLabel()", w.Name)
t := mapToolkits[a.Where] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
listMap(debugError) listMap(debugError)
log(debugError, "ERROR newLabel() listMap()") log(debugError, "ERROR newLabel() listMap()")
@ -30,5 +30,4 @@ func newLabel(a *toolkit.Action) {
newt.uiControl = c newt.uiControl = c
place(a, t, newt) 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 package main
import ( import (
"os" witlog "git.wit.org/wit/gui/log"
"runtime"
"runtime/pprof"
golog "log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
// "net"
) )
var LOGOFF bool = false // turn this off, all logging stops // various debugging flags
var WARN bool var logNow bool = true // useful for active development
var INFO bool var logError bool = true
var logWarn bool = false
type spewt struct { var logInfo bool = false
a bool var logVerbose bool = false
}
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) { func log(a ...any) {
if (LOGOFF) { witlog.Where = "wit/gui/andlabs"
return witlog.Log(a...)
} }
if (a == nil) { func sleep(a ...any) {
return witlog.Sleep(a...)
}
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)) { func exit(a ...any) {
// a = a[1:] witlog.Exit(a...)
a[0] = "GUI/Toolkit/Andlabs"
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)
} }

View File

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

View File

@ -31,43 +31,55 @@ func Action(a *toolkit.Action) {
rawAction(a) rawAction(a)
} }
if (callback == nil) {
if (a.Callback != nil) {
log(debugNow, "setting Callback", a.Callback)
callback = a.Callback
}
}
// f() // f()
Queue(f) Queue(f)
} }
func rawAction(a *toolkit.Action) { 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.S =", a.S)
log(debugAction, "Action() START a.Widget =", a.Widget) 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: case toolkit.Add:
add(a) add(a)
case toolkit.Show: case toolkit.Show:
a.Widget.B = true a.Widget.B = true
show(a.Widget) show(a)
case toolkit.Hide: case toolkit.Hide:
a.Widget.B = false a.Widget.B = false
show(a.Widget) show(a)
case toolkit.Enable: case toolkit.Enable:
a.Widget.B = true a.Widget.B = true
enable(a.Widget) enable(a)
case toolkit.Disable: case toolkit.Disable:
a.Widget.B = false a.Widget.B = false
enable(a.Widget) enable(a)
case toolkit.Get: case toolkit.Get:
setText(a) setText(a)
case toolkit.GetText: case toolkit.GetText:
switch a.Widget.Type { switch a.Widget.Type {
case toolkit.Textbox: case toolkit.Textbox:
t := mapToolkits[a.Widget] t := andlabs[a.WidgetId]
a.S = t.s a.S = t.s
} }
case toolkit.Set: case toolkit.Set:
setText(a) setText(a)
case toolkit.SetFlag:
flag(a)
case toolkit.SetText: case toolkit.SetText:
setText(a) setText(a)
case toolkit.AddText: case toolkit.AddText:
@ -82,15 +94,13 @@ func rawAction(a *toolkit.Action) {
pad(a) pad(a)
case toolkit.Delete: case toolkit.Delete:
uiDelete(a) uiDelete(a)
case toolkit.Flag:
flag(a)
case toolkit.Move: case toolkit.Move:
log(debugNow, "attempt to move() =", a.Type, a.Widget) log(debugNow, "attempt to move() =", a.ActionType, a.Widget)
move(a) move(a)
default: 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) { func flag(a *toolkit.Action) {
@ -122,70 +132,70 @@ func flag(a *toolkit.Action) {
} }
func setText(a *toolkit.Action) { func setText(a *toolkit.Action) {
w := a.Widget t := andlabs[a.WidgetId]
if (w == nil) { if (t == nil) {
log(debugError, "setText error. w.Widget == nil") log(debugError, "setText error. andlabs[id] == nil", a.WidgetId)
actionDump(debugError, a) actionDump(debugError, a)
return return
} }
t := mapToolkits[w] log(debugChange, "setText() Attempt on", t.Type, "with", a.S)
log(debugChange, "setText() Attempt on", w.Type, "with", a.S)
switch w.Type { switch t.Type {
case toolkit.Window: case toolkit.Window:
t.uiWindow.SetTitle(a.S) t.uiWindow.SetTitle(a.S)
case toolkit.Tab: case toolkit.Tab:
case toolkit.Group: case toolkit.Group:
t.uiGroup.SetTitle(a.S) t.uiGroup.SetTitle(a.S)
case toolkit.Checkbox: case toolkit.Checkbox:
switch a.Type { switch a.ActionType {
case toolkit.SetText: case toolkit.SetText:
t.uiCheckbox.SetText(a.S) t.uiCheckbox.SetText(a.S)
case toolkit.Get: case toolkit.Get:
w.B = t.uiCheckbox.Checked() t.tw.B = t.uiCheckbox.Checked()
case toolkit.Set: case toolkit.Set:
t.uiCheckbox.SetChecked(a.B) // TODO: commented out while working on chan
w.B = a.B // t.uiCheckbox.SetChecked(a.B)
t.tw.B = a.B
default: 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: case toolkit.Textbox:
switch a.Type { switch a.ActionType {
case toolkit.Set: case toolkit.Set:
t.uiMultilineEntry.SetText(a.S) t.uiMultilineEntry.SetText(a.S)
case toolkit.SetText: case toolkit.SetText:
t.uiMultilineEntry.SetText(a.S) t.uiMultilineEntry.SetText(a.S)
case toolkit.Get: case toolkit.Get:
w.S = t.s t.tw.S = t.s
case toolkit.GetText: case toolkit.GetText:
w.S = t.s t.tw.S = t.s
default: 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: case toolkit.Label:
t.uiLabel.SetText(a.S) t.uiLabel.SetText(a.S)
case toolkit.Button: case toolkit.Button:
t.uiButton.SetText(a.S) t.uiButton.SetText(a.S)
case toolkit.Slider: case toolkit.Slider:
switch a.Type { switch a.ActionType {
case toolkit.Get: case toolkit.Get:
w.I = t.uiSlider.Value() t.tw.I = t.uiSlider.Value()
case toolkit.Set: case toolkit.Set:
t.uiSlider.SetValue(a.I) t.uiSlider.SetValue(a.I)
default: 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: case toolkit.Spinner:
switch a.Type { switch a.ActionType {
case toolkit.Get: case toolkit.Get:
w.I = t.uiSpinbox.Value() t.tw.I = t.uiSpinbox.Value()
case toolkit.Set: case toolkit.Set:
t.uiSpinbox.SetValue(a.I) t.uiSpinbox.SetValue(a.I)
default: 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: case toolkit.Dropdown:
switch a.Type { switch a.ActionType {
case toolkit.AddText: case toolkit.AddText:
AddDropdownName(a) AddDropdownName(a)
case toolkit.Set: case toolkit.Set:
@ -199,7 +209,7 @@ func setText(a *toolkit.Action) {
log(debugChange, "i, s", i, s) log(debugChange, "i, s", i, s)
if (a.S == s) { if (a.S == s) {
t.uiCombobox.SetSelected(i) t.uiCombobox.SetSelected(i)
log(debugChange, "setText() Dropdown worked.", w.S) log(debugChange, "setText() Dropdown worked.", t.tw.S)
return return
} }
} }
@ -213,14 +223,14 @@ func setText(a *toolkit.Action) {
t.uiCombobox.SetSelected(i) t.uiCombobox.SetSelected(i)
} }
case toolkit.Get: case toolkit.Get:
w.S = t.s t.tw.S = t.s
case toolkit.GetText: case toolkit.GetText:
w.S = t.s t.tw.S = t.s
default: 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: case toolkit.Combobox:
switch a.Type { switch a.ActionType {
case toolkit.AddText: case toolkit.AddText:
t.AddComboboxName(a.S) t.AddComboboxName(a.S)
case toolkit.Set: case toolkit.Set:
@ -230,13 +240,13 @@ func setText(a *toolkit.Action) {
t.uiEditableCombobox.SetText(a.S) t.uiEditableCombobox.SetText(a.S)
t.s = a.S t.s = a.S
case toolkit.Get: case toolkit.Get:
w.S = t.s t.tw.S = t.s
case toolkit.GetText: case toolkit.GetText:
w.S = t.s t.tw.S = t.s
default: default:
log(debugError, "setText() unknown", a.Type, "on checkbox", w.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name)
} }
default: 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" _ "github.com/andlabs/ui/winmanifest"
) )
func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT { func (t *andlabsT) newSlider(a *toolkit.Action) *andlabsT {
// make new node here
log(debugToolkit, w.Name, w.Type, w.X, w.Y)
var newt 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.uiSlider = s
newt.uiControl = s newt.uiControl = s
newt.tw = w newt.tw = w
newt.Type = toolkit.Slider
newt.wId = a.WidgetId
s.OnChanged(func(spin *ui.Slider) { s.OnChanged(func(spin *ui.Slider) {
newt.tw.I = newt.uiSlider.Value() newt.tw.I = newt.uiSlider.Value()
newt.commonChange(newt.tw) newt.commonChange(newt.tw, a.WidgetId)
}) })
return &newt return &newt
@ -28,17 +30,15 @@ func (t *andlabsT) newSlider(w *toolkit.Widget) *andlabsT {
func newSlider(a *toolkit.Action) { func newSlider(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget w := a.Widget
parentW := a.Where
log(debugToolkit, "newSlider()", w.Name) log(debugToolkit, "newSlider()", w.Name)
t := mapToolkits[parentW] t := andlabs[a.ParentId]
if (t == nil) { 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 return
} }
w.X = a.X // w.X = a.X
w.Y = a.Y // w.Y = a.Y
newt = t.newSlider(w) newt = t.newSlider(a)
place(a, t, newt) place(a, t, newt)
mapWidgetsToolkits(a, newt)
} }

View File

@ -7,19 +7,21 @@ import (
_ "github.com/andlabs/ui/winmanifest" _ "github.com/andlabs/ui/winmanifest"
) )
func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT { func (t *andlabsT) newSpinner(a *toolkit.Action) *andlabsT {
// make new node here
log(debugToolkit, "newSpinner()", w.X, w.Y)
var newt 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.uiSpinbox = s
newt.uiControl = s newt.uiControl = s
newt.tw = w newt.tw = w
newt.wId = a.WidgetId
newt.Type = toolkit.Spinner
s.OnChanged(func(s *ui.Spinbox) { s.OnChanged(func(s *ui.Spinbox) {
newt.tw.I = newt.uiSpinbox.Value() newt.tw.I = newt.uiSpinbox.Value()
newt.commonChange(newt.tw) newt.commonChange(newt.tw, a.WidgetId)
}) })
return &newt return &newt
@ -28,16 +30,12 @@ func (t *andlabsT) newSpinner(w *toolkit.Widget) *andlabsT {
func newSpinner(a *toolkit.Action) { func newSpinner(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget w := a.Widget
parentW := a.Where
t := mapToolkits[parentW] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugError, "NewSpinner() toolkit struct == nil. name=", parentW.Name, w.Name) log(debugError, "NewSpinner() toolkit struct == nil. name=", w.Name)
return return
} }
w.X = a.X newt = t.newSpinner(a)
w.Y = a.Y
newt = t.newSpinner(w)
place(a, t, newt) 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"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
var andlabs map[int]*andlabsT
var callback func(int)
// stores the raw toolkit internals // stores the raw toolkit internals
type andlabsT struct { type andlabsT struct {
id string wId int // widget ID
Type toolkit.WidgetType
Name string Name string
// Type toolkit.WidgetType // Type toolkit.WidgetType
Width int Width int
Height int Height int
tw *toolkit.Widget tw *toolkit.Widget
parent *andlabsT parent *andlabsT

View File

@ -19,36 +19,43 @@ import (
once there is one. If you send a Window here, it will replace once there is one. If you send a Window here, it will replace
any existing tabs rather than adding a new one 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 w *ui.Window
var newt *andlabsT var newt *andlabsT
log(debugToolkit, "gui.toolkit.AddTab()") log(debugToolkit, "newTab() START", a.WidgetId, a.ParentId)
if (t.uiWindow == nil) {
log(debugToolkit, "gui.Toolkit.UiWindow == nil. I can't add a toolbar without window")
return nil
}
if (t.uiTab == nil) { 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 // this means you have to make a new tab
log(debugToolkit, "gui.toolkit.NewTab() GOOD. This should be the first tab:", name) log(debugToolkit, "newTab() GOOD. This should be the first tab:", a.WidgetId, a.ParentId)
newt = rawTab(t.uiWindow, name) newt = rawTab(t.uiWindow, a.Text)
t.uiTab = newt.uiTab t.uiTab = newt.uiTab
} else { } else {
// this means you have to append a tab // this means you have to append a tab
log(debugToolkit, "gui.toolkit.NewTab() GOOD. This should be an additional tab:", name) log(debugToolkit, "newTab() GOOD. This should be an additional tab:", a.WidgetId, a.ParentId)
newt = t.appendTab(name) 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:") log(debugToolkit, "t:")
t.Dump(debugToolkit) t.Dump(debugToolkit)
log(debugToolkit, "newt:") log(debugToolkit, "newt:")
newt.Dump(debugToolkit) newt.Dump(debugToolkit)
return newt
} }
// This sets _all_ the tabs to Margin = true // 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 { func rawTab(w *ui.Window, name string) *andlabsT {
var newt andlabsT var newt andlabsT
log(debugToolkit, "gui.toolkit.NewTab() ADD", name) log(debugToolkit, "rawTab() START", name)
if (w == nil) { if (w == nil) {
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(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(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")
sleep(1) sleep(1)
return nil return nil
} }
log(debugToolkit, "gui.toolkit.AddTab() START name =", name)
tab := ui.NewTab() 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) w.SetChild(tab)
newt.uiWindow = w
newt.uiTab = tab newt.uiTab = tab
newt.uiControl = tab newt.uiControl = tab
newt.uiBox = hbox log(debugToolkit, "rawTab() END", name)
return &newt return &newt
} }
@ -120,20 +119,14 @@ func (t *andlabsT) appendTab(name string) *andlabsT {
} }
func newTab(a *toolkit.Action) { func newTab(a *toolkit.Action) {
parentW := a.Where // w := a.Widget
w := a.Widget log(debugToolkit, "newTab()", a.ParentId)
var newt *andlabsT
log(debugToolkit, "gui.andlabs.NewTab()", w.Name)
t := mapToolkits[parentW] t := andlabs[a.ParentId]
if (t == nil) { 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 return
} }
newt = t.newTab(w.Name) t.newTab(a)
mapWidgetsToolkits(a, newt)
}
func doTab(a *toolkit.Action) {
newTab(a)
} }

View File

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

View File

@ -1,69 +1,24 @@
package main package main
import ( 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 // This is a map between the widgets in wit/gui and the internal structures of gocui
var mapWidgets map[*andlabsT]*toolkit.Widget // var mapWidgets map[*andlabsT]*toolkit.Widget
var mapToolkits map[*toolkit.Widget]*andlabsT // var mapToolkits map[*toolkit.Widget]*andlabsT
// This lists out the known mappings // This lists out the known mappings
// deprecate and use instead the GUI interface // deprecate and use instead the GUI interface
func listMap(b bool) { func listMap(b bool) {
log(b, "listMap() disabled HERE. output too big") log(b, "listMap() disabled HERE. output too big")
return return
for t, w := range mapWidgets {
log(b, "andlabs =", t.Name, "widget =", w.Name)
}
log(b, "listMap() HERE mapToolkits()") log(b, "listMap() HERE mapToolkits()")
for w, t := range mapToolkits { for i, t := range andlabs {
log(b, "andlabs =", t, "widget =", w.Name) log(b, "andlabs =", t, "widgetId =", i)
t.Dump(b) t.Dump(b)
} }
log(b, "listMap() HERE mapWidgets()") log(b, "listMap() HERE mapWidgets()")
log(b, "listMap() HERE FIXME. output too big") 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 w := a.Widget
var newt *andlabsT 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) { if (w == nil) {
log(debugToolkit, "wit/gui plugin error. widget == nil") log(debugToolkit, "wit/gui plugin error. widget == nil")
@ -27,13 +27,15 @@ func newWindow(a *toolkit.Action) {
} }
newt = new(andlabsT) newt = new(andlabsT)
newt.tw = w 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 // 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.SetBorderless(canvas)
win.SetMargined(margin) win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool { win.OnClosing(func(*ui.Window) bool {
newt.commonChange(newt.tw) newt.commonChange(newt.tw, a.WidgetId)
return true return true
}) })
win.Show() win.Show()
@ -42,16 +44,17 @@ func newWindow(a *toolkit.Action) {
// newt.UiWindowBad = win // deprecate this as soon as possible // newt.UiWindowBad = win // deprecate this as soon as possible
newt.Name = w.Name newt.Name = w.Name
mapWidgetsToolkits(a, newt) andlabs[a.WidgetId] = newt
return return
} }
func (t *andlabsT) SetWindowTitle(title string) { func (t *andlabsT) SetWindowTitle(title string) {
log(debugToolkit, "toolkit NewWindow", t.Name, "title", title) log(debugToolkit, "toolkit NewWindow", t.Name, "title", title)
win := t.uiWindow win := t.uiWindow
if (win != nil) { if (win == nil) {
win.SetTitle(title) log(debugError, "Error: no window", t.wId)
} else { } else {
win.SetTitle(title)
log(debugToolkit, "Setting the window title", 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:
objdump -t ../democui.so |less 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 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 debugError bool = true
var canvas bool // if set to true, the windows are a raw canvas
var menubar bool // for windows
var stretchy bool // expand things like buttons to the maximum size
var padded bool // add space between things like buttons
var margin bool // add space around the frames of windows
var debugToolkit bool
var debugChange bool
var debugPlugin bool
var debugFlags bool
var debugError bool = true
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc // This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func setDefaultBehavior(s bool) { func setDefaultBehavior(s bool) {
defaultBehavior = s me.defaultBehavior = s
if (defaultBehavior) { if (me.defaultBehavior) {
log(debugToolkit, "Setting this toolkit to use the default behavior.") log(logInfo, "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.") log(logInfo, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
stretchy = false me.stretchy = false
padded = true me.padded = true
menubar = true me.menubar = true
margin = true me.margin = true
canvas = false me.canvas = false
bookshelf = true // 99% of the time, things make a vertical stack of objects me.bookshelf = true // 99% of the time, things make a vertical stack of objects
} else { } 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 () { func actionDump(b bool, a *toolkit.Action) {
log(true, "debugToolkit =", debugToolkit) if (a == nil) {
log(true, "debugChange =", debugChange) log(b, "action = nil")
log(true, "debugPlugin =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugError =", debugError)
}
/*
func (t *gocuiT) Dump(b bool) {
if ! b {
return return
} }
log(b, "Name = ", t.Name, t.Width, t.Height)
if (t.uiBox != nil) { log(b, "a.Name =", a.Name)
log(b, "uiBox =", t.uiBox) 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)
} }
if (t.uiButton != nil) {
log(b, "uiButton =", t.uiButton)
}
if (t.uiCombobox != nil) {
log(b, "uiCombobox =", t.uiCombobox)
}
if (t.uiWindow != nil) {
log(b, "uiWindow =", t.uiWindow)
}
if (t.uiTab != nil) {
log(b, "uiTab =", t.uiTab)
}
if (t.uiGroup != nil) {
log(b, "uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log(b, "uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
}
if (t.uiSlider != nil) {
log(b, "uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log(b, "uiCheckbox =", t.uiCheckbox)
}
widgetDump(b, t.tw)
}
*/
func widgetDump(b bool, w *toolkit.Widget) { func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) { if (w == nil) {
@ -88,6 +48,7 @@ func widgetDump(b bool, w *toolkit.Widget) {
return return
} }
/*
log(b, "widget.Name =", w.Name) log(b, "widget.Name =", w.Name)
log(b, "widget.Type =", w.Type) log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom) 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.Height =", w.Height)
log(b, "widget.X =", w.X) log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y) log(b, "widget.Y =", w.Y)
*/
} }
/* func dumpWidgets(g *gocui.Gui, v *gocui.View) {
func GetDebugToolkit () bool { for _, view := range g.Views() {
return debugToolkit 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 package main
import ( import (
"os" "os"
golog "log" witlog "git.wit.org/wit/gui/log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
) )
var LOGOFF bool = false // turn this off, all logging stops // various debugging flags
var WARN bool var logNow bool = true // useful for active development
var INFO bool var logError bool = true
var logWarn bool = false
type spewt struct { var logInfo bool = false
a bool var logVerbose bool = false
}
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) { func log(a ...any) {
if (LOGOFF) { witlog.Where = "wit/democui"
return witlog.Log(a...)
} }
if (a == nil) { func sleep(a ...any) {
return witlog.Sleep(a...)
}
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)) { func exit(a ...any) {
// a = a[1:] witlog.Exit(a...)
a[0] = "GUI/Toolkit/gocui"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
}
func logindent(depth int, format string, a ...interface{}) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
}
// newFormat := tabs + strconv.Itoa(depth) + " " + format
newFormat := tabs + format
log(debugToolkit, newFormat, a)
} }
func setOutput(f *os.File) { 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 ( import (
"errors" "errors"
"fmt" "fmt"
"os"
"github.com/awesome-gocui/gocui" "github.com/awesome-gocui/gocui"
) )
var g *gocui.Gui func MouseMain() {
var err error g, err := gocui.NewGui(gocui.OutputNormal, true)
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)
if err != nil { if err != nil {
exit("error opening file: %v", err) panic(err)
} }
defer f.Close() defer g.Close()
setOutput(f) me.baseGui = g
log("This is a test log entry")
g, err = gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
exit(err)
}
g.Cursor = true g.Cursor = true
g.Mouse = true g.Mouse = true
g.SetManagerFunc(layout) g.SetManagerFunc(layout)
if err := keybindings(g); err != nil { if err := defaultKeybindings(g); err != nil {
exit(err) panic(err)
} }
log("exit Init()")
}
func StartConsoleMouse() {
defer g.Close()
log("start Main()")
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) { if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
exit(err) panic(err)
} }
log("exit Main()")
} }
func layout(g *gocui.Gui) error { 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) { if !errors.Is(err, gocui.ErrUnknownView) {
return err return err
} }
v.Highlight = true
v.SelBgColor = gocui.ColorGreen v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "andlabs") fmt.Fprintln(v, "Button 1 - line 1")
fmt.Fprintln(v, "addDemoTab") fmt.Fprintln(v, "Button 1 - line 2")
fmt.Fprintln(v, "DemoToolkitWindow") fmt.Fprintln(v, "Button 1 - line 3")
fmt.Fprintln(v, "DebugWindow") fmt.Fprintln(v, "Button 1 - line 4")
fmt.Fprintln(v, "do nothing")
fmt.Fprintln(v, "exit")
if _, err := g.SetCurrentView("but1"); err != nil { if _, err := g.SetCurrentView("but1"); err != nil {
return err return err
} }
@ -94,59 +63,12 @@ func layout(g *gocui.Gui) error {
if !errors.Is(err, gocui.ErrUnknownView) { if !errors.Is(err, gocui.ErrUnknownView) {
return err return err
} }
v.Highlight = true
v.SelBgColor = gocui.ColorGreen v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1") fmt.Fprintln(v, "Button 2 - line 1")
} }
if v, err := g.SetView("but3", 24, 2, 44, 4, 0); err != nil { helplayout(g)
if !errors.Is(err, gocui.ErrUnknownView) { updateHighlightedView(g)
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
if v, err := g.SetView("but4", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
if v, err := g.SetView("but5", 24, 2, 44, 4, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.Highlight = true
v.SelBgColor = gocui.ColorGreen
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1")
}
return nil
}
func keybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
for _, n := range []string{"but1", "but2"} {
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
return err
}
}
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, delMsg); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseRight, gocui.ModNone, delMsg); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseMiddle, gocui.ModNone, delMsg); err != nil {
return err
}
return nil return nil
} }
@ -168,18 +90,80 @@ func showMsg(g *gocui.Gui, v *gocui.View) error {
} }
maxX, maxY := g.Size() 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 v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
if !errors.Is(err, gocui.ErrUnknownView) { v.Clear()
return err v.SelBgColor = gocui.ColorCyan
} v.SelFgColor = gocui.ColorBlack
mouseClick(l)
fmt.Fprintln(v, l) fmt.Fprintln(v, l)
} }
return nil return nil
} }
func delMsg(g *gocui.Gui, v *gocui.View) error { func updateHighlightedView(g *gocui.Gui) {
// Error check removed, because delete could be called multiple times with the above keybindings mx, my := g.MousePosition()
g.DeleteView("msg") 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 return nil
} }

View File

@ -4,112 +4,15 @@ import (
// if you include more than just this 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) // then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
"git.wit.org/wit/gui/toolkit" "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() { func Quit() {
g.Close() me.baseGui.Close()
} }
// This lists out the know mappings func Action(a *toolkit.Action) {
func listMap() { log(logNow, "Action()", a)
for v, w := range viewWidget { w := setupWidgetT(a)
log("view =", v.Name, "widget name =", w.Name) place(w, a)
} log(logInfo, "Action() END")
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")
}
} }

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 return
} }
/*
log(b, "widget.Name =", w.Name) log(b, "widget.Name =", w.Name)
// log(b, "widget.Action =", w.Action) // log(b, "widget.Action =", w.Action)
log(b, "widget.Type =", w.Type) 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.Height =", w.Height)
log(b, "widget.X =", w.X) log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y) 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 package main
import ( import (
"os" "os"
golog "log" witlog "git.wit.org/wit/gui/log"
"time"
"reflect"
"github.com/davecgh/go-spew/spew"
) )
var LOGOFF bool = false // turn this off, all logging stops
var WARN bool
var INFO bool
type spewt struct {
a bool
}
var SPEW spewt
/*
sleep() # you know what this does? sleeps for 1 second. yep. dump. easy.
sleep(.1) # you know what this does? yes, it sleeps for 1/10th of a second
*/
func sleep(a ...any) {
if (a == nil) {
time.Sleep(time.Second)
return
}
log(true, "sleep", a[0])
switch a[0].(type) {
case int:
time.Sleep(time.Duration(a[0].(int)) * time.Second)
case float64:
time.Sleep(time.Duration(a[0].(float64) * 1000) * time.Millisecond)
default:
log("sleep a[0], type = ", a[0], reflect.TypeOf(a[0]))
}
}
/*
exit() # yep. exits. I guess everything must be fine
exit(3) # I guess 3 it is then
exit("dont like apples") # ok. I'll make a note of that
*/
func exit(a ...any) {
log(true, "exit", a)
//if (a) {
// os.Exit(a)
//}
os.Exit(0)
}
/*
I've spent, am spending, too much time thinking about 'logging'. 'log', 'logrus', 'zap', whatever.
I'm not twitter. i don't give a fuck about how many nanoseconds it takes to log. Anyway, this
implementation is probably faster than all of those because you just set one bool to FALSE
and it all stops.
Sometimes I need to capture to stdout, sometimes stdout can't
work because it doesn't exist for the user. This whole thing is a PITA. Then it's spread
over 8 million references in every .go file. I'm tapping out and putting
it in one place. here it is. Also, this makes having debug levels really fucking easy.
You can define whatever level of logging you want from anywhere (command line) etc.
log() # doesn't do anything
log(stuff) # sends it to whatever log you define in a single place. here is the place
*/
func log(a ...any) { func log(a ...any) {
if (LOGOFF) { witlog.Log(a...)
return
} }
if (a == nil) { func sleep(a ...any) {
return witlog.Sleep(a...)
}
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)) { func exit(a ...any) {
// a = a[1:] witlog.Exit(a...)
a[0] = "GUI/Toolkit/gocui"
if (debugToolkit) {
scs := spew.ConfigState{MaxDepth: 1}
scs.Dump(a)
// spew.Dump(a)
}
return
}
golog.Println(a...)
}
func logindent(depth int, format string, a ...interface{}) {
var tabs string
for i := 0; i < depth; i++ {
tabs = tabs + format
}
// newFormat := tabs + strconv.Itoa(depth) + " " + format
newFormat := tabs + format
log(debugToolkit, newFormat, a)
} }
func setOutput(f *os.File) { 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() // All Toolkit interactions should be done via a channel or Queue()
// TODO: FIGURE OUT HOW TO IMPLEMENT THIS // 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 // 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?) // Could a protobuf be used here? (Can functions be passed?)
type Widget struct { type Widget struct {
Name string Name string
// Action string // "New", "Delete", "Set", aka something to do
Type WidgetType Type WidgetType
// This function is how you interact with the toolkit // This function is how you interact with the toolkit
@ -29,7 +30,7 @@ type Widget struct {
Callback func() Callback func()
// re-adding an id to test channels // re-adding an id to test channels
id int Id int
// This is how the values are passed back and forth // This is how the values are passed back and forth
// values from things like checkboxes & dropdown's // values from things like checkboxes & dropdown's
@ -39,32 +40,22 @@ type Widget struct {
// maybe safe if there is correctly working Custom() between goroutines? // maybe safe if there is correctly working Custom() between goroutines?
// (still probably not, almost certainly not. not possible. layer violation?) // (still probably not, almost certainly not. not possible. layer violation?)
S string // not safe to have 'S' 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 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 // this should be the widget
// if the action is New, Hide, Enable, etc // if the action is New, Hide, Enable, etc
Widget *Widget Widget *Widget
Callback func(int)
// this is the widget
// where the other one should be put on New, Move, etc
Where *Widget
// This is how the values are passed back and forth // This is how the values are passed back and forth
// values from things like checkboxes & dropdown's // values from things like checkboxes & dropdown's
@ -90,31 +81,30 @@ type Action struct {
Expand bool Expand bool
} }
// https://ieftimov.com/post/golang-datastructures-trees/
// TODO: protobuf ?
const ( const (
Unknown WidgetType = iota Unknown WidgetType = iota
Window Root // the master 'root' node of the binary tree
Tab // internally, this should be a window (?) Flag // used to send configuration values to plugins
Frame // should windows and tab's be frames (?) Window // in certain gui's (ncurses), these are tabs
Grid // a grid of frames ? Tab // internally, this is a window
Group // internally, this should be a grid (?) Frame // deprecate?
Box // internally, this should be a grid (?) Grid // like drawers in a chest
Group // like the 'Appetizers' section on a menu
Box // a vertical or horizontal stack of widgets
Button Button
Checkbox Checkbox // select 'on' or 'off'
Dropdown Dropdown
Combobox // dropdown with edit=true (?) Combobox // dropdown with edit=true
Label Label
Textbox // is this a Label with edit=true? Textbox // is this a Label with edit=true
Slider Slider // like a progress bar
Spinner Spinner // like setting the oven temperature
Image Image // TODO
Area Area // TODO
Form Form // TODO
Font Font // TODO
Color Color // TODO
Dialog Dialog // TODO
) )
const ( const (
@ -122,7 +112,6 @@ const (
Delete Delete
Get Get
Set Set
SetFlag
GetText GetText
SetText SetText
AddText AddText
@ -137,11 +126,14 @@ const (
Append Append
Move Move
Dump Dump
Flag
) )
func (s WidgetType) String() string { func (s WidgetType) String() string {
switch s { switch s {
case Root:
return "Root"
case Flag:
return "Flag"
case Window: case Window:
return "Window" return "Window"
case Tab: case Tab:
@ -185,7 +177,7 @@ func (s WidgetType) String() string {
case Unknown: case Unknown:
return "Unknown" return "Unknown"
} }
return "Widget.Type.String() Error" return "WidgetType.String() Error"
} }
func (s ActionType) String() string { func (s ActionType) String() string {
@ -198,8 +190,6 @@ func (s ActionType) String() string {
return "Get" return "Get"
case Set: case Set:
return "Set" return "Set"
case SetFlag:
return "SetFlag"
case GetText: case GetText:
return "GetText" return "GetText"
case SetText: case SetText:
@ -226,22 +216,8 @@ func (s ActionType) String() string {
return "Append" return "Append"
case Move: case Move:
return "Move" return "Move"
case Flag:
return "Flag"
case Dump: case Dump:
return "Dump" return "Dump"
} }
return "Action.Type.String() Error" return "ActionType.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
} }

View File

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