gocui: compiling and running again

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-04-08 15:34:36 -05:00
parent 462015470d
commit 11d3f20c4a
12 changed files with 87 additions and 163 deletions

View File

@ -127,14 +127,7 @@ Creates a window helpful for debugging this package
`func Indent(b bool, a ...interface{})`
### func [InitPlugins](/main.go#L64)
`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 [LoadPlugin](/main.go#L176)
### func [LoadPlugin](/main.go#L172)
`func LoadPlugin(name string) bool`
@ -144,12 +137,6 @@ and allow the 'go-arg' command line args to override the defaults
loads and initializes a toolkit (andlabs/ui, gocui, etc)
### func [Main](/main.go#L198)
`func Main(f func())`
This should not pass a function
### func [SetDebug](/debug.go#L28)
`func SetDebug(s bool)`
@ -162,7 +149,7 @@ This should not pass a function
`func ShowDebugValues()`
### func [StandardExit](/main.go#L251)
### func [StandardExit](/main.go#L261)
`func StandardExit()`
@ -203,61 +190,14 @@ 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](/common.go#L12)
#### func [New](/main.go#L190)
`func New() *Node`
#### func [NewWindow](/window.go#L13)
`func NewWindow() *Node`
This routine creates a blank window with a Title and size (W x H)
This routine can not have any arguements due to the nature of how
it can be passed via the 'andlabs/ui' queue which, because it is
cross platform, must pass UI changes into the OS threads (that is
my guess).
This example demonstrates how to create a NewWindow()
Interacting with a GUI in a cross platform fashion adds some
unusual problems. To obvuscate those, andlabs/ui starts a
goroutine that interacts with the native gui toolkits
on the Linux, MacOS, Windows, etc.
Because of this oddity, to initialize a new window, the
function is not passed any arguements and instead passes
the information via the Config type.
```golang
package main
import (
"git.wit.org/wit/gui"
)
func main() {
// Define the name and size
gui.Config.Title = "WIT GUI Window 1"
gui.Config.Width = 640
gui.Config.Height = 480
// Create the Window
gui.NewWindow()
}
```
Output:
```
You get a window
```
#### func [Start](/main.go#L100)
`func Start() *Node`
There should only be one of these per application
This is due to restrictions by being cross platform
some toolkit's on some operating systems don't support more than one
Keep things simple. Do the default expected thing whenever possible
### type [Symbol](/plugin.go#L16)

View File

@ -4,7 +4,6 @@ package main
import (
"fmt"
"log"
// "time"
"strconv"
"git.wit.org/wit/gui"
)
@ -18,11 +17,9 @@ var buttonCounter int = 5
func main() {
// This will turn on all debugging
// gui.SetDebug(true)
myGui = gui.Start()
// time.Sleep(1 * time.Second)
myGui = gui.New()
buttonWindow()
log.Println("Main() END")
// time.Sleep(1 * time.Second)
// This is just a optional goroutine to watch that things are alive
gui.Watchdog()
@ -33,11 +30,9 @@ func main() {
func buttonWindow() {
var w, t, g, more, more2 *gui.Node
log.Println("buttonWindow()")
log.Println("buttonWindow()")
log.Println("buttonWindow()")
log.Println("buttonWindow() START")
w = myGui.NewWindow2(title).SetText("Nueva Ventana de Botones")
w = myGui.NewWindow(title).SetText("Nueva Ventana de Botones")
t = w.NewTab("buttonTab")
g = t.NewGroup("buttonGroup")
g1 := t.NewGroup("buttonGroup 2")

View File

@ -9,18 +9,6 @@ import (
// functions for handling text related GUI elements
func New() *Node {
if (Config.rootNode == nil) {
log(logError, "New() ERROR: rootNode is nil")
}
// There should only be one of these per application
// This is due to restrictions by being cross platform
// some toolkit's on some operating systems don't support more than one
// Keep things simple. Do the default expected thing whenever possible
return startS("gocui")
}
func (n *Node) Show() *Node {
var a toolkit.Action
a.ActionType = toolkit.Show
@ -204,14 +192,9 @@ func (n *Node) Unpad() *Node {
// me.window = myGui.New2().Window("DNS and IPv6 Control Panel").Standard()
// myFunnyWindow = myGui.NewWindow("Hello").Standard().SetText("Hola")
func (n *Node) New2() *Node {
log(debugNow, "New2() Start")
return n.NewWindow2("New2")
}
func (n *Node) Window(title string) *Node {
log(debugError, "Window()", n)
return n.NewWindow2(title)
return n.NewWindow(title)
}
// This should not really do anything. as per the docs, the "Standard()" way

View File

@ -9,10 +9,7 @@ func (n *Node) DebugFlags(makeWindow bool) {
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "Debug Flags"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w = Config.rootNode.NewWindow("Debug Flags")
w.Custom = w.StandardClose
} else {
w = n.NewTab("Flags")

View File

@ -18,10 +18,7 @@ func (n *Node) DebugGoChannels(makeWindow bool) {
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "Debug GO Channels"
Config.Width = 300
Config.Height = 400
w = NewWindow()
w = Config.rootNode.NewWindow("Debug GO Channels")
w.Custom = w.StandardClose
} else {
w = n.NewTab("Chan")

View File

@ -16,10 +16,7 @@ func (n *Node) DebugGolangWindow(makeWindow bool) {
// make a new window
// make a new tab in the existing window
if (makeWindow) {
Config.Title = "GO"
Config.Width = 1280
Config.Height = 720
w = NewWindow()
w = Config.rootNode.NewWindow("GO")
w.Custom = w.StandardClose
} else {
w = n.NewTab("GOLANG")

View File

@ -60,10 +60,7 @@ func DebugWidgetWindow(w *Node) {
// make a new window
// make a new tab in the existing window
if (makeTabs) {
Config.Title = "Widgets"
Config.Width = 300
Config.Height = 400
bugWidget = NewWindow()
bugWidget = Config.rootNode.NewWindow("Widgets")
bugWidget.Custom = bugWidget.StandardClose
} else {
bugWidget = bugWin.NewTab("Widgets")

View File

@ -19,12 +19,9 @@ var myButton *Node
Creates a window helpful for debugging this package
*/
func DebugWindow() {
Config.Title = "go.wit.org/gui debug window"
Config.Width = 300
Config.Height = 200
bugWin = NewWindow()
bugWin = Config.rootNode.NewWindow("go.wit.org/gui debug window").DebugTab("Debug Tab")
bugWin.Custom = bugWin.StandardClose
bugWin.DebugTab("Debug Tab")
// bugWin.DebugTab("Debug Tab")
}
func (n *Node) DebugTab(title string) *Node {
@ -94,7 +91,7 @@ func (n *Node) DebugTab(title string) *Node {
})
g2.NewButton("load plugin 'gocui'", func () {
startS("gocui")
LoadPlugin("gocui")
})
return newN

52
main.go
View File

@ -2,10 +2,11 @@ package gui
import (
"os"
// "embed"
// "embed" // reminder to not attempt this within the 'wit/gui' package
"git.wit.org/wit/gui/toolkit"
)
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
// Windows doesn't support plugins. How can I keep andlabs and only compile it on windows?
// https://forum.heroiclabs.com/t/setting-up-goland-to-compile-plugins-on-windows/594/5
// import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
@ -43,6 +44,7 @@ func init() {
go watchCallback()
}
/*
func doGuiChan() {
for {
select {
@ -58,7 +60,9 @@ func doGuiChan() {
log(true, "doGuiChan() for()")
}
}
*/
/*
// 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 {
@ -96,15 +100,7 @@ func InitPlugins(names []string) []string {
}
return []string{}
}
func Start() *Node {
log(logInfo, "Start() Main(f)")
f := func() {
}
go Main(f)
sleep(1)
return Config.rootNode
}
*/
func watchCallback() {
log(logInfo, "watchCallback() START")
@ -174,26 +170,39 @@ func (n *Node) doUserEvent(a toolkit.Action) {
}
func LoadPlugin(name string) bool {
startS(name)
log(logInfo, "Start() Main(f) for name =", name)
newPlugin := LoadToolkit(name)
if (newPlugin == nil) {
return false
}
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
}
func startS(name string) *Node {
log(logInfo, "Start() Main(f) for name =", name)
aplug := LoadToolkit(name)
if (aplug == nil) {
// There should only be one of these per application
// This is due to restrictions by being cross platform
// 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")) {
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
}
/*
// will this really work on mswindows & macos?
f := func() {
if (LoadPlugin("andlabs")) {
log(logError, "New() failed to load andlabs")
}
go Main(f)
*/
sleep(1) // temp hack until chan communication is setup
return Config.rootNode
}
/*
// This should not pass a function
func Main(f func()) {
log(debugGui, "Starting gui.Main() (using gtk via andlabs/ui)")
@ -239,6 +248,7 @@ func Main(f func()) {
}
}
*/
// The window is destroyed but the application does not quit
func (n *Node) StandardClose() {

View File

@ -118,10 +118,11 @@ func LoadToolkit(name string) *aplug {
log(debugPlugin, "LoadToolkit() END", newPlug.name, filename)
newPlug.Init()
newPlug.pluginChan = newPlug.PluginChannel()
// TODO: find a new way to do this that is locking, safe and accurate
Config.rootNode.redraw(newPlug)
// set the communication to the plugins
newPlug.pluginChan = newPlug.PluginChannel()
newPlug.Callback(Config.guiChan)
newPlug.LoadOk = true
return newPlug
}

View File

@ -50,6 +50,15 @@ func catchActionChannel() {
log(logInfo, "catchActionChannel() infinite for() loop restarted select on channel")
select {
case a := <-me.pluginChan:
// this plugin can be loaded, but it doesn't actually do anything until
// the calling program sends an action to it. Then, it actually will initialize
// the tty and take over your console
if (me.baseGui == nil) {
log(logError,"main() was not run yet")
go main()
// probably not needed, but in here for now under development
sleep(1)
}
log(logNow, "catchActionChannel()", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
action(&a)
}
@ -61,8 +70,8 @@ func Exit() {
me.baseGui.Close()
}
func Main(f func()) {
log("start Init()")
func main() {
log(logInfo, "main() start Init()")
outf, err := os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {

View File

@ -6,6 +6,27 @@ import (
// This routine creates a blank window with a Title and size (W x H)
//
func (n *Node) NewWindow(title string) *Node {
var newNode *Node
// Windows are created off of the master node of the Binary Tree
newNode = n.newNode(Config.Title, toolkit.Window, StandardExit)
log(logInfo, "NewWindow()", Config.Title)
var a toolkit.Action
a.ActionType = toolkit.Add
a.Width = Config.Width
a.Height = Config.Height
a.Name = title
a.Text = title
newaction(&a, newNode, n)
return newNode
}
/*
// This routine can not have any arguements due to the nature of how
// it can be passed via the 'andlabs/ui' queue which, because it is
// cross platform, must pass UI changes into the OS threads (that is
@ -46,24 +67,4 @@ func NewWindow() *Node {
return newNode
}
// This routine creates a blank window with a Title
//
func (n *Node) NewWindow2(title string) *Node {
var newNode *Node
// Windows are created off of the master node of the Binary Tree
newNode = n.newNode(Config.Title, toolkit.Window, StandardExit)
log(logInfo, "NewWindow()", Config.Title)
var a toolkit.Action
a.ActionType = toolkit.Add
a.Width = Config.Width
a.Height = Config.Height
a.Name = title
a.Text = title
newaction(&a, newNode, n)
return newNode
}
*/