gocui: callbacks work via a channel
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
90e45a4a3e
commit
bddce3d5a3
|
@ -131,13 +131,13 @@ Creates a window helpful for debugging this package
|
||||||
|
|
||||||
`func InitPlugins(names []string)`
|
`func InitPlugins(names []string)`
|
||||||
|
|
||||||
### func [LoadToolkit](/plugin.go#L46)
|
### func [LoadToolkit](/plugin.go#L50)
|
||||||
|
|
||||||
`func LoadToolkit(name string) bool`
|
`func LoadToolkit(name string) bool`
|
||||||
|
|
||||||
loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
||||||
|
|
||||||
### func [Main](/main.go#L127)
|
### func [Main](/main.go#L143)
|
||||||
|
|
||||||
`func Main(f func())`
|
`func Main(f func())`
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ This should not pass a function
|
||||||
|
|
||||||
`func ShowDebugValues()`
|
`func ShowDebugValues()`
|
||||||
|
|
||||||
### func [StandardExit](/main.go#L179)
|
### func [StandardExit](/main.go#L204)
|
||||||
|
|
||||||
`func StandardExit()`
|
`func StandardExit()`
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ This struct can be used with the go-arg package
|
||||||
var Config GuiConfig
|
var Config GuiConfig
|
||||||
```
|
```
|
||||||
|
|
||||||
### type [Node](/structs.go#L58)
|
### type [Node](/structs.go#L60)
|
||||||
|
|
||||||
`type Node struct { ... }`
|
`type Node struct { ... }`
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ You get a window
|
||||||
|
|
||||||
`func Start() *Node`
|
`func Start() *Node`
|
||||||
|
|
||||||
#### func [StartS](/main.go#L113)
|
#### func [StartS](/main.go#L129)
|
||||||
|
|
||||||
`func StartS(name string) *Node`
|
`func StartS(name string) *Node`
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ func (n *Node) DebugGoChannels(makeWindow bool) {
|
||||||
debugWG.Done()
|
debugWG.Done()
|
||||||
})
|
})
|
||||||
g.NewButton("close chan", func () {
|
g.NewButton("close chan", func () {
|
||||||
|
log("close() on", debugNumberChan)
|
||||||
close(debugNumberChan)
|
close(debugNumberChan)
|
||||||
})
|
})
|
||||||
g.NewButton("print", func () {
|
g.NewButton("print", func () {
|
||||||
|
|
25
main.go
25
main.go
|
@ -104,6 +104,22 @@ func Start() *Node {
|
||||||
return Config.rootNode
|
return Config.rootNode
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func doSomething() {
|
||||||
|
log(logNow, "doSomething()")
|
||||||
|
}
|
||||||
|
|
||||||
|
func watchCallback() {
|
||||||
|
log(logNow, "makeCallback() START")
|
||||||
|
for {
|
||||||
|
log(logNow, "makeCallback() for loop")
|
||||||
|
select {
|
||||||
|
case a := <-Config.guiChan:
|
||||||
|
log(logNow, "makeCallback() SELECT widget id =", a.WidgetId, a.Name)
|
||||||
|
sleep(.5) // TODO: remove this. added while under development
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (n *Node) LoadPlugin(name string) bool {
|
func (n *Node) LoadPlugin(name string) bool {
|
||||||
StartS(name)
|
StartS(name)
|
||||||
Redraw(name)
|
Redraw(name)
|
||||||
|
@ -129,6 +145,11 @@ func Main(f func()) {
|
||||||
|
|
||||||
InitPlugins([]string{"andlabs", "gocui"})
|
InitPlugins([]string{"andlabs", "gocui"})
|
||||||
|
|
||||||
|
if (Config.guiChan == nil) {
|
||||||
|
Config.guiChan = make(chan toolkit.Action)
|
||||||
|
go watchCallback()
|
||||||
|
}
|
||||||
|
|
||||||
for _, aplug := range allPlugins {
|
for _, aplug := range allPlugins {
|
||||||
log(debugGui, "gui.Node.NewButton() toolkit plugin =", aplug.name)
|
log(debugGui, "gui.Node.NewButton() toolkit plugin =", aplug.name)
|
||||||
if (aplug.MainOk) {
|
if (aplug.MainOk) {
|
||||||
|
@ -140,8 +161,12 @@ func Main(f func()) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
aplug.MainOk = true
|
aplug.MainOk = true
|
||||||
|
if (aplug.Callback != nil) {
|
||||||
|
aplug.Callback(Config.guiChan)
|
||||||
|
}
|
||||||
aplug.Main(f)
|
aplug.Main(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
25
plugin.go
25
plugin.go
|
@ -33,6 +33,10 @@ type aplug struct {
|
||||||
Quit func()
|
Quit func()
|
||||||
// NewWindow func(*toolkit.Widget)
|
// NewWindow func(*toolkit.Widget)
|
||||||
|
|
||||||
|
// sets the chan for the plugin to call back too
|
||||||
|
Callback func(chan toolkit.Action)
|
||||||
|
// 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)
|
||||||
|
|
||||||
|
@ -83,6 +87,8 @@ func LoadToolkit(name string) bool {
|
||||||
// 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")
|
||||||
|
|
||||||
|
newPlug.Callback = loadCallback(&newPlug, "Callback")
|
||||||
|
|
||||||
allPlugins = append(allPlugins, &newPlug)
|
allPlugins = append(allPlugins, &newPlug)
|
||||||
|
|
||||||
log(debugPlugin, "gui.LoadToolkit() END", newPlug.name, filename)
|
log(debugPlugin, "gui.LoadToolkit() END", newPlug.name, filename)
|
||||||
|
@ -112,6 +118,25 @@ func loadFuncE(p *aplug, funcName string) func() {
|
||||||
return newfunc
|
return newfunc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func loadCallback(p *aplug, funcName string) func(chan toolkit.Action) {
|
||||||
|
var newfunc func(chan toolkit.Action)
|
||||||
|
var ok bool
|
||||||
|
var test plugin.Symbol
|
||||||
|
|
||||||
|
test, err = p.plug.Lookup(funcName)
|
||||||
|
if err != nil {
|
||||||
|
log(debugGui, "DID NOT FIND: name =", test, "err =", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
newfunc, ok = test.(func(chan toolkit.Action))
|
||||||
|
if !ok {
|
||||||
|
log(debugGui, "function name =", funcName, "names didn't map correctly. Fix the plugin name =", p.name)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return newfunc
|
||||||
|
}
|
||||||
|
|
||||||
func loadFunc2(p *aplug, funcName string) func(*toolkit.Widget, *toolkit.Widget) {
|
func loadFunc2(p *aplug, funcName string) func(*toolkit.Widget, *toolkit.Widget) {
|
||||||
var newfunc func(*toolkit.Widget, *toolkit.Widget)
|
var newfunc func(*toolkit.Widget, *toolkit.Widget)
|
||||||
var ok bool
|
var ok bool
|
||||||
|
|
|
@ -51,6 +51,8 @@ type GuiConfig struct {
|
||||||
|
|
||||||
ActionCh1 chan int
|
ActionCh1 chan int
|
||||||
ActionCh2 chan int
|
ActionCh2 chan int
|
||||||
|
|
||||||
|
guiChan chan toolkit.Action
|
||||||
}
|
}
|
||||||
|
|
||||||
// The Node is a binary tree. This is how all GUI elements are stored
|
// The Node is a binary tree. This is how all GUI elements are stored
|
||||||
|
|
|
@ -34,6 +34,7 @@ func (w *cuiWidget) doWidgetClick() {
|
||||||
} else {
|
} else {
|
||||||
w.setCheckbox(true)
|
w.setCheckbox(true)
|
||||||
}
|
}
|
||||||
|
w.doUserEvent()
|
||||||
case toolkit.Grid:
|
case toolkit.Grid:
|
||||||
me.rootNode.hideWidgets()
|
me.rootNode.hideWidgets()
|
||||||
w.placeGrid()
|
w.placeGrid()
|
||||||
|
@ -47,10 +48,28 @@ func (w *cuiWidget) doWidgetClick() {
|
||||||
}
|
}
|
||||||
w.placeWidgets()
|
w.placeWidgets()
|
||||||
w.toggleTree()
|
w.toggleTree()
|
||||||
|
case toolkit.Button:
|
||||||
|
w.doUserEvent()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this passes the user event back from the plugin
|
||||||
|
func (w *cuiWidget) doUserEvent() {
|
||||||
|
if (me.callback == nil) {
|
||||||
|
log(logError, "doUserEvent() no callback channel was configured")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var a toolkit.Action
|
||||||
|
a.WidgetId = w.id
|
||||||
|
a.Name = w.name
|
||||||
|
a.Text = w.text
|
||||||
|
a.B = w.b
|
||||||
|
a.ActionType = toolkit.User
|
||||||
|
me.callback <- a
|
||||||
|
log(logNow, "END: sent a button click callback()")
|
||||||
|
}
|
||||||
|
|
||||||
var toggle bool = true
|
var toggle bool = true
|
||||||
func (w *cuiWidget) toggleTree() {
|
func (w *cuiWidget) toggleTree() {
|
||||||
if (toggle) {
|
if (toggle) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
|
"git.wit.org/wit/gui/toolkit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Init() {
|
func Init() {
|
||||||
|
@ -27,6 +28,11 @@ func Init() {
|
||||||
me.padH = 3
|
me.padH = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this sets the channel to send user events back from the plugin
|
||||||
|
func Callback(guiCallback chan toolkit.Action) {
|
||||||
|
me.callback = guiCallback
|
||||||
|
}
|
||||||
|
|
||||||
func Exit() {
|
func Exit() {
|
||||||
// TODO: exit correctly
|
// TODO: exit correctly
|
||||||
me.baseGui.Close()
|
me.baseGui.Close()
|
||||||
|
|
|
@ -23,7 +23,7 @@ type config struct {
|
||||||
rootNode *cuiWidget // the base of the binary tree. it should have id == 0
|
rootNode *cuiWidget // the base of the binary tree. it should have id == 0
|
||||||
ctrlDown *cuiWidget // shown if you click the mouse when the ctrl key is pressed
|
ctrlDown *cuiWidget // shown if you click the mouse when the ctrl key is pressed
|
||||||
|
|
||||||
callback func(int)
|
callback chan toolkit.Action
|
||||||
helpLabel *gocui.View
|
helpLabel *gocui.View
|
||||||
|
|
||||||
defaultBehavior bool
|
defaultBehavior bool
|
||||||
|
|
|
@ -110,6 +110,7 @@ const (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Add ActionType = iota
|
Add ActionType = iota
|
||||||
|
User // the user did something (mouse, keyboard, etc)
|
||||||
Delete
|
Delete
|
||||||
Get
|
Get
|
||||||
Set
|
Set
|
||||||
|
|
|
@ -15,7 +15,7 @@ var watchtime time.Duration = 100 // in tenths of seconds
|
||||||
func Watchdog() {
|
func Watchdog() {
|
||||||
var i = 1
|
var i = 1
|
||||||
for {
|
for {
|
||||||
log(debugGui, "watchdog timer is alive. give me something to do.", i)
|
log(logInfo, "watchdog timer is alive. give me something to do.", i)
|
||||||
i += 1
|
i += 1
|
||||||
time.Sleep(watchtime * time.Second / 10)
|
time.Sleep(watchtime * time.Second / 10)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue