new-gui/main.go

194 lines
5.0 KiB
Go

package gui
import (
"os"
"go.wit.com/log"
"go.wit.com/gui/widget"
)
// 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 "go.wit.com/gui/toolkit/andlabs"
const Xaxis = 0 // stack things horizontally
const Yaxis = 1 // stack things vertically
func init() {
log.Log(NOW, "init() has been run")
me.counter = 0
// me.prefix = "wit"
// Populates the top of the binary tree
me.rootNode = addNode()
me.rootNode.progname = "guiBinaryTree"
me.rootNode.WidgetType = widget.Root
me.rootNode.hidden = false // always send the rootNode to the toolkits
// used to pass debugging flags to the toolkit plugins
me.flag = me.rootNode.newNode("flag", 0)
me.flag.WidgetType = widget.Flag
me.flag = me.rootNode.newNode("stdout", 0)
me.flag.WidgetType = widget.Stdout
me.guiChan = make(chan widget.Action, 1)
go watchCallback()
}
// lookup the widget by the id sent from the toolkit
func (n *Node) findId(i int) (*Node) {
if (n == nil) {
return nil
}
if (n.id == i) {
return n
}
for _, child := range n.children {
newN := child.findId(i)
if (newN != nil) {
return newN
}
}
return nil
}
func watchCallback() {
log.Info("guiChan() START")
for {
log.Info("guiChan() restarted")
select {
case a := <-me.guiChan:
if (a.ActionType == widget.UserQuit) {
log.Warn("guiChan() User sent Quit()")
me.rootNode.doCustom()
log.Exit("wit/gui toolkit.UserQuit")
break
}
if (a.ActionType == widget.EnableDebug) {
log.Warn("guiChan() Enable Debugging Window")
log.Warn("guiChan() TODO: not implemented")
// DebugWindow()
break
}
n := me.rootNode.findId(a.WidgetId)
if (n == nil) {
log.Warn("guiChan() UNKNOWN widget id")
log.Warn("id =", a.WidgetId, a.ProgName)
} else {
log.Verbose("guiChan() FOUND widget id =", n.id, n.progname)
n.doUserEvent(a)
}
// this maybe a good idea?
// TODO: Throttle user events somehow
// sleep(.01) // hack that throttles user events
}
}
}
func (n *Node) doCustom() {
log.Info("doUserEvent() widget =", n.id, n.progname, n.WidgetType)
if (n.Custom == nil) {
log.Warn("Custom() = nil. SKIPPING")
return
}
go n.Custom()
}
func (n *Node) doUserEvent(a widget.Action) {
log.Info("doUserEvent() node =", n.id, n.progname)
if a.Value == nil {
log.Warn("doUserEvent() a.A == nil", n.id, n.progname)
return
}
n.value = a.Value
n.doCustom()
return
/*
switch n.WidgetType {
case widget.Checkbox:
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.value)
n.doCustom()
case widget.Button:
log.Info("doUserEvent() node =", n.id, n.progname, "button clicked")
n.doCustom()
case widget.Combobox:
n.S = a.S
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S)
n.doCustom()
case widget.Dropdown:
n.S = a.S
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S)
n.doCustom()
case widget.Textbox:
n.S = a.S
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.S)
n.doCustom()
case widget.Spinner:
n.I = a.I
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I)
n.doCustom()
case widget.Slider:
n.I = a.I
log.Info("doUserEvent() node =", n.id, n.progname, "set to:", n.I)
n.doCustom()
case widget.Window:
log.Info("doUserEvent() node =", n.id, n.progname, "window closed")
n.doCustom()
default:
log.Info("doUserEvent() type =", n.WidgetType)
}
*/
}
// 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 {
return me.rootNode
}
// try to load andlabs, if that doesn't work, fall back to the console
func (n *Node) Default() *Node {
if (argGui.GuiPlugin != "") {
log.Warn("New.Default() try toolkit =", argGui.GuiPlugin)
return n.LoadToolkit(argGui.GuiPlugin)
}
// 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") == "") {
if (n.LoadToolkit("gocui") == nil) {
log.Warn("New() failed to load gocui")
}
return n
}
if (n.LoadToolkit("andlabs") != nil) {
return n
}
n.LoadToolkit("gocui")
return n
}
// The window is destroyed but the application does not quit
func (n *Node) StandardClose() {
log.Log(GUI, "wit/gui Standard Window Close. name =", n.progname)
log.Log(GUI, "wit/gui Standard Window Close. n.Custom exit =", n.Custom)
}
// The window is destroyed and the application exits
// TODO: properly exit the plugin since Quit() doesn't do it
func StandardExit() {
log.Log(NOW, "wit/gui Standard Window Exit. running os.Exit()")
log.Log(NOW, "StandardExit() attempt to exit each toolkit plugin")
for i, plug := range allPlugins {
log.Log(NOW, "NewButton()", i, plug)
}
log.Exit(0)
}