summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Carr <[email protected]>2022-11-06 19:57:20 -0600
committerJeff Carr <[email protected]>2022-11-06 19:57:20 -0600
commitb410d0fd083ee89eed410cda2123a22cddcd3f44 (patch)
tree3f1a637003629a3ec7d383b5db6beb0df9e5a97c
parente55fb6675d692e3f44fa67b02b12661e476bd028 (diff)
Implement a early AddButton() via a golang pluginv0.4.5
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 <[email protected]>
-rw-r--r--cmds/buttonAsPlugin/Makefile2
-rw-r--r--cmds/buttonAsPlugin/log.go64
-rw-r--r--cmds/buttonAsPlugin/main.go31
-rw-r--r--group.go5
-rw-r--r--main.go7
-rw-r--r--plugin.go90
-rw-r--r--structs.go7
-rw-r--r--toolkit/andlabs/box.go20
-rw-r--r--toolkit/andlabs/common.go8
-rw-r--r--toolkit/andlabs/main.go8
-rw-r--r--toolkit/andlabs/structs.go6
-rw-r--r--toolkit/andlabs/window.go12
-rw-r--r--toolkit/gocui/greeter.go19
-rw-r--r--toolkit/gocui/main.go20
-rw-r--r--toolkit/gocui/newJ.go2
15 files changed, 260 insertions, 41 deletions
diff --git a/cmds/buttonAsPlugin/Makefile b/cmds/buttonAsPlugin/Makefile
index 431d956..d9a67bf 100644
--- a/cmds/buttonAsPlugin/Makefile
+++ b/cmds/buttonAsPlugin/Makefile
@@ -1,5 +1,5 @@
run: build
- ./buttonAsPlugin
+ ./buttonAsPlugin >/tmp/buttonAsPlugin.log 2>&1
build-release:
go get -v -u -x .
diff --git a/cmds/buttonAsPlugin/log.go b/cmds/buttonAsPlugin/log.go
new file mode 100644
index 0000000..642ff7b
--- /dev/null
+++ b/cmds/buttonAsPlugin/log.go
@@ -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)
+}
diff --git a/cmds/buttonAsPlugin/main.go b/cmds/buttonAsPlugin/main.go
index 1c2eeaf..e26c75e 100644
--- a/cmds/buttonAsPlugin/main.go
+++ b/cmds/buttonAsPlugin/main.go
@@ -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")
})
}
diff --git a/group.go b/group.go
index 07ec1b9..7e60b23 100644
--- a/group.go
+++ b/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")
diff --git a/main.go b/main.go
index 30eb6a7..e3e6609 100644
--- a/main.go
+++ b/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)
}
diff --git a/plugin.go b/plugin.go
new file mode 100644
index 0000000..5c10e03
--- /dev/null
+++ b/plugin.go
@@ -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)
+}
diff --git a/structs.go b/structs.go
index 2a0493e..bf16758 100644
--- a/structs.go
+++ b/structs.go
@@ -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"`
}
diff --git a/toolkit/andlabs/box.go b/toolkit/andlabs/box.go
index 8347bab..29a8331 100644
--- a/toolkit/andlabs/box.go
+++ b/toolkit/andlabs/box.go
@@ -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
}
diff --git a/toolkit/andlabs/common.go b/toolkit/andlabs/common.go
index e997aca..451f9d6 100644
--- a/toolkit/andlabs/common.go
+++ b/toolkit/andlabs/common.go
@@ -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
}
diff --git a/toolkit/andlabs/main.go b/toolkit/andlabs/main.go
index d1dc7e6..da639fa 100644
--- a/toolkit/andlabs/main.go
+++ b/toolkit/andlabs/main.go
@@ -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)
}
diff --git a/toolkit/andlabs/structs.go b/toolkit/andlabs/structs.go
index 374627c..9bba671 100644
--- a/toolkit/andlabs/structs.go
+++ b/toolkit/andlabs/structs.go
@@ -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
diff --git a/toolkit/andlabs/window.go b/toolkit/andlabs/window.go
index 3e5f16a..efbd672 100644
--- a/toolkit/andlabs/window.go
+++ b/toolkit/andlabs/window.go
@@ -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)
+ }
}
}
diff --git a/toolkit/gocui/greeter.go b/toolkit/gocui/greeter.go
index 9d546a7..de6ee68 100644
--- a/toolkit/gocui/greeter.go
+++ b/toolkit/gocui/greeter.go
@@ -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 {
diff --git a/toolkit/gocui/main.go b/toolkit/gocui/main.go
index 2439a3a..314f5be 100644
--- a/toolkit/gocui/main.go
+++ b/toolkit/gocui/main.go
@@ -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)
diff --git a/toolkit/gocui/newJ.go b/toolkit/gocui/newJ.go
index 47c7439..3e04cd3 100644
--- a/toolkit/gocui/newJ.go
+++ b/toolkit/gocui/newJ.go
@@ -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