better toolkit init options
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
a235371d1a
commit
ca708db97e
|
@ -123,20 +123,17 @@ Creates a window helpful for debugging this package
|
|||
|
||||
`func ExampleCatcher(f func())`
|
||||
|
||||
### func [FindPlugin](/plugin.go#L64)
|
||||
|
||||
`func FindPlugin(name string) *aplug`
|
||||
|
||||
loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
||||
attempts to locate the .so file
|
||||
|
||||
### func [Indent](/debug.go#L120)
|
||||
|
||||
`func Indent(b bool, a ...interface{})`
|
||||
|
||||
### func [LoadPlugin](/main.go#L114)
|
||||
|
||||
`func LoadPlugin(name string) bool`
|
||||
|
||||
### func [LoadToolkit](/plugin.go#L68)
|
||||
|
||||
`func LoadToolkit(name string) *aplug`
|
||||
|
||||
loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
||||
|
||||
### func [SetDebug](/debug.go#L28)
|
||||
|
||||
`func SetDebug(s bool)`
|
||||
|
@ -149,7 +146,7 @@ loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
|||
|
||||
`func ShowDebugValues()`
|
||||
|
||||
### func [StandardExit](/main.go#L155)
|
||||
### func [StandardExit](/main.go#L153)
|
||||
|
||||
`func StandardExit()`
|
||||
|
||||
|
@ -190,7 +187,7 @@ var Config GuiConfig
|
|||
The Node is a binary tree. This is how all GUI elements are stored
|
||||
simply the name and the size of whatever GUI element exists
|
||||
|
||||
#### func [New](/main.go#L132)
|
||||
#### func [New](/main.go#L126)
|
||||
|
||||
`func New() *Node`
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ func main() {
|
|||
// This will turn on all debugging
|
||||
// gui.SetDebug(true)
|
||||
|
||||
myGui = gui.New()
|
||||
myGui = gui.New().LoadToolkit("gocui")
|
||||
buttonWindow()
|
||||
|
||||
// This is just a optional goroutine to watch that things are alive
|
||||
|
@ -55,11 +55,11 @@ func buttonWindow() {
|
|||
g.NewButton("Load 'gocui'", func () {
|
||||
// this set the xterm and mate-terminal window title. maybe works generally?
|
||||
fmt.Println("\033]0;" + title + "blah \007")
|
||||
gui.LoadPlugin("gocui")
|
||||
myGui.LoadToolkit("gocui")
|
||||
})
|
||||
|
||||
g.NewButton("Load 'andlabs'", func () {
|
||||
gui.LoadPlugin("andlabs")
|
||||
myGui.LoadToolkit("andlabs")
|
||||
})
|
||||
|
||||
g.NewButton("NewButton(more)", func () {
|
||||
|
|
|
@ -90,8 +90,8 @@ func (n *Node) DebugTab(title string) *Node {
|
|||
}
|
||||
})
|
||||
|
||||
g2.NewButton("load plugin 'gocui'", func () {
|
||||
LoadPlugin("gocui")
|
||||
g2.NewButton("load toolkit 'gocui'", func () {
|
||||
Config.rootNode.LoadToolkit("gocui")
|
||||
})
|
||||
|
||||
return newN
|
||||
|
|
31
main.go
31
main.go
|
@ -40,7 +40,7 @@ func init() {
|
|||
Config.flag = Config.rootNode.newNode("flag", 0, nil)
|
||||
Config.flag.WidgetType = toolkit.Flag
|
||||
|
||||
Config.guiChan = make(chan toolkit.Action)
|
||||
Config.guiChan = make(chan toolkit.Action, 1)
|
||||
go watchCallback()
|
||||
}
|
||||
|
||||
|
@ -111,18 +111,12 @@ func (n *Node) doUserEvent(a toolkit.Action) {
|
|||
}
|
||||
}
|
||||
|
||||
func LoadPlugin(name string) bool {
|
||||
func (n *Node) LoadToolkit(name string) *Node {
|
||||
log(logInfo, "Start() Main(f) for name =", name)
|
||||
newPlugin := LoadToolkit(name)
|
||||
if (newPlugin == nil) {
|
||||
return false
|
||||
if (FindPlugin(name) == nil) {
|
||||
return n
|
||||
}
|
||||
|
||||
sleep(1) // temp hack until chan communication is setup
|
||||
|
||||
// TODO: find a new way to do this that is locking, safe and accurate
|
||||
Config.rootNode.redraw(newPlugin)
|
||||
return true
|
||||
return n
|
||||
}
|
||||
|
||||
// There should only be one of these per application
|
||||
|
@ -130,18 +124,22 @@ func LoadPlugin(name string) bool {
|
|||
// some toolkit's on some operating systems don't support more than one
|
||||
// Keep things simple. Do the default expected thing whenever possible
|
||||
func New() *Node {
|
||||
if (LoadPlugin("gocui")) {
|
||||
return Config.rootNode
|
||||
}
|
||||
|
||||
func (n *Node) Default() *Node {
|
||||
if (FindPlugin("gocui") == nil) {
|
||||
log(logError, "New() failed to load gocui")
|
||||
}
|
||||
// if DISPLAY isn't set, return since gtk can't load
|
||||
// TODO: figure out how to check what to do in macos and mswindows
|
||||
if (os.Getenv("DISPLAY") == "") {
|
||||
return Config.rootNode
|
||||
return n
|
||||
}
|
||||
if (LoadPlugin("andlabs")) {
|
||||
if (FindPlugin("andlabs") == nil) {
|
||||
log(logError, "New() failed to load andlabs")
|
||||
}
|
||||
return Config.rootNode
|
||||
return n
|
||||
}
|
||||
|
||||
// The window is destroyed but the application does not quit
|
||||
|
@ -157,9 +155,6 @@ func StandardExit() {
|
|||
log("StandardExit() attempt to exit each toolkit plugin")
|
||||
for i, aplug := range allPlugins {
|
||||
log("NewButton()", i, aplug)
|
||||
if (aplug.Quit != nil) {
|
||||
aplug.Quit()
|
||||
}
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
|
|
40
plugin.go
40
plugin.go
|
@ -21,10 +21,11 @@ type aplug struct {
|
|||
filename string
|
||||
plug *plugin.Plugin
|
||||
sym *plugin.Symbol
|
||||
LoadOk bool
|
||||
// LoadOk bool
|
||||
InitOk bool
|
||||
MainOk bool
|
||||
// MainOk bool
|
||||
|
||||
// startup whatever might need to be setup in the plugin
|
||||
Init func()
|
||||
|
||||
// This passes the go channel to the plugin
|
||||
|
@ -47,35 +48,30 @@ type aplug struct {
|
|||
// each toolkit has it's own goroutine and each one is sent this
|
||||
// add button request
|
||||
pluginChan chan toolkit.Action
|
||||
|
||||
PluginChannel func() chan toolkit.Action
|
||||
|
||||
// deprecate all this
|
||||
// TODO: make Main() main() and never allow the user to call it
|
||||
// run plugin.Main() when the plugin is loaded
|
||||
Main func(func ()) // this never returns. Each plugin must have it's own goroutine
|
||||
Quit func()
|
||||
|
||||
// simplifies passing to the plugin
|
||||
// Send func(*toolkit.Widget, *toolkit.Widget)
|
||||
// should replace Send()
|
||||
// Action func(*toolkit.Action)
|
||||
// Main func(func ()) // this never returns. Each plugin must have it's own goroutine
|
||||
// Quit func()
|
||||
}
|
||||
|
||||
var allPlugins []*aplug
|
||||
|
||||
// loads and initializes a toolkit (andlabs/ui, gocui, etc)
|
||||
func LoadToolkit(name string) *aplug {
|
||||
// attempts to locate the .so file
|
||||
func FindPlugin(name string) *aplug {
|
||||
var newPlug *aplug
|
||||
newPlug = new(aplug)
|
||||
|
||||
log(logInfo, "LoadToolkit() START")
|
||||
newPlug.LoadOk = false
|
||||
log(logInfo, "FindPlugin() START")
|
||||
newPlug.InitOk = false
|
||||
|
||||
for _, aplug := range allPlugins {
|
||||
log(debugGui, "LoadToolkit() already loaded toolkit plugin =", aplug.name)
|
||||
log(debugGui, "FindPlugin() already loaded toolkit plugin =", aplug.name)
|
||||
if (aplug.name == name) {
|
||||
log(debugError, "LoadToolkit() SKIPPING", name, "as you can't load it twice")
|
||||
log(debugError, "FindPlugin() SKIPPING", name, "as you can't load it twice")
|
||||
return aplug
|
||||
}
|
||||
}
|
||||
|
@ -94,13 +90,13 @@ func LoadToolkit(name string) *aplug {
|
|||
newPlug.Init = loadFuncE(newPlug, "Init")
|
||||
|
||||
// should make a goroutine that never exits
|
||||
newPlug.Main = loadFuncF(newPlug, "Main")
|
||||
// newPlug.Main = loadFuncF(newPlug, "Main")
|
||||
|
||||
// should send things to the goroutine above
|
||||
// newPlug.Queue = loadFuncF(&newPlug, "Queue")
|
||||
|
||||
// unload the plugin and restore state
|
||||
newPlug.Quit = loadFuncE(newPlug, "Quit")
|
||||
// newPlug.Quit = loadFuncE(newPlug, "Quit")
|
||||
|
||||
// Sends instructions like "Add", "Delete", "Disable", etc
|
||||
// Sends a widget (button, checkbox, etc) and it's parent widget
|
||||
|
@ -116,14 +112,20 @@ func LoadToolkit(name string) *aplug {
|
|||
|
||||
allPlugins = append(allPlugins, newPlug)
|
||||
|
||||
log(debugPlugin, "LoadToolkit() END", newPlug.name, filename)
|
||||
log(debugPlugin, "FindPlugin() END", newPlug.name, filename)
|
||||
newPlug.Init()
|
||||
|
||||
// set the communication to the plugins
|
||||
newPlug.pluginChan = newPlug.PluginChannel()
|
||||
newPlug.Callback(Config.guiChan)
|
||||
|
||||
newPlug.LoadOk = true
|
||||
newPlug.InitOk = true
|
||||
|
||||
sleep(1) // temp hack until chan communication is setup
|
||||
|
||||
// TODO: find a new way to do this that is locking, safe and accurate
|
||||
Config.rootNode.redraw(newPlug)
|
||||
|
||||
return newPlug
|
||||
}
|
||||
|
||||
|
|
|
@ -15,21 +15,21 @@ func actionDump(b bool, a *toolkit.Action) {
|
|||
log(b, "actionDump() ParentId =", a.ParentId)
|
||||
}
|
||||
|
||||
func add(a *toolkit.Action) {
|
||||
func add(a toolkit.Action) {
|
||||
if (andlabs[a.WidgetId] != nil) {
|
||||
log(debugError, "add() error. can't make a widget that already exists. id =", a.WidgetId)
|
||||
actionDump(debugError, a)
|
||||
actionDump(debugError, &a)
|
||||
return
|
||||
}
|
||||
if (a.WidgetId == 0) {
|
||||
log(debugError, "add() error. w.WidgetId == 0")
|
||||
actionDump(debugError, a)
|
||||
actionDump(debugError, &a)
|
||||
return
|
||||
}
|
||||
|
||||
// for now, window gets handled without checking where == nil)
|
||||
if (a.WidgetType == toolkit.Window) {
|
||||
newWindow(*a)
|
||||
newWindow(a)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -44,49 +44,49 @@ func add(a *toolkit.Action) {
|
|||
|
||||
switch a.WidgetType {
|
||||
case toolkit.Window:
|
||||
newWindow(*a)
|
||||
newWindow(a)
|
||||
return
|
||||
case toolkit.Tab:
|
||||
log(debugError, "add() CAME AT THIS FROM add() =", a.Name)
|
||||
log(debugError, "add() CAME AT THIS FROM add() =", a.Name)
|
||||
log(debugError, "add() CAME AT THIS FROM add() =", a.Name)
|
||||
newTab(*a)
|
||||
newTab(a)
|
||||
return
|
||||
case toolkit.Label:
|
||||
newLabel(a)
|
||||
newLabel(&a)
|
||||
return
|
||||
case toolkit.Button:
|
||||
newButton(a)
|
||||
newButton(&a)
|
||||
return
|
||||
case toolkit.Grid:
|
||||
newGrid(a)
|
||||
newGrid(&a)
|
||||
return
|
||||
case toolkit.Checkbox:
|
||||
newCheckbox(a)
|
||||
newCheckbox(&a)
|
||||
return
|
||||
case toolkit.Spinner:
|
||||
newSpinner(a)
|
||||
newSpinner(&a)
|
||||
return
|
||||
case toolkit.Slider:
|
||||
newSlider(a)
|
||||
newSlider(&a)
|
||||
return
|
||||
case toolkit.Dropdown:
|
||||
newDropdown(a)
|
||||
newDropdown(&a)
|
||||
return
|
||||
case toolkit.Combobox:
|
||||
newCombobox(a)
|
||||
newCombobox(&a)
|
||||
return
|
||||
case toolkit.Textbox:
|
||||
newTextbox(a)
|
||||
newTextbox(&a)
|
||||
return
|
||||
case toolkit.Group:
|
||||
newGroup(a)
|
||||
newGroup(&a)
|
||||
return
|
||||
case toolkit.Box:
|
||||
newBox(a)
|
||||
newBox(&a)
|
||||
return
|
||||
case toolkit.Image:
|
||||
newImage(a)
|
||||
newImage(&a)
|
||||
return
|
||||
default:
|
||||
log(debugError, "add() error TODO: ", a.WidgetType, a.Name)
|
||||
|
@ -122,13 +122,14 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
|
|||
|
||||
// add the structure to the array
|
||||
if (andlabs[a.WidgetId] == nil) {
|
||||
log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId)
|
||||
log(logInfo, "place() MAPPED", a.WidgetId, a.ParentId)
|
||||
andlabs[a.WidgetId] = newt
|
||||
newt.WidgetType = a.WidgetType
|
||||
} else {
|
||||
log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId)
|
||||
log(debugError, "THIS IS BAD")
|
||||
log(debugError, "place() DO WHAT?", a.WidgetId, a.ParentId)
|
||||
log(debugError, "place() THIS IS BAD")
|
||||
}
|
||||
log(logInfo, "place() DONE MAPPED", a.WidgetId, a.ParentId)
|
||||
|
||||
if (newt.uiControl == nil) {
|
||||
log(debugError, "place() ERROR uiControl == nil", a.ParentId)
|
||||
|
@ -141,12 +142,13 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
log(logInfo, "place() switch", where.WidgetType)
|
||||
switch where.WidgetType {
|
||||
case toolkit.Grid:
|
||||
log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y)
|
||||
log(debugGrid, "place() Grid try at Parent X,Y =", a.X, a.Y)
|
||||
newt.gridX = a.X
|
||||
newt.gridY = a.Y
|
||||
log(debugGrid, "add() Grid try at gridX,gridY", newt.gridX, newt.gridY)
|
||||
log(debugGrid, "place() Grid try at gridX,gridY", newt.gridX, newt.gridY)
|
||||
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
|
||||
t.uiGrid.Append(newt.uiControl,
|
||||
newt.gridY - 1, newt.gridX - 1, 1, 1,
|
||||
|
@ -155,7 +157,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
|
|||
case toolkit.Group:
|
||||
if (t.uiBox == nil) {
|
||||
t.uiGroup.SetChild(newt.uiControl)
|
||||
log(debugGrid, "add() hack Group to use this as the box?", a.Name, a.WidgetType)
|
||||
log(debugGrid, "place() hack Group to use this as the box?", a.Name, a.WidgetType)
|
||||
t.uiBox = newt.uiBox
|
||||
} else {
|
||||
t.uiBox.Append(newt.uiControl, stretchy)
|
||||
|
@ -166,6 +168,8 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
|
|||
t.boxC += 1
|
||||
return true
|
||||
case toolkit.Box:
|
||||
log(logInfo, "place() uiBox =", t.uiBox)
|
||||
log(logInfo, "place() uiControl =", newt.uiControl)
|
||||
t.uiBox.Append(newt.uiControl, stretchy)
|
||||
t.boxC += 1
|
||||
return true
|
||||
|
@ -173,7 +177,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
|
|||
t.uiWindow.SetChild(newt.uiControl)
|
||||
return true
|
||||
default:
|
||||
log(debugError, "add() how?", a.ParentId)
|
||||
log(debugError, "place() how?", a.ParentId)
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@ func newButton(a *toolkit.Action) {
|
|||
newt.uiButton = b
|
||||
newt.uiControl = b
|
||||
newt.wId = a.WidgetId
|
||||
// newt.tw = a.Widget
|
||||
newt.WidgetType = a.WidgetType
|
||||
newt.parent = t
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"embed"
|
||||
"git.wit.org/wit/gui/toolkit"
|
||||
|
||||
|
@ -16,14 +17,20 @@ var res embed.FS
|
|||
var pluginChan chan toolkit.Action
|
||||
|
||||
var uiMainUndef bool = true
|
||||
var uiMain sync.Once
|
||||
var muAction sync.Mutex
|
||||
|
||||
func catchActionChannel() {
|
||||
log(logNow, "catchActionChannel() START")
|
||||
for {
|
||||
log(logNow, "catchActionChannel() for loop")
|
||||
uiMain.Do(func() {
|
||||
go ui.Main(demoUI)
|
||||
})
|
||||
select {
|
||||
case a := <-pluginChan:
|
||||
log(logNow, "catchActionChannel() SELECT widget id =", a.WidgetId, a.Name)
|
||||
/*
|
||||
// go Action(a)
|
||||
if (uiMainUndef) {
|
||||
log(logError,"catchActionChannel() main() was not run yet")
|
||||
|
@ -34,7 +41,7 @@ func catchActionChannel() {
|
|||
log(logError,"catchActionChannel() ui.Main() START")
|
||||
log(logError,"catchActionChannel() ui.Main() START")
|
||||
sleep(1)
|
||||
go ui.Main(demoUI)
|
||||
// go ui.Main(demoUI)
|
||||
// go ui.Main( func() {
|
||||
// rawAction(a)
|
||||
// })
|
||||
|
@ -46,6 +53,12 @@ func catchActionChannel() {
|
|||
rawAction(a)
|
||||
log(logNow, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
||||
}
|
||||
*/
|
||||
log(logNow, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
|
||||
muAction.Lock()
|
||||
rawAction(a)
|
||||
muAction.Unlock()
|
||||
log(logNow, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +103,7 @@ func Init() {
|
|||
setDefaultBehavior(true)
|
||||
|
||||
andlabs = make(map[int]*andlabsT)
|
||||
pluginChan = make(chan toolkit.Action)
|
||||
pluginChan = make(chan toolkit.Action, 1)
|
||||
|
||||
log(logNow, "Init() start channel reciever")
|
||||
go catchActionChannel()
|
||||
|
|
|
@ -55,7 +55,7 @@ func rawAction(a toolkit.Action) {
|
|||
|
||||
switch a.ActionType {
|
||||
case toolkit.Add:
|
||||
add(&a)
|
||||
add(a)
|
||||
case toolkit.Show:
|
||||
a.B = true
|
||||
show(&a)
|
||||
|
|
|
@ -22,6 +22,7 @@ type andlabsT struct {
|
|||
|
||||
// tw *toolkit.Widget
|
||||
parent *andlabsT
|
||||
a toolkit.Action
|
||||
|
||||
uiControl ui.Control
|
||||
|
||||
|
|
|
@ -127,6 +127,7 @@ const (
|
|||
Append
|
||||
Move
|
||||
Dump
|
||||
Quit
|
||||
)
|
||||
|
||||
func (s WidgetType) String() string {
|
||||
|
|
|
@ -24,10 +24,10 @@ func Watchdog() {
|
|||
}
|
||||
}
|
||||
if (i == 2) {
|
||||
LoadPlugin("gocui")
|
||||
Config.rootNode.LoadToolkit("gocui")
|
||||
}
|
||||
// if (i == 3) {
|
||||
// LoadPlugin("andlabs")
|
||||
// Config.rootNode.LoadToolkit("andlabs")
|
||||
// }
|
||||
i += 1
|
||||
time.Sleep(watchtime * time.Second / 10)
|
||||
|
|
Loading…
Reference in New Issue