open gocui when DISPLAY=""

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-04-07 09:18:03 -05:00
parent 5ba335ddee
commit 8f6e971948
9 changed files with 96 additions and 60 deletions

View File

@ -127,13 +127,16 @@ Creates a window helpful for debugging this package
`func Indent(b bool, a ...interface{})` `func Indent(b bool, a ...interface{})`
### func [InitPlugins](/main.go#L58) ### func [InitPlugins](/main.go#L61)
`func InitPlugins(names []string)` `func InitPlugins(names []string) []string`
TODO: add logic to just load the 1st 'most common' gui toolkit
and allow the 'go-arg' command line args to override the defaults
### func [LoadToolkit](/plugin.go#L50) ### func [LoadToolkit](/plugin.go#L50)
`func LoadToolkit(name string) bool` `func LoadToolkit(name string) *aplug`
loads and initializes a toolkit (andlabs/ui, gocui, etc) loads and initializes a toolkit (andlabs/ui, gocui, etc)
@ -159,7 +162,7 @@ This should not pass a function
`func ShowDebugValues()` `func ShowDebugValues()`
### func [StandardExit](/main.go#L255) ### func [StandardExit](/main.go#L262)
`func StandardExit()` `func StandardExit()`
@ -248,11 +251,11 @@ func main() {
You get a window You get a window
``` ```
#### func [Start](/main.go#L98) #### func [Start](/main.go#L97)
`func Start() *Node` `func Start() *Node`
#### func [StartS](/main.go#L180) #### func [StartS](/main.go#L178)
`func StartS(name string) *Node` `func StartS(name string) *Node`

View File

@ -11,6 +11,7 @@ import (
var title string = "Demo Plugin Window" var title string = "Demo Plugin Window"
var outfile string = "/tmp/guilogfile" var outfile string = "/tmp/guilogfile"
var myGui *gui.Node
var buttonCounter int = 5 var buttonCounter int = 5
@ -27,25 +28,13 @@ func main() {
// gui.Init() // gui.Init()
// buttonWindow() // buttonWindow()
go gui.Main(func () { myGui = gui.Start()
log.Println("START Main f()") time.Sleep(1 * time.Second)
buttonWindow() buttonWindow()
/*
log.Println("END NewWindow()")
log.Println("START NewGroup()")
g := w.NewGroup("new Group 22")
log.Println("END NewGroup()")
g.NewButton("asdjkl", func () {
log.Println("world")
})
*/
log.Println("END Main f()")
// gui.StandardExit(nil)
})
log.Println("Main() END") log.Println("Main() END")
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
gui.StartS("gocui") // gui.StartS("gocui")
gui.Redraw("gocui") // gui.Redraw("gocui")
gui.Watchdog() gui.Watchdog()
gui.StandardExit() gui.StandardExit()
} }
@ -84,6 +73,10 @@ func buttonWindow() {
gui.Redraw("gocui") gui.Redraw("gocui")
}) })
g.NewButton("Load 'andlabs'", func () {
gui.StartS("andlabs")
})
g.NewButton("NewButton(more)", func () { 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(buttonCounter) name := "foobar " + strconv.Itoa(buttonCounter)

47
main.go
View File

@ -1,6 +1,7 @@
package gui package gui
import ( import (
"os"
// "embed" // "embed"
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
) )
@ -55,44 +56,42 @@ func doGuiChan() {
} }
} }
func InitPlugins(names []string) { // TODO: add logic to just load the 1st 'most common' gui toolkit
// and allow the 'go-arg' command line args to override the defaults
func InitPlugins(names []string) []string {
log(debugGui, "Starting gui.Init()") log(debugGui, "Starting gui.Init()")
for _, aplug := range allPlugins { for _, aplug := range allPlugins {
log(debugGui, "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 []string{name}
} }
} }
} }
// try to load each plugin in the order passed to this function // try to load each plugin in the order passed to this function
for _, name := range names { for _, name := range names {
if (LoadToolkit(name)) { aPlug := LoadToolkit(name)
// aplug.InitOk = true if (aPlug != nil) {
// aplug.Init() // exit because it worked!
return return []string{name}
} }
} }
// the program didn't specify a plugin. Try to load one // the program didn't specify a plugin. Try to load one
// TODO: detect the OS & user preferences to load the best one // TODO: detect the OS & user preferences to load the best one
// TODO: commented out Init() on 02/26/2023 because I'm not sure how to run it correctly // TODO: commented out Init() on 02/26/2023 because I'm not sure how to run it correctly
if (LoadToolkit("andlabs")) { andlabsPlug := LoadToolkit("andlabs")
// aplug.InitOk = true if (andlabsPlug != nil) {
// aplug.Init() return []string{}
return
} }
if (LoadToolkit("gocui")) { gocuiPlug := LoadToolkit("andlabs")
// aplug.InitOk = true if (gocuiPlug != nil) {
// aplug.Init() return []string{}
return
} }
return []string{}
// Should die here? TODO: need a Node to call StandardExit
// StandardExit("golang wit/gui could not load a plugin TODO: do something to STDOUT (?)")
} }
func Start() *Node { func Start() *Node {
@ -173,13 +172,13 @@ func (n *Node) doUserEvent(a toolkit.Action) {
func (n *Node) LoadPlugin(name string) bool { func (n *Node) LoadPlugin(name string) bool {
StartS(name) StartS(name)
Redraw(name)
return true return true
} }
func StartS(name string) *Node { func StartS(name string) *Node {
log(logInfo, "Start() Main(f) for name =", name) log(logInfo, "Start() Main(f) for name =", name)
if (LoadToolkit(name) == false) { aplug := LoadToolkit(name)
if (aplug == nil) {
return Config.rootNode return Config.rootNode
} }
// will this really work on mswindows & macos? // will this really work on mswindows & macos?
@ -187,6 +186,7 @@ func StartS(name string) *Node {
} }
go Main(f) go Main(f)
sleep(1) // temp hack until chan communication is setup sleep(1) // temp hack until chan communication is setup
Config.rootNode.Redraw(aplug)
return Config.rootNode return Config.rootNode
} }
@ -194,7 +194,14 @@ func StartS(name string) *Node {
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)")
InitPlugins([]string{"andlabs", "gocui"}) // TODO: this is linux only
// TODO: detect if this was run from the command line (parent == bash?)
// if DISPLAY is not set, don't even bother with loading andlabs
if (os.Getenv("DISPLAY") == "") {
InitPlugins([]string{"gocui"})
} else {
InitPlugins([]string{"andlabs", "gocui"})
}
if (Config.guiChan == nil) { if (Config.guiChan == nil) {
Config.guiChan = make(chan toolkit.Action) Config.guiChan = make(chan toolkit.Action)

View File

@ -47,8 +47,9 @@ type aplug struct {
var allPlugins []*aplug var allPlugins []*aplug
// loads and initializes a toolkit (andlabs/ui, gocui, etc) // loads and initializes a toolkit (andlabs/ui, gocui, etc)
func LoadToolkit(name string) bool { func LoadToolkit(name string) *aplug {
var newPlug aplug var newPlug *aplug
newPlug = new(aplug)
log(debugGui, "gui.LoadToolkit() START") log(debugGui, "gui.LoadToolkit() START")
newPlug.LoadOk = false newPlug.LoadOk = false
@ -57,44 +58,45 @@ func LoadToolkit(name string) bool {
log(debugGui, "gui.LoadToolkit() already loaded toolkit plugin =", aplug.name) log(debugGui, "gui.LoadToolkit() already loaded toolkit plugin =", aplug.name)
if (aplug.name == name) { if (aplug.name == name) {
log(debugGui, "gui.LoadToolkit() SKIPPING") log(debugGui, "gui.LoadToolkit() SKIPPING")
return true return aplug
} }
} }
// locate the shared library file // locate the shared library file
filename := name + ".so" filename := name + ".so"
loadPlugin(&newPlug, filename) loadPlugin(newPlug, filename)
if (newPlug.plug == nil) { if (newPlug.plug == nil) {
log(true, "attempt to find plugin", filename, "failed") log(true, "attempt to find plugin", filename, "failed")
return false return nil
} }
// newPlug.Ok = true // newPlug.Ok = true
newPlug.name = name newPlug.name = name
// deprecate Init(?) // deprecate Init(?)
newPlug.Init = loadFuncE(&newPlug, "Init") newPlug.Init = loadFuncE(newPlug, "Init")
// should make a goroutine that never exits // should make a goroutine that never exits
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 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")
newPlug.Callback = loadCallback(&newPlug, "Callback") 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)
newPlug.Init() newPlug.Init()
Config.rootNode.Redraw(newPlug)
newPlug.LoadOk = true newPlug.LoadOk = true
return true return newPlug
} }
// TODO: All these functions need to be done a smarter way // TODO: All these functions need to be done a smarter way

View File

@ -38,9 +38,10 @@ func helplayout(g *gocui.Gui) error {
fmt.Fprintln(help, "d: show/hide debugging") fmt.Fprintln(help, "d: show/hide debugging")
fmt.Fprintln(help, "h: hide widgets") fmt.Fprintln(help, "h: hide widgets")
fmt.Fprintln(help, "s: show all widgets") fmt.Fprintln(help, "s: show all widgets")
fmt.Fprintln(help, "q: quit()")
fmt.Fprintln(help, "p: panic()") fmt.Fprintln(help, "p: panic()")
fmt.Fprintln(help, "STDOUT: /tmp/witgui.log") fmt.Fprintln(help, "STDOUT: /tmp/witgui.log")
fmt.Fprintln(help, "Ctrl-C or Q: Exit") // fmt.Fprintln(help, "Ctrl-C: Exit") // TODO: fix ctrl-c handling
if _, err := g.SetCurrentView("help"); err != nil { if _, err := g.SetCurrentView("help"); err != nil {
return err return err
} }

View File

@ -70,9 +70,24 @@ func addDebugKeys(g *gocui.Gui) {
return nil return nil
}) })
// exit
g.SetKeybinding("", 'q', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.baseGui.Close()
exit("forced exit() from within gocui")
return nil
})
g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.baseGui.Close()
exit("forced exit() from within gocui")
return nil
})
// panic // panic
g.SetKeybinding("", 'p', gocui.ModNone, g.SetKeybinding("", 'p', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error { func(g *gocui.Gui, v *gocui.View) error {
me.baseGui.Close()
panic("forced panic in gocui") panic("forced panic in gocui")
return nil return nil
}) })

View File

@ -34,7 +34,7 @@ func Callback(guiCallback chan toolkit.Action) {
} }
func Exit() { func Exit() {
// TODO: exit correctly // TODO: send exit to the plugin
me.baseGui.Close() me.baseGui.Close()
} }
@ -51,4 +51,5 @@ func Main(f func()) {
log("This is a test log entry") log("This is a test log entry")
MouseMain() MouseMain()
me.baseGui.Close()
} }

View File

@ -15,8 +15,15 @@ func Action(a *toolkit.Action) {
w := findWidget(a.WidgetId, me.rootNode) w := findWidget(a.WidgetId, me.rootNode)
switch a.ActionType { switch a.ActionType {
case toolkit.Add: case toolkit.Add:
w = makeWidget(a) if (w == nil) {
w.addWidget() w = makeWidget(a)
w.addWidget()
} else {
// this is done to protect the plugin being 'refreshed' with the
// widget binary tree. TODO: find a way to keep them in sync
log(logError, "Action() Add ignored for already defined widget",
a.WidgetId, a.ActionType, a.WidgetType, a.Name)
}
case toolkit.Show: case toolkit.Show:
if (a.B) { if (a.B) {
w.drawView() w.drawView()

View File

@ -15,7 +15,14 @@ var watchtime time.Duration = 100 // in tenths of seconds
func Watchdog() { func Watchdog() {
var i = 1 var i = 1
for { for {
log(logInfo, "watchdog timer is alive. give me something to do.", i) log(logNow, "watchdog timer is alive. give me something to do.", i)
if (Config.rootNode == nil) {
log(logInfo, "Config.rootNode == nil", i)
} else {
if (logVerbose) {
Config.rootNode.ListChildren(true)
}
}
i += 1 i += 1
time.Sleep(watchtime * time.Second / 10) time.Sleep(watchtime * time.Second / 10)
} }