Implement a early AddButton() via a golang plugin
pass a name to gocui.AddButton() cleaner plugin usage add the start to golang plugin plugin stuff in a single file added a button correctly andlabs/ui added a button via plugin to gocli hot diggity! trying to invoke a gocli plugin function from the andlabs ui load the plugin hide more debugging output turn off all output Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
482c3ef8eb
commit
c43a684857
|
@ -1,5 +1,5 @@
|
|||
run: build
|
||||
./buttonAsPlugin
|
||||
./buttonAsPlugin >/tmp/buttonAsPlugin.log 2>&1
|
||||
|
||||
build-release:
|
||||
go get -v -u -x .
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
// This creates a simple hello world window
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
"io"
|
||||
"time"
|
||||
"bufio"
|
||||
arg "github.com/alexflint/go-arg"
|
||||
)
|
||||
|
||||
|
||||
var args struct {
|
||||
Foo string
|
||||
Bar bool
|
||||
User string `arg:"env:USER"`
|
||||
Demo bool `help:"run a demo"`
|
||||
}
|
||||
|
||||
var f1 *os.File
|
||||
var f2 *os.File
|
||||
var err error
|
||||
|
||||
func init() {
|
||||
arg.MustParse(&args)
|
||||
fmt.Println(args.Foo, args.Bar, args.User)
|
||||
|
||||
f1, err = os.OpenFile("/tmp/guilogfile", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
log.Fatalf("error opening file: %v", err)
|
||||
}
|
||||
// hmm. is there a trick here or must this be in main()
|
||||
// defer f.Close()
|
||||
|
||||
log.SetOutput(f1)
|
||||
log.Println("This is a test log entry")
|
||||
}
|
||||
|
||||
func captureSTDOUT() {
|
||||
f2, _ = os.OpenFile("/tmp/my.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
|
||||
multiWriter := io.MultiWriter(os.Stderr, f2)
|
||||
rd, wr, err := os.Pipe()
|
||||
if err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// overwrite os.Stdout
|
||||
os.Stderr = wr
|
||||
|
||||
go func() {
|
||||
scanner := bufio.NewScanner(rd)
|
||||
for scanner.Scan() {
|
||||
stdoutLine := scanner.Text()
|
||||
multiWriter.Write([]byte(stdoutLine + "\n"))
|
||||
}
|
||||
}()
|
||||
|
||||
fmt.Println("foobar")
|
||||
|
||||
// hacky sleep to ensure the go routine can write before program exits
|
||||
time.Sleep(time.Second)
|
||||
}
|
|
@ -7,6 +7,12 @@ import (
|
|||
)
|
||||
|
||||
func main() {
|
||||
// go loadPlugin(plugHello, "../../toolkit/hello.so")
|
||||
|
||||
// this doesn't seem to work
|
||||
captureSTDOUT()
|
||||
|
||||
// go loadPlugin("../../toolkit/gocli.so")
|
||||
gui.Main(buttonWindow)
|
||||
}
|
||||
|
||||
|
@ -17,9 +23,6 @@ func buttonWindow() {
|
|||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
|
||||
// gui.Config.Exit = gui.StandardClose
|
||||
// gui.SetDebug(true)
|
||||
|
||||
w = gui.NewWindow()
|
||||
g = w.NewGroup("buttonGroup")
|
||||
|
||||
|
@ -27,7 +30,25 @@ func buttonWindow() {
|
|||
log.Println("world")
|
||||
})
|
||||
|
||||
g.NewButton("foo", func () {
|
||||
log.Println("bar")
|
||||
/*
|
||||
g.NewButton("LoadPlugin()", func () {
|
||||
log.Println("world")
|
||||
gui.LoadPlugin("../../toolkit/gocli.so")
|
||||
})
|
||||
*/
|
||||
|
||||
g.NewButton("RunGreet()", func () {
|
||||
log.Println("world")
|
||||
go gui.RunGreet()
|
||||
})
|
||||
|
||||
g.NewButton("gui.LookupJcarrButton()", func () {
|
||||
log.Println("gui.LookupJcarrButton()")
|
||||
gui.LookupJcarrButton()
|
||||
})
|
||||
|
||||
g.NewButton("gui.GocuiAddButton()", func () {
|
||||
log.Println("gui.GocuiAddButton()")
|
||||
gui.GocuiAddButton("new foobar")
|
||||
})
|
||||
}
|
||||
|
|
5
group.go
5
group.go
|
@ -9,7 +9,10 @@ import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|||
func (n *Node) NewGroup(name string) *Node {
|
||||
var newT *toolkit.Toolkit
|
||||
var gNode *Node
|
||||
log.Println("toolkit.NewGroup() START", name)
|
||||
|
||||
if (GetDebug()) {
|
||||
log.Println("toolkit.NewGroup() START", name)
|
||||
}
|
||||
|
||||
if (n.toolkit == nil) {
|
||||
log.Println("toolkit.NewGroup() toolkit == nil")
|
||||
|
|
7
main.go
7
main.go
|
@ -29,10 +29,15 @@ func init() {
|
|||
if (Config.Options.Debug) {
|
||||
Config.master.Dump()
|
||||
}
|
||||
|
||||
// load the gocli plugin
|
||||
PlugGocli = LoadPlugin("../../toolkit/gocli.so")
|
||||
}
|
||||
|
||||
func Main(f func()) {
|
||||
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||
if (Config.Options.Debug) {
|
||||
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||
}
|
||||
toolkit.Main(f)
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
package gui
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"plugin"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type Greeter interface {
|
||||
Greet()
|
||||
JcarrButton()
|
||||
AddButton(string)
|
||||
}
|
||||
|
||||
var PlugGocli *plugin.Plugin
|
||||
var PlugHello *plugin.Plugin
|
||||
|
||||
// var gBut plugin.Symbol
|
||||
var jcarrBut plugin.Symbol
|
||||
var symGreeter plugin.Symbol
|
||||
var greeter Greeter
|
||||
var ok bool
|
||||
|
||||
func LoadPlugin(name string) *plugin.Plugin {
|
||||
scs := spew.ConfigState{MaxDepth: 1}
|
||||
|
||||
// load module
|
||||
// 1. open the so file to load the symbols
|
||||
plug, err := plugin.Open(name)
|
||||
log.Println("plug =")
|
||||
log.Println(scs.Sdump(plug))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
PlugGocli = plug
|
||||
|
||||
// 2. look up a symbol (an exported function or variable)
|
||||
// in this case, variable Greeter
|
||||
symGreeter, err = plug.Lookup("Greeter")
|
||||
log.Println("symGreater", symGreeter)
|
||||
log.Println(scs.Sdump(symGreeter))
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 3. Assert that loaded symbol is of a desired type
|
||||
// in this case interface type Greeter (defined above)
|
||||
// var greeter Greeter
|
||||
greeter, ok = symGreeter.(Greeter)
|
||||
log.Println("greeter", symGreeter)
|
||||
log.Println(scs.Sdump(greeter))
|
||||
if !ok {
|
||||
log.Println("unexpected type from module symbol")
|
||||
os.Exit(1)
|
||||
}
|
||||
return plug
|
||||
}
|
||||
|
||||
func RunGreet() {
|
||||
log.Println("gui.RunGreet() START")
|
||||
if (greeter == nil) {
|
||||
log.Println("wit/gui gocui plugin didn't load")
|
||||
return
|
||||
}
|
||||
greeter.Greet()
|
||||
}
|
||||
|
||||
func LookupJcarrButton() {
|
||||
log.Println("lookupJcarrButton() START")
|
||||
|
||||
if (greeter == nil) {
|
||||
log.Println("wit/gui gocui plugin didn't load")
|
||||
return
|
||||
}
|
||||
greeter.JcarrButton()
|
||||
}
|
||||
|
||||
func GocuiAddButton(name string) {
|
||||
log.Println("GocuiAddButton() START", name)
|
||||
|
||||
if (greeter == nil) {
|
||||
log.Println("wit/gui gocui plugin didn't load")
|
||||
return
|
||||
}
|
||||
greeter.AddButton(name)
|
||||
}
|
|
@ -46,13 +46,13 @@ func ShowDebugValues() {
|
|||
log.Println("\t wit/gui DebugDump =", Config.Options.DebugDump)
|
||||
log.Println("\t wit/gui DebugNode =", Config.Options.DebugNode)
|
||||
log.Println("\t wit/gui DebugTabs =", Config.Options.DebugTabs)
|
||||
// log.Println("\t wit/gui DebugTable =", Config.Options.DebugTable)
|
||||
// log.Println("\t wit/gui DebugWindow =", Config.Options.DebugWindow)
|
||||
log.Println("\t wit/gui DebugPlugin =", Config.Options.DebugPlugin)
|
||||
log.Println("\t wit/gui DebugChange =", Config.Options.DebugChange)
|
||||
|
||||
log.Println("\t wit/gui DebugToolkit =", toolkit.DebugToolkit)
|
||||
}
|
||||
|
||||
// This struct can be used with go-arg
|
||||
type GuiOptions struct {
|
||||
// These are global debugging settings
|
||||
// TODO: move to a standard logging system
|
||||
|
@ -60,8 +60,7 @@ type GuiOptions struct {
|
|||
DebugDump bool
|
||||
DebugNode bool
|
||||
DebugTabs bool
|
||||
// DebugTable bool
|
||||
// DebugWindow bool
|
||||
DebugPlugin bool
|
||||
DebugChange bool `help:"debug mouse clicks and keyboard input"`
|
||||
}
|
||||
|
||||
|
|
|
@ -12,10 +12,14 @@ func (t *Toolkit) GetBox() *ui.Box {
|
|||
|
||||
// create a new box
|
||||
func (t *Toolkit) NewBox() *Toolkit {
|
||||
log.Println("gui.Toolbox.NewBox() START create default")
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolbox.NewBox() START create default")
|
||||
}
|
||||
t.Dump()
|
||||
if (t.uiGroup != nil) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Group")
|
||||
if (DebugToolkit) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Group")
|
||||
}
|
||||
var newTK Toolkit
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
|
@ -26,7 +30,9 @@ func (t *Toolkit) NewBox() *Toolkit {
|
|||
return &newTK
|
||||
}
|
||||
if (t.uiBox != nil) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Box")
|
||||
if (DebugToolkit) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Box")
|
||||
}
|
||||
var newTK Toolkit
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
|
@ -38,7 +44,9 @@ func (t *Toolkit) NewBox() *Toolkit {
|
|||
return &newTK
|
||||
}
|
||||
if (t.uiWindow != nil) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Window")
|
||||
if (DebugToolkit) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Window")
|
||||
}
|
||||
var newT Toolkit
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
|
@ -50,7 +58,9 @@ func (t *Toolkit) NewBox() *Toolkit {
|
|||
// panic("WTF")
|
||||
return &newT
|
||||
}
|
||||
log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box")
|
||||
if (DebugToolkit) {
|
||||
log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box")
|
||||
}
|
||||
t.Dump()
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ package toolkit
|
|||
import "log"
|
||||
|
||||
func init() {
|
||||
log.Println("gui/toolkit init() Setting defaultBehavior = true")
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui/toolkit init() Setting defaultBehavior = true")
|
||||
}
|
||||
setDefaultBehavior(true)
|
||||
}
|
||||
|
||||
|
@ -37,7 +39,9 @@ func (t Toolkit) commonChange(widget string) {
|
|||
func (t *Toolkit) broken() bool {
|
||||
if (t.uiBox == nil) {
|
||||
if (t.uiWindow != nil) {
|
||||
log.Println("gui.Toolkit.UiBox == nil. This is an empty window. Try to add a box")
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolkit.UiBox == nil. This is an empty window. Try to add a box")
|
||||
}
|
||||
t.NewBox()
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
)
|
||||
|
||||
func Main(f func()) {
|
||||
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||
if (DebugToolkit) {
|
||||
log.Println("Starting gui.Main() (using gtk via andlabs/ui)")
|
||||
}
|
||||
ui.Main(f)
|
||||
}
|
||||
|
||||
|
@ -22,6 +24,8 @@ func Main(f func()) {
|
|||
// For example: Queue(NewWindow())
|
||||
//
|
||||
func Queue(f func()) {
|
||||
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
||||
if (DebugToolkit) {
|
||||
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
||||
}
|
||||
ui.QueueMain(f)
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@ var DebugToolkit bool
|
|||
func setDefaultBehavior(s bool) {
|
||||
defaultBehavior = s
|
||||
if (defaultBehavior) {
|
||||
log.Println("Setting this toolkit to use the default behavior.")
|
||||
log.Println("This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
|
||||
if (DebugToolkit) {
|
||||
log.Println("Setting this toolkit to use the default behavior.")
|
||||
log.Println("This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
|
||||
}
|
||||
stretchy = false
|
||||
padded = true
|
||||
menubar = true
|
||||
|
|
|
@ -17,7 +17,9 @@ func (t *Toolkit) ErrorWindow(msg1 string, msg2 string) {
|
|||
|
||||
func NewWindow(title string, x int, y int) *Toolkit {
|
||||
var t Toolkit
|
||||
log.Println("toolkit NewWindow", title, x, y)
|
||||
if (DebugToolkit) {
|
||||
log.Println("toolkit NewWindow", title, x, y)
|
||||
}
|
||||
w := ui.NewWindow(title, x, y, menubar)
|
||||
w.SetBorderless(canvas)
|
||||
w.SetMargined(margin)
|
||||
|
@ -50,11 +52,15 @@ func NewWindow(title string, x int, y int) *Toolkit {
|
|||
}
|
||||
|
||||
func (t *Toolkit) SetWindowTitle(title string) {
|
||||
log.Println("toolkit NewWindow", t.Name, "title", title)
|
||||
if (DebugToolkit) {
|
||||
log.Println("toolkit NewWindow", t.Name, "title", title)
|
||||
}
|
||||
win := t.uiWindow
|
||||
if (win != nil) {
|
||||
win.SetTitle(title)
|
||||
} else {
|
||||
log.Println("Setting the window title", title)
|
||||
if (DebugToolkit) {
|
||||
log.Println("Setting the window title", title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ import (
|
|||
|
||||
type greeting string
|
||||
|
||||
// this is exported
|
||||
var Greeter greeting
|
||||
|
||||
// func main() {
|
||||
func (g greeting) Greet() {
|
||||
|
@ -19,16 +21,25 @@ func (g greeting) Greet() {
|
|||
// ToolkitMain()
|
||||
}
|
||||
|
||||
// this is exported
|
||||
var Greeter greeting
|
||||
func (g greeting) JcarrButton() {
|
||||
fmt.Println("Hello GreetButton meet Universe")
|
||||
addButton("Greet foo")
|
||||
addButton("Greet foo 2")
|
||||
}
|
||||
|
||||
func AddGroup(name string) {
|
||||
func addGroup(name string) {
|
||||
log.Println("addGroup()", name)
|
||||
currentY = 2
|
||||
currentX += groupSize + 6
|
||||
}
|
||||
|
||||
func AddButton(name string) error {
|
||||
func (g greeting) AddButton(name string) {
|
||||
// func (g greeting) AddButton() {
|
||||
log.Println("gui.gocui.AddButton()", name)
|
||||
addButton(name)
|
||||
}
|
||||
|
||||
func addButton(name string) error {
|
||||
t := len(name)
|
||||
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
|
||||
if err == nil {
|
||||
|
|
|
@ -50,18 +50,18 @@ func Init() {
|
|||
log.Panicln(err)
|
||||
}
|
||||
|
||||
AddButton("hello")
|
||||
AddButton("world")
|
||||
AddButton("foo")
|
||||
addButton("hello")
|
||||
addButton("world")
|
||||
addButton("foo")
|
||||
|
||||
AddGroup("blank")
|
||||
AddButton("bar")
|
||||
AddButton("bar none")
|
||||
AddButton("bar going")
|
||||
addGroup("blank")
|
||||
addButton("bar")
|
||||
addButton("bar none")
|
||||
addButton("bar going")
|
||||
|
||||
AddGroup("te")
|
||||
AddButton("world 2")
|
||||
AddButton("foo 2")
|
||||
addGroup("te")
|
||||
addButton("world 2")
|
||||
addButton("foo 2")
|
||||
|
||||
if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Panicln(err)
|
||||
|
|
|
@ -20,7 +20,7 @@ var bottomY int = 7
|
|||
|
||||
func newJ(g *gocui.Gui) error {
|
||||
// maxX, maxY := g.Size()
|
||||
name := fmt.Sprintf("jcarr %v test ", idxView)
|
||||
name := fmt.Sprintf("jcarr %v foo ", idxView)
|
||||
v, err := g.SetView(name, topX, topY, bottomX, bottomY, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in New Issue