start trying to make the tookits plugins
totally minimize helloworld demo try to make a button plugin example debug changes final changes before attempting to use a golang plugin actually running gocui as a plugin add gocli-as-plugin example try to convert the go-cui toolkit into a plugin doc updates make a minimal console gui Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
5417c8f477
commit
482c3ef8eb
|
@ -3,3 +3,10 @@ cmds/helloworld/helloworld
|
|||
cmds/textbox/textbox
|
||||
cmds/gui-demo/gui-demo
|
||||
cmds/consolemouse/consolemouse
|
||||
cmds/console-hello-world/console-hello-world
|
||||
cmds/gocli-as-plugin/gocli-as-plugin
|
||||
cmds/buttonAsPlugin/buttonAsPlugin
|
||||
|
||||
tookit/gocui/gocli
|
||||
|
||||
toolkit/*.so
|
||||
|
|
5
Makefile
5
Makefile
|
@ -1,3 +1,5 @@
|
|||
.PHONY: README.md
|
||||
|
||||
all: README.md
|
||||
@echo
|
||||
@echo "make examples # will run all the examples"
|
||||
|
@ -33,3 +35,6 @@ doc:
|
|||
# GO111MODULE=on go install github.com/posener/goreadme/cmd/goreadme@latest (worked Oct 20 2022)
|
||||
README.md: doc.go
|
||||
goreadme -factories -types -functions -variabless > README.md
|
||||
|
||||
plugins:
|
||||
GO111MODULE="off" go build -buildmode=plugin -o toolkit/gocli.so toolkit/gocli/greeter.go
|
||||
|
|
18
README.md
18
README.md
|
@ -21,7 +21,7 @@ Principles:
|
|||
* It's ok to guess. We will return something close.
|
||||
* Hide complexity internally here
|
||||
* Isolate the GUI toolkit
|
||||
* Function names should follow [Wikipedia Graphical widget]
|
||||
* Try to use [Wikipedia Graphical widget] names
|
||||
```
|
||||
|
||||
## Quick Start
|
||||
|
@ -161,15 +161,15 @@ This creates a window that shows how this package works
|
|||
|
||||
`func GolangDebugWindow()`
|
||||
|
||||
### func [IndentPrintln](/structs.go#L190)
|
||||
### func [IndentPrintln](/structs.go#L199)
|
||||
|
||||
`func IndentPrintln(a ...interface{})`
|
||||
|
||||
### func [Main](/main.go#L34)
|
||||
### func [Main](/main.go#L31)
|
||||
|
||||
`func Main(f func())`
|
||||
|
||||
### func [Queue](/main.go#L45)
|
||||
### func [Queue](/main.go#L42)
|
||||
|
||||
`func Queue(f func())`
|
||||
|
||||
|
@ -194,7 +194,7 @@ For example: gui.Queue(NewWindow())
|
|||
|
||||
## Types
|
||||
|
||||
### type [GuiConfig](/structs.go#L42)
|
||||
### type [GuiConfig](/structs.go#L56)
|
||||
|
||||
`type GuiConfig struct { ... }`
|
||||
|
||||
|
@ -204,7 +204,11 @@ For example: gui.Queue(NewWindow())
|
|||
var Config GuiConfig
|
||||
```
|
||||
|
||||
### type [Node](/structs.go#L97)
|
||||
### type [GuiOptions](/structs.go#L44)
|
||||
|
||||
`type GuiOptions struct { ... }`
|
||||
|
||||
### type [Node](/structs.go#L104)
|
||||
|
||||
`type Node struct { ... }`
|
||||
|
||||
|
@ -262,7 +266,7 @@ func main() {
|
|||
You get a window
|
||||
```
|
||||
|
||||
### type [Widget](/structs.go#L67)
|
||||
### type [Widget](/structs.go#L74)
|
||||
|
||||
`type Widget int`
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
run: build
|
||||
./buttonAsPlugin
|
||||
|
||||
build-release:
|
||||
go get -v -u -x .
|
||||
go build
|
||||
./buttonAsPlugin
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go get -v -x .
|
||||
GO111MODULE="off" go build
|
||||
|
||||
update:
|
||||
GO111MODULE="off" go get -v -u -x .
|
|
@ -0,0 +1,33 @@
|
|||
// This is a simple example
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gui.Main(buttonWindow)
|
||||
}
|
||||
|
||||
// This creates a window
|
||||
func buttonWindow() {
|
||||
var w, g *gui.Node
|
||||
gui.Config.Title = "Demo Plugin Window"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
|
||||
// gui.Config.Exit = gui.StandardClose
|
||||
// gui.SetDebug(true)
|
||||
|
||||
w = gui.NewWindow()
|
||||
g = w.NewGroup("buttonGroup")
|
||||
|
||||
g.NewButton("hello", func () {
|
||||
log.Println("world")
|
||||
})
|
||||
|
||||
g.NewButton("foo", func () {
|
||||
log.Println("bar")
|
||||
})
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
run: build
|
||||
./console-hello-world
|
||||
reset
|
||||
ldd ./console-hello-world
|
||||
|
||||
build-release:
|
||||
go get -v -u -x .
|
||||
go build
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go get -v -x .
|
||||
GO111MODULE="off" go build
|
||||
|
||||
update:
|
||||
GO111MODULE="off" go get -v -u -x .
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
// "errors"
|
||||
// "fmt"
|
||||
"log"
|
||||
// "strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func initKeybindings(g *gocui.Gui) error {
|
||||
log.Println("got to initKeybindings")
|
||||
if err := g.SetKeybinding("", 'q', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'Q', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeySpace, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return newView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyBackspace, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return delView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyBackspace2, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return delView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("tab", v.Name())
|
||||
return nextView(g, true)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowLeft, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return moveView(g, v, -delta, 0)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return moveView(g, v, delta, 0)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("down", v.Name())
|
||||
return moveView(g, v, 0, delta)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("up", v.Name())
|
||||
return moveView(g, v, 0, -delta)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("enter", v.Name())
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 't', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
_, err := g.SetViewOnTop(views[curView])
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'b', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
_, err := g.SetViewOnBottom(views[curView])
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'j', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return newJ(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'h', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("help", v.Name())
|
||||
tmp, _ := g.SetViewOnTop("help")
|
||||
log.Println("help 2", tmp.Name(), "blah")
|
||||
// g.SetView("help", 2, 2, 30, 15, 0);
|
||||
g.SetCurrentView("help")
|
||||
// moveView(g, tmp, 0, -delta)
|
||||
if err := g.DeleteView("help"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// This creates a simple hello world window
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
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 f *os.File
|
||||
var err error
|
||||
|
||||
func init() {
|
||||
arg.MustParse(&args)
|
||||
fmt.Println(args.Foo, args.Bar, args.User)
|
||||
|
||||
f, 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(f)
|
||||
log.Println("This is a test log entry")
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
const delta = 1
|
||||
|
||||
var (
|
||||
views = []string{}
|
||||
curView = -1
|
||||
idxView = 0
|
||||
currentX = 5
|
||||
currentY = 2
|
||||
groupSize = 0
|
||||
baseGui *gocui.Gui
|
||||
)
|
||||
|
||||
var helpLabel *gocui.View
|
||||
|
||||
func main() {
|
||||
// setup log to write to a file
|
||||
// logInit()
|
||||
|
||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
||||
baseGui = g
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
g.Highlight = true
|
||||
g.SelFgColor = gocui.ColorRed
|
||||
g.SelFrameColor = gocui.ColorRed
|
||||
|
||||
g.SetManagerFunc(layout)
|
||||
|
||||
if err := initKeybindings(g); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if err := newView(g); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
addButton("hello")
|
||||
addButton("world")
|
||||
addButton("foo")
|
||||
|
||||
addGroup("blank")
|
||||
addButton("bar")
|
||||
addButton("bar none")
|
||||
addButton("bar going")
|
||||
|
||||
addGroup("te")
|
||||
addButton("world 2")
|
||||
addButton("foo 2")
|
||||
|
||||
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
var err error
|
||||
maxX, _ := g.Size()
|
||||
helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 11, 0)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(helpLabel, "KEYBINDINGS")
|
||||
fmt.Fprintln(helpLabel, "Enter: Click Button")
|
||||
fmt.Fprintln(helpLabel, "Tab/Space: Switch Buttons")
|
||||
fmt.Fprintln(helpLabel, "")
|
||||
fmt.Fprintln(helpLabel, "h: Help")
|
||||
fmt.Fprintln(helpLabel, "Backspace: Delete Button")
|
||||
fmt.Fprintln(helpLabel, "Arrow keys: Move Button")
|
||||
fmt.Fprintln(helpLabel, "t: Move Button to the top")
|
||||
fmt.Fprintln(helpLabel, "b: Move Button to the button")
|
||||
fmt.Fprintln(helpLabel, "Ctrl-C or Q: Exit")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
var topX int = 2
|
||||
var bottomX int = 20
|
||||
var topY int = 2
|
||||
var bottomY int = 7
|
||||
|
||||
func newJ(g *gocui.Gui) error {
|
||||
// maxX, maxY := g.Size()
|
||||
name := fmt.Sprintf("jcarr %v test ", idxView)
|
||||
v, err := g.SetView(name, topX, topY, bottomX, bottomY, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, name)
|
||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
||||
// fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
||||
log.Println("newJ added a new view", v.Name())
|
||||
|
||||
if _, err := g.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func addGroup(name string) {
|
||||
log.Println("addGroup()", name)
|
||||
currentY = 2
|
||||
currentX += groupSize + 6
|
||||
}
|
||||
|
||||
func addButton(name string) error {
|
||||
t := len(name)
|
||||
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, " " + name)
|
||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
||||
|
||||
if _, err := baseGui.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
currentY += 3
|
||||
if (groupSize < len(views)) {
|
||||
groupSize = len(views)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newView(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
name := fmt.Sprintf("v%v", idxView)
|
||||
v, err := g.SetView(name, maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
||||
|
||||
if _, err := g.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
return nil
|
||||
}
|
||||
|
||||
func delView(g *gocui.Gui) error {
|
||||
if len(views) <= 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := g.DeleteView(views[curView]); err != nil {
|
||||
return err
|
||||
}
|
||||
views = append(views[:curView], views[curView+1:]...)
|
||||
|
||||
return nextView(g, false)
|
||||
}
|
||||
|
||||
func nextView(g *gocui.Gui, disableCurrent bool) error {
|
||||
next := curView + 1
|
||||
if next > len(views)-1 {
|
||||
next = 0
|
||||
}
|
||||
|
||||
if _, err := g.SetCurrentView(views[next]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curView = next
|
||||
return nil
|
||||
}
|
||||
|
||||
func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error {
|
||||
name := v.Name()
|
||||
x0, y0, x1, y1, err := g.ViewPosition(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println(x0, y0, x1, y1)
|
||||
if _, err := g.SetView(name, x0+dx, y0+dy, x1+dx, y1+dy, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
x0, y0, x1, y1, err = g.ViewPosition(name)
|
||||
log.Println(x0, y0, x1, y1)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
run: build
|
||||
./gocli-as-plugin
|
||||
# ldd ./gocli-as-plugin
|
||||
|
||||
build-release:
|
||||
go get -v -u -x .
|
||||
go build
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go get -v -x .
|
||||
GO111MODULE="off" go build
|
||||
|
||||
update:
|
||||
GO111MODULE="off" go get -v -u -x .
|
|
@ -0,0 +1,35 @@
|
|||
// This creates a simple hello world window
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"fmt"
|
||||
"os"
|
||||
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 f *os.File
|
||||
var err error
|
||||
|
||||
func init() {
|
||||
arg.MustParse(&args)
|
||||
fmt.Println(args.Foo, args.Bar, args.User)
|
||||
|
||||
f, 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(f)
|
||||
log.Println("This is a test log entry")
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"plugin"
|
||||
// "github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
type Greeter interface {
|
||||
Greet()
|
||||
}
|
||||
|
||||
var plugGocli *plugin.Plugin
|
||||
var plugHello *plugin.Plugin
|
||||
|
||||
func main() {
|
||||
log.Println("attempt plugin")
|
||||
|
||||
go loadPlugin(plugHello, "../../toolkit/hello.so")
|
||||
loadPlugin(plugGocli, "../../toolkit/gocli.so")
|
||||
}
|
||||
|
||||
func loadPlugin(plug *plugin.Plugin, name string) {
|
||||
// load module
|
||||
// 1. open the so file to load the symbols
|
||||
plug, err = plugin.Open(name)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 2. look up a symbol (an exported function or variable)
|
||||
// in this case, variable Greeter
|
||||
symGreeter, err := plug.Lookup("Greeter")
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
log.Println("symGreater", symGreeter)
|
||||
|
||||
// 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)
|
||||
if !ok {
|
||||
log.Println("unexpected type from module symbol")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 4. use the module
|
||||
greeter.Greet()
|
||||
}
|
|
@ -1,44 +1,24 @@
|
|||
// This creates a simple hello world window
|
||||
// This is a simple example
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"log"
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
func main() {
|
||||
gui.Main(myGUI)
|
||||
gui.Main(helloworld)
|
||||
}
|
||||
|
||||
// This initializes the first window
|
||||
func myGUI() {
|
||||
// This creates a window
|
||||
func helloworld() {
|
||||
var w *gui.Node
|
||||
gui.Config.Title = "Hello World golang wit/gui Window"
|
||||
gui.Config.Title = "helloworld golang wit/gui window"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
gui.Config.Exit = myExit
|
||||
|
||||
w = gui.NewWindow()
|
||||
addHelloWorld(w, "A Simple Tab")
|
||||
w.NewButton("hello", func () {
|
||||
log.Println("world")
|
||||
})
|
||||
}
|
||||
|
||||
func addHelloWorld(window *gui.Node, title string) {
|
||||
var newNode, g, tb *gui.Node
|
||||
|
||||
newNode = window.NewTab(title)
|
||||
|
||||
g = newNode.NewGroup("hello")
|
||||
tb = g.NewTextbox("hello world box") // when debugging, this string will be used
|
||||
tb.OnChanged = func(*gui.Node) {
|
||||
s := tb.GetText()
|
||||
log.Println("text box =", s)
|
||||
}
|
||||
tb.SetText("world")
|
||||
}
|
||||
|
||||
func myExit(n *gui.Node) {
|
||||
log.Println("exit() here")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
|
|
3
doc.go
3
doc.go
|
@ -18,8 +18,7 @@ Principles:
|
|||
* It's ok to guess. We will return something close.
|
||||
* Hide complexity internally here
|
||||
* Isolate the GUI toolkit
|
||||
* Function names should follow [Wikipedia Graphical widget]
|
||||
|
||||
* Try to use [Wikipedia Graphical widget] names
|
||||
|
||||
Quick Start
|
||||
|
||||
|
|
40
main.go
40
main.go
|
@ -2,33 +2,33 @@ package gui
|
|||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
|
||||
import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
||||
|
||||
|
||||
// the _ means we only need this for the init()
|
||||
|
||||
const Xaxis = 0 // box that is horizontal
|
||||
const Yaxis = 1 // box that is vertical
|
||||
const Xaxis = 0 // stack things horizontally
|
||||
const Yaxis = 1 // stack things vertically
|
||||
|
||||
func init() {
|
||||
log.Println("gui.init() has been run")
|
||||
|
||||
Config.counter = 0
|
||||
Config.prefix = "wit"
|
||||
Config.Options.DebugNode = false
|
||||
Config.Options.DebugTabs = false
|
||||
|
||||
title := "master"
|
||||
// Config.Options.Debug = true
|
||||
// Config.Options.DebugNode = true
|
||||
// Config.Options.DebugTabs = true
|
||||
|
||||
title := "guiBinaryTree"
|
||||
w := 640
|
||||
h := 480
|
||||
// f := StandardClose
|
||||
|
||||
// Populates the top of the binary tree
|
||||
Config.master = addNode(title, w, h)
|
||||
// Config.master.custom = f
|
||||
|
||||
Config.master.Dump()
|
||||
if (Config.Options.Debug) {
|
||||
Config.master.Dump()
|
||||
}
|
||||
}
|
||||
|
||||
func Main(f func()) {
|
||||
|
@ -46,3 +46,19 @@ func Queue(f func()) {
|
|||
log.Println("Sending function to gui.Main() (using gtk via andlabs/ui)")
|
||||
toolkit.Queue(f)
|
||||
}
|
||||
|
||||
// The window is destroyed but the application does not quit
|
||||
func StandardClose(n *Node) {
|
||||
if (Config.Options.Debug) {
|
||||
log.Println("wit/gui Standard Window Close. name =", n.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// The window is destroyed but the application does not quit
|
||||
func StandardExit(n *Node) {
|
||||
if (Config.Options.Debug) {
|
||||
log.Println("wit/gui Standard Window Exit. running os.Exit()")
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
10
node.go
10
node.go
|
@ -1,8 +1,5 @@
|
|||
package gui
|
||||
|
||||
import "strconv"
|
||||
// import "fmt"
|
||||
|
||||
/*
|
||||
generic function to create a new node on the binary tree
|
||||
*/
|
||||
|
@ -25,9 +22,12 @@ func addNode(title string, w int, h int) *Node {
|
|||
n.Width = w
|
||||
n.Height = h
|
||||
|
||||
id := Config.prefix + strconv.Itoa(Config.counter)
|
||||
// no longer a string
|
||||
// id := Config.prefix + strconv.Itoa(Config.counter)
|
||||
// n.id = id
|
||||
|
||||
n.id = Config.counter
|
||||
Config.counter += 1
|
||||
n.id = id
|
||||
|
||||
return &n
|
||||
}
|
||||
|
|
38
structs.go
38
structs.go
|
@ -21,7 +21,15 @@ import toolkit "git.wit.org/wit/gui/toolkit/andlabs"
|
|||
|
||||
var Config GuiConfig
|
||||
|
||||
func SetDebugToolkit (s bool) {
|
||||
func GetDebug () bool {
|
||||
return Config.Options.Debug
|
||||
}
|
||||
|
||||
func SetDebug (s bool) {
|
||||
Config.Options.Debug = s
|
||||
// also set these
|
||||
Config.Options.DebugDump = s
|
||||
Config.Options.DebugNode = s
|
||||
toolkit.DebugToolkit = s
|
||||
}
|
||||
|
||||
|
@ -29,6 +37,10 @@ func GetDebugToolkit () bool {
|
|||
return toolkit.DebugToolkit
|
||||
}
|
||||
|
||||
func SetDebugToolkit (s bool) {
|
||||
toolkit.DebugToolkit = s
|
||||
}
|
||||
|
||||
func ShowDebugValues() {
|
||||
log.Println("\t wit/gui Debug =", Config.Options.Debug)
|
||||
log.Println("\t wit/gui DebugDump =", Config.Options.DebugDump)
|
||||
|
@ -102,23 +114,27 @@ func (s Widget) String() string {
|
|||
|
||||
// The Node is simply the name and the size of whatever GUI element exists
|
||||
type Node struct {
|
||||
id string
|
||||
id int
|
||||
|
||||
Name string
|
||||
Width int
|
||||
Height int
|
||||
|
||||
// this function is run when there are mouse or keyboard events
|
||||
OnChanged func(*Node)
|
||||
|
||||
parent *Node
|
||||
// TODO: make children a double linked list since some toolkits require order
|
||||
// TODO: make children a double linked list since some toolkits require order (?)
|
||||
children []*Node
|
||||
|
||||
// hmm. how do you handle this when the toolkits are plugins?
|
||||
toolkit *toolkit.Toolkit
|
||||
|
||||
// things that may not really be needed (?)
|
||||
custom func()
|
||||
OnChanged func(*Node)
|
||||
checked bool
|
||||
text string
|
||||
|
||||
toolkit *toolkit.Toolkit
|
||||
}
|
||||
|
||||
func (n *Node) Parent() *Node {
|
||||
|
@ -159,12 +175,12 @@ func (n *Node) Dump() {
|
|||
IndentPrintln("toolkit = ", reflect.ValueOf(n.toolkit).Kind())
|
||||
n.toolkit.Dump()
|
||||
}
|
||||
if (n.id == "") {
|
||||
// Node structs should never have a nil id.
|
||||
// I probably shouldn't panic here, but this is just to check the sanity of
|
||||
// the gui package to make sure it's not exiting
|
||||
panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
|
||||
}
|
||||
// if (n.id == nil) {
|
||||
// // Node structs should never have a nil id.
|
||||
// // I probably shouldn't panic here, but this is just to check the sanity of
|
||||
// // the gui package to make sure it's not exiting
|
||||
// panic("gui.Node.Dump() id == nil TODO: make a unigue id here in the golang gui library")
|
||||
// }
|
||||
IndentPrintln("NODE DUMP END")
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,19 @@ func (t *Toolkit) NewBox() *Toolkit {
|
|||
|
||||
return &newTK
|
||||
}
|
||||
if (t.uiWindow != nil) {
|
||||
log.Println("\tgui.Toolbox.NewBox() is a Window")
|
||||
var newT Toolkit
|
||||
|
||||
vbox := ui.NewVerticalBox()
|
||||
vbox.SetPadded(padded)
|
||||
t.uiWindow.SetChild(vbox)
|
||||
newT.uiBox = vbox
|
||||
newT.Name = t.Name
|
||||
|
||||
// panic("WTF")
|
||||
return &newT
|
||||
}
|
||||
log.Println("\tgui.Toolbox.NewBox() FAILED. Couldn't figure out where to make a box")
|
||||
t.Dump()
|
||||
return nil
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package toolkit
|
||||
|
||||
import "log"
|
||||
import "os"
|
||||
// import "os"
|
||||
|
||||
import "github.com/andlabs/ui"
|
||||
import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
@ -11,15 +11,12 @@ func (t Toolkit) NewButton(name string) *Toolkit {
|
|||
var newt Toolkit
|
||||
var b *ui.Button
|
||||
|
||||
if (t.uiBox == nil) {
|
||||
log.Println("gui.ToolboxNode.NewButton() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||
log.Println("probably could just make a box here?")
|
||||
os.Exit(0)
|
||||
if t.broken() {
|
||||
return nil
|
||||
}
|
||||
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolbox.NewGroup() create", name)
|
||||
log.Println("gui.Toolbox.NewButton() create", name)
|
||||
}
|
||||
b = ui.NewButton(name)
|
||||
newt.uiButton = b
|
||||
|
@ -40,6 +37,7 @@ func (t Toolkit) NewButton(name string) *Toolkit {
|
|||
log.Println("wit/gui/toolkit NewButton() toolkit.Custom() START")
|
||||
}
|
||||
newt.Custom()
|
||||
return
|
||||
if (DebugToolkit) {
|
||||
log.Println("wit/gui/toolkit NewButton() toolkit.Custom() END")
|
||||
}
|
||||
|
@ -53,14 +51,29 @@ func (t Toolkit) NewButton(name string) *Toolkit {
|
|||
log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() START (IS THIS A BAD IDEA?)")
|
||||
}
|
||||
t.Custom()
|
||||
return
|
||||
if (DebugToolkit) {
|
||||
log.Println("wit/gui/toolkit NewButton() running parent toolkit.Custom() END (IS THIS A BAD IDEA?)")
|
||||
}
|
||||
}
|
||||
log.Println("TODO: LEFT TOOLKIT GOROUTINE button name =", name)
|
||||
log.Println("TODO: LEFT TOOLKIT GOROUTINE WITH NOTHING TO DO button name =", name)
|
||||
})
|
||||
|
||||
t.uiBox.Append(b, stretchy)
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolbox.NewButton() about to append to Box parent t:", name)
|
||||
t.Dump()
|
||||
log.Println("gui.Toolbox.NewButton() about to append to Box new t:", name)
|
||||
newt.Dump()
|
||||
}
|
||||
if (t.uiBox != nil) {
|
||||
t.uiBox.Append(b, stretchy)
|
||||
} else if (t.uiWindow != nil) {
|
||||
t.uiWindow.SetChild(b)
|
||||
} else {
|
||||
log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window")
|
||||
log.Println("ERROR: wit/gui andlabs couldn't place this button in a box or a window")
|
||||
return &t
|
||||
}
|
||||
|
||||
return &newt
|
||||
}
|
||||
|
|
|
@ -2,9 +2,6 @@ package toolkit
|
|||
|
||||
import "log"
|
||||
|
||||
// import "github.com/andlabs/ui"
|
||||
// import _ "github.com/andlabs/ui/winmanifest"
|
||||
|
||||
func init() {
|
||||
log.Println("gui/toolkit init() Setting defaultBehavior = true")
|
||||
setDefaultBehavior(true)
|
||||
|
@ -37,8 +34,13 @@ func (t Toolkit) commonChange(widget string) {
|
|||
|
||||
// does some sanity checks on the internal structs of the binary tree
|
||||
// TODO: probably this should not panic unless it's running in devel mode (?)
|
||||
func (t Toolkit) broken() bool {
|
||||
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")
|
||||
t.NewBox()
|
||||
return false
|
||||
}
|
||||
log.Println("gui.Toolkit.UiBox == nil. I can't add a widget without a place to put it")
|
||||
// log.Println("probably could just make a box here?")
|
||||
// corruption or something horrible?
|
||||
|
@ -48,6 +50,7 @@ func (t Toolkit) broken() bool {
|
|||
}
|
||||
if (t.uiWindow == nil) {
|
||||
log.Println("gui.Toolkit.UiWindow == nil. I can't add a widget without a place to put it (IGNORING FOR NOW)")
|
||||
forceDump(t)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -10,19 +10,21 @@ import _ "github.com/andlabs/ui/winmanifest"
|
|||
func (t Toolkit) NewGroup(title string) *Toolkit {
|
||||
var newt Toolkit
|
||||
|
||||
if (t.uiBox == nil) {
|
||||
log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||
log.Println("probably could just make a box here?")
|
||||
os.Exit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
if (DebugToolkit) {
|
||||
log.Println("gui.Toolbox.NewGroup() create", title)
|
||||
}
|
||||
g := ui.NewGroup(title)
|
||||
g.SetMargined(margin)
|
||||
t.uiBox.Append(g, stretchy)
|
||||
|
||||
if (t.uiBox != nil) {
|
||||
t.uiBox.Append(g, stretchy)
|
||||
} else if (t.uiWindow != nil) {
|
||||
t.uiWindow.SetChild(g)
|
||||
} else {
|
||||
log.Println("gui.ToolboxNode.NewGroup() node.UiBox == nil. I can't add a range UI element without a place to put it")
|
||||
log.Println("probably could just make a box here?")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
hbox := ui.NewVerticalBox()
|
||||
hbox.SetPadded(padded)
|
||||
|
@ -30,6 +32,7 @@ func (t Toolkit) NewGroup(title string) *Toolkit {
|
|||
|
||||
newt.uiGroup = g
|
||||
newt.uiBox = hbox
|
||||
newt.uiWindow = t.uiWindow
|
||||
newt.Name = title
|
||||
|
||||
t.Dump()
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/andlabs/ui"
|
||||
// the _ means we only need this for the init()
|
||||
_ "github.com/andlabs/ui/winmanifest"
|
||||
)
|
||||
|
||||
|
|
|
@ -87,9 +87,10 @@ func (t *Toolkit) String() string {
|
|||
}
|
||||
|
||||
func forceDump(t *Toolkit) {
|
||||
tmp := DebugToolkit
|
||||
DebugToolkit = true
|
||||
t.Dump()
|
||||
DebugToolkit = false
|
||||
DebugToolkit = tmp
|
||||
}
|
||||
|
||||
func (t *Toolkit) GetText() string {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
all: plugin
|
||||
ldd ../gocli.so
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go build
|
||||
|
||||
plugin:
|
||||
GO111MODULE="off" go build -buildmode=plugin -o ../gocli.so
|
|
@ -0,0 +1,57 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
type greeting string
|
||||
|
||||
|
||||
// func main() {
|
||||
func (g greeting) Greet() {
|
||||
fmt.Println("Hello Universe")
|
||||
Init()
|
||||
// ToolkitMain()
|
||||
}
|
||||
|
||||
// this is exported
|
||||
var Greeter greeting
|
||||
|
||||
func AddGroup(name string) {
|
||||
log.Println("addGroup()", name)
|
||||
currentY = 2
|
||||
currentX += groupSize + 6
|
||||
}
|
||||
|
||||
func AddButton(name string) error {
|
||||
t := len(name)
|
||||
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, " " + name)
|
||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
||||
|
||||
if _, err := baseGui.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
currentY += 3
|
||||
if (groupSize < len(views)) {
|
||||
groupSize = len(views)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,130 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
// "errors"
|
||||
// "fmt"
|
||||
"log"
|
||||
// "strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func initKeybindings(g *gocui.Gui) error {
|
||||
log.Println("got to initKeybindings")
|
||||
if err := g.SetKeybinding("", 'q', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'Q', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return gocui.ErrQuit
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeySpace, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return newView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyBackspace, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return delView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyBackspace2, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return delView(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyTab, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("tab", v.Name())
|
||||
return nextView(g, true)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowLeft, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return moveView(g, v, -delta, 0)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowRight, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return moveView(g, v, delta, 0)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowDown, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("down", v.Name())
|
||||
return moveView(g, v, 0, delta)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyArrowUp, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("up", v.Name())
|
||||
return moveView(g, v, 0, -delta)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", gocui.KeyEnter, gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("enter", v.Name())
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 't', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
_, err := g.SetViewOnTop(views[curView])
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'b', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
_, err := g.SetViewOnBottom(views[curView])
|
||||
return err
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'j', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
return newJ(g)
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := g.SetKeybinding("", 'h', gocui.ModNone,
|
||||
func(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Println("help", v.Name())
|
||||
tmp, _ := g.SetViewOnTop("help")
|
||||
log.Println("help 2", tmp.Name(), "blah")
|
||||
// g.SetView("help", 2, 2, 30, 15, 0);
|
||||
g.SetCurrentView("help")
|
||||
// moveView(g, tmp, 0, -delta)
|
||||
if err := g.DeleteView("help"); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
const delta = 1
|
||||
|
||||
var (
|
||||
views = []string{}
|
||||
curView = -1
|
||||
idxView = 0
|
||||
currentX = 5
|
||||
currentY = 2
|
||||
groupSize = 0
|
||||
baseGui *gocui.Gui
|
||||
)
|
||||
|
||||
var helpLabel *gocui.View
|
||||
|
||||
func Init() {
|
||||
// setup log to write to a file
|
||||
// logInit()
|
||||
|
||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
||||
baseGui = g
|
||||
if err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
g.Highlight = true
|
||||
g.SelFgColor = gocui.ColorRed
|
||||
g.SelFrameColor = gocui.ColorRed
|
||||
|
||||
g.SetManagerFunc(layout)
|
||||
|
||||
if err := initKeybindings(g); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
if err := newView(g); err != nil {
|
||||
log.Panicln(err)
|
||||
}
|
||||
|
||||
AddButton("hello")
|
||||
AddButton("world")
|
||||
AddButton("foo")
|
||||
|
||||
AddGroup("blank")
|
||||
AddButton("bar")
|
||||
AddButton("bar none")
|
||||
AddButton("bar going")
|
||||
|
||||
AddGroup("te")
|
||||
AddButton("world 2")
|
||||
AddButton("foo 2")
|
||||
|
||||
if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func ToolkitMain() {
|
||||
if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Panicln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func layout(g *gocui.Gui) error {
|
||||
var err error
|
||||
maxX, _ := g.Size()
|
||||
helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 11, 0)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(helpLabel, "KEYBINDINGS")
|
||||
fmt.Fprintln(helpLabel, "Enter: Click Button")
|
||||
fmt.Fprintln(helpLabel, "Tab/Space: Switch Buttons")
|
||||
fmt.Fprintln(helpLabel, "")
|
||||
fmt.Fprintln(helpLabel, "h: Help")
|
||||
fmt.Fprintln(helpLabel, "Backspace: Delete Button")
|
||||
fmt.Fprintln(helpLabel, "Arrow keys: Move Button")
|
||||
fmt.Fprintln(helpLabel, "t: Move Button to the top")
|
||||
fmt.Fprintln(helpLabel, "b: Move Button to the button")
|
||||
fmt.Fprintln(helpLabel, "Ctrl-C or Q: Exit")
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
var topX int = 2
|
||||
var bottomX int = 20
|
||||
var topY int = 2
|
||||
var bottomY int = 7
|
||||
|
||||
func newJ(g *gocui.Gui) error {
|
||||
// maxX, maxY := g.Size()
|
||||
name := fmt.Sprintf("jcarr %v test ", idxView)
|
||||
v, err := g.SetView(name, topX, topY, bottomX, bottomY, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, name)
|
||||
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
|
||||
// fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
||||
log.Println("newJ added a new view", v.Name())
|
||||
|
||||
if _, err := g.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func newView(g *gocui.Gui) error {
|
||||
maxX, maxY := g.Size()
|
||||
name := fmt.Sprintf("v%v", idxView)
|
||||
v, err := g.SetView(name, maxX/2-5, maxY/2-5, maxX/2+5, maxY/2+5, 0)
|
||||
if err == nil {
|
||||
return err
|
||||
}
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Wrap = true
|
||||
fmt.Fprintln(v, strings.Repeat(name+" ", 30))
|
||||
|
||||
if _, err := g.SetCurrentView(name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
views = append(views, name)
|
||||
curView = len(views) - 1
|
||||
idxView += 1
|
||||
return nil
|
||||
}
|
||||
|
||||
func delView(g *gocui.Gui) error {
|
||||
if len(views) <= 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := g.DeleteView(views[curView]); err != nil {
|
||||
return err
|
||||
}
|
||||
views = append(views[:curView], views[curView+1:]...)
|
||||
|
||||
return nextView(g, false)
|
||||
}
|
||||
|
||||
func nextView(g *gocui.Gui, disableCurrent bool) error {
|
||||
next := curView + 1
|
||||
if next > len(views)-1 {
|
||||
next = 0
|
||||
}
|
||||
|
||||
if _, err := g.SetCurrentView(views[next]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
curView = next
|
||||
return nil
|
||||
}
|
||||
|
||||
func moveView(g *gocui.Gui, v *gocui.View, dx, dy int) error {
|
||||
name := v.Name()
|
||||
x0, y0, x1, y1, err := g.ViewPosition(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.Println(x0, y0, x1, y1)
|
||||
if _, err := g.SetView(name, x0+dx, y0+dy, x1+dx, y1+dy, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
x0, y0, x1, y1, err = g.ViewPosition(name)
|
||||
log.Println(x0, y0, x1, y1)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
all: plugin
|
||||
ldd ../hello.so
|
||||
|
||||
build:
|
||||
GO111MODULE="off" go build
|
||||
|
||||
plugin:
|
||||
GO111MODULE="off" go build -buildmode=plugin -o ../hello.so
|
|
@ -0,0 +1,23 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
// "errors"
|
||||
"fmt"
|
||||
// "log"
|
||||
// "strings"
|
||||
|
||||
// "github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
type greeting string
|
||||
|
||||
|
||||
// func main() {
|
||||
func (g greeting) Greet() {
|
||||
fmt.Println("Hello Universe")
|
||||
Init()
|
||||
// ToolkitMain()
|
||||
}
|
||||
|
||||
// this is exported
|
||||
var Greeter greeting
|
|
@ -0,0 +1,44 @@
|
|||
// This creates a simple hello world window
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"log"
|
||||
"git.wit.org/wit/gui"
|
||||
)
|
||||
|
||||
func Init() {
|
||||
gui.Main(myGUI)
|
||||
}
|
||||
|
||||
// This initializes the first window
|
||||
func myGUI() {
|
||||
var w *gui.Node
|
||||
gui.Config.Title = "Hello World golang wit/gui Window"
|
||||
gui.Config.Width = 640
|
||||
gui.Config.Height = 480
|
||||
gui.Config.Exit = myExit
|
||||
|
||||
w = gui.NewWindow()
|
||||
addHelloWorld(w, "A Simple Tab")
|
||||
}
|
||||
|
||||
func addHelloWorld(window *gui.Node, title string) {
|
||||
var newNode, g, tb *gui.Node
|
||||
|
||||
newNode = window.NewTab(title)
|
||||
|
||||
g = newNode.NewGroup("hello")
|
||||
tb = g.NewTextbox("hello world box") // when debugging, this string will be used
|
||||
tb.OnChanged = func(*gui.Node) {
|
||||
s := tb.GetText()
|
||||
log.Println("text box =", s)
|
||||
}
|
||||
tb.SetText("world")
|
||||
}
|
||||
|
||||
func myExit(n *gui.Node) {
|
||||
log.Println("exit() here")
|
||||
os.Exit(0)
|
||||
}
|
||||
|
|
@ -9,14 +9,6 @@ import (
|
|||
"runtime/pprof"
|
||||
)
|
||||
|
||||
func StandardClose(n *Node) {
|
||||
// origlog.Println("Should Exit Here")
|
||||
// closed = true
|
||||
log.Println("")
|
||||
log.Println("STANDARD WINDOW CLOSE. Should not exit app.")
|
||||
log.Println("")
|
||||
}
|
||||
|
||||
func GolangDebugWindow() {
|
||||
var w, t *Node
|
||||
|
||||
|
|
18
window.go
18
window.go
|
@ -23,19 +23,23 @@ func NewWindow() *Node {
|
|||
|
||||
// Windows are created off of the master node of the Binary Tree
|
||||
n = Config.master.New(title)
|
||||
// n.custom = f
|
||||
|
||||
n.OnChanged = Config.Exit
|
||||
|
||||
t = toolkit.NewWindow(title, w, h)
|
||||
t.Custom = func () {
|
||||
log.Println("Got to wit/gui Window Close START user defined close()")
|
||||
if (n.custom == nil) {
|
||||
log.Println("Got to wit/gui Window Close SKIP node.custom() == nil")
|
||||
if (Config.Options.Debug) {
|
||||
log.Println("Got to wit/gui Window Close START user defined close()")
|
||||
}
|
||||
if (n.OnChanged != nil) {
|
||||
if (Config.Options.Debug) {
|
||||
log.Println("Got to wit/gui Window Close SKIP node.custom() == nil")
|
||||
}
|
||||
n.OnChanged(n)
|
||||
return
|
||||
}
|
||||
n.custom()
|
||||
log.Println("Got to wit/gui Window Close END user defined close()")
|
||||
StandardExit(n)
|
||||
}
|
||||
n.toolkit = t
|
||||
|
||||
return n
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue