gocui: always show STDOUT
Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
parent
9e3c729d11
commit
597b17039a
1
Makefile
1
Makefile
|
@ -69,6 +69,7 @@ doc:
|
||||||
goget:
|
goget:
|
||||||
GO111MODULE="off" go get -v -t -u
|
GO111MODULE="off" go get -v -t -u
|
||||||
make -C toolkit/gocui goget
|
make -C toolkit/gocui goget
|
||||||
|
make -C toolkit/andlabs goget
|
||||||
|
|
||||||
# GO111MODULE=on go install github.com/posener/goreadme/cmd/goreadme@latest (worked Oct 20 2022)
|
# GO111MODULE=on go install github.com/posener/goreadme/cmd/goreadme@latest (worked Oct 20 2022)
|
||||||
README.md: doc.go
|
README.md: doc.go
|
||||||
|
|
18
plugin.go
18
plugin.go
|
@ -107,6 +107,7 @@ func sendCallback(p *aplug, funcName string) func(chan toolkit.Action) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO: clean this up. use command args?
|
TODO: clean this up. use command args?
|
||||||
|
TODO: use LD_LIBRARY_PATH ?
|
||||||
This searches in the following order for the plugin .so files:
|
This searches in the following order for the plugin .so files:
|
||||||
./toolkit/
|
./toolkit/
|
||||||
~/go/src/go.wit.org/gui/toolkit/
|
~/go/src/go.wit.org/gui/toolkit/
|
||||||
|
@ -138,6 +139,12 @@ func searchPaths(name string) *aplug {
|
||||||
if (p != nil) {
|
if (p != nil) {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filename = "/usr/local/lib/" + name + ".so"
|
||||||
|
p = tryfile(name, filename)
|
||||||
|
if (p != nil) {
|
||||||
|
return p
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,7 +156,7 @@ func tryfile(name string, filename string) *aplug {
|
||||||
log(debugGui, "plugin FAILED =", filename, err)
|
log(debugGui, "plugin FAILED =", filename, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
log(debugGui, "loading plugin =", filename)
|
log(debugGui, "tryfile() loading plugin =", filename)
|
||||||
|
|
||||||
var newPlug *aplug
|
var newPlug *aplug
|
||||||
newPlug = new(aplug)
|
newPlug = new(aplug)
|
||||||
|
@ -166,17 +173,20 @@ func tryfile(name string, filename string) *aplug {
|
||||||
// for things like: add a new button called 'Check IPv6'
|
// for things like: add a new button called 'Check IPv6'
|
||||||
newPlug.PluginChannel = getPluginChannel(newPlug, "PluginChannel")
|
newPlug.PluginChannel = getPluginChannel(newPlug, "PluginChannel")
|
||||||
|
|
||||||
|
// add it to the list of plugins
|
||||||
allPlugins = append(allPlugins, newPlug)
|
allPlugins = append(allPlugins, newPlug)
|
||||||
|
|
||||||
log(debugPlugin, "initPlugin() END", newPlug.name, filename)
|
|
||||||
// newPlug.Init()
|
|
||||||
|
|
||||||
// set the communication to the plugins
|
// set the communication to the plugins
|
||||||
newPlug.pluginChan = newPlug.PluginChannel()
|
newPlug.pluginChan = newPlug.PluginChannel()
|
||||||
|
if (newPlug.pluginChan == nil) {
|
||||||
|
log(debugError, "tryfile() ERROR PluginChannel() returned nil for plugin:", newPlug.name, filename)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
newPlug.Callback(Config.guiChan)
|
newPlug.Callback(Config.guiChan)
|
||||||
|
|
||||||
newPlug.InitOk = true
|
newPlug.InitOk = true
|
||||||
|
|
||||||
|
log(debugPlugin, "tryfile() END", newPlug.name, filename)
|
||||||
return newPlug
|
return newPlug
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,3 +2,6 @@ all: plugin
|
||||||
|
|
||||||
plugin:
|
plugin:
|
||||||
GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so
|
GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so
|
||||||
|
|
||||||
|
goget:
|
||||||
|
GO111MODULE="off" go get -v -t -u
|
||||||
|
|
|
@ -13,12 +13,9 @@ import (
|
||||||
// to this toolkit from the wit/gui golang package
|
// to this toolkit from the wit/gui golang package
|
||||||
func init() {
|
func init() {
|
||||||
log(logInfo, "Init() of awesome-gocui")
|
log(logInfo, "Init() of awesome-gocui")
|
||||||
me.defaultWidth = 10
|
Set(&me, "default")
|
||||||
me.defaultHeight = 2 // this means by default one line of text in a button
|
|
||||||
me.defaultBehavior = true
|
me.defaultBehavior = true
|
||||||
|
|
||||||
me.horizontalPadding = 20
|
|
||||||
me.horizontalPadding = 20
|
|
||||||
me.groupPadding = 4
|
me.groupPadding = 4
|
||||||
me.buttonPadding = 3
|
me.buttonPadding = 3
|
||||||
|
|
||||||
|
@ -29,14 +26,21 @@ func init() {
|
||||||
me.padW = 3
|
me.padW = 3
|
||||||
me.padH = 3
|
me.padH = 3
|
||||||
|
|
||||||
|
// todo, remove all of these
|
||||||
|
me.defaultWidth = 10
|
||||||
|
me.defaultHeight = 2 // this means by default one line of text in a button
|
||||||
|
|
||||||
|
me.horizontalPadding = 20
|
||||||
|
me.horizontalPadding = 20
|
||||||
|
// todo, remove all of these
|
||||||
|
|
||||||
me.pluginChan = make(chan toolkit.Action)
|
me.pluginChan = make(chan toolkit.Action)
|
||||||
|
|
||||||
log(logNow, "Init() start pluginChan")
|
log(logNow, "Init() start pluginChan")
|
||||||
go catchActionChannel()
|
go catchActionChannel()
|
||||||
sleep(.1)
|
sleep(.1) // probably not needed, but in here for now under development
|
||||||
go main()
|
go main()
|
||||||
// probably not needed, but in here for now under development
|
sleep(.1) // probably not needed, but in here for now under development
|
||||||
sleep(.1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this sets the channel to send user events back from the plugin
|
// this sets the channel to send user events back from the plugin
|
||||||
|
|
|
@ -35,33 +35,28 @@ func MouseMain() {
|
||||||
|
|
||||||
func layout(g *gocui.Gui) error {
|
func layout(g *gocui.Gui) error {
|
||||||
maxX, maxY := g.Size()
|
maxX, maxY := g.Size()
|
||||||
|
mx, my := g.MousePosition()
|
||||||
if _, err := g.View("msg"); msgMouseDown && err == nil {
|
if _, err := g.View("msg"); msgMouseDown && err == nil {
|
||||||
moveMsg(g)
|
moveMsg(g)
|
||||||
}
|
}
|
||||||
if v, err := g.SetView("global", -1, -1, maxX, maxY, 0); err != nil {
|
// if v, err := g.SetView("global", -1, -1, maxX, maxY, 0); err != nil {
|
||||||
|
// what is this do? I made it just the top 2 lines for now. Is this useful for something?
|
||||||
|
if v, err := g.SetView("global", -1, -1, maxX, 2, 10); err != nil {
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||||
|
log("global failed", maxX, maxY)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
v.Frame = false
|
v.Frame = false
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if v, err := g.SetView("but1", 2, 2, 22, 7, 0); err != nil {
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
v.SelBgColor = gocui.ColorGreen
|
|
||||||
v.SelFgColor = gocui.ColorBlack
|
|
||||||
fmt.Fprintln(v, "Button 1 - line 1")
|
|
||||||
fmt.Fprintln(v, "Button 1 - line 2")
|
|
||||||
fmt.Fprintln(v, "Button 1 - line 3")
|
|
||||||
fmt.Fprintln(v, "Button 1 - line 4")
|
|
||||||
if _, err := g.SetCurrentView("but1"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
helplayout(g)
|
helplayout(g)
|
||||||
|
if widgetView, _ := g.View("msg"); widgetView == nil {
|
||||||
|
log(logInfo, "create output widget now", maxX, maxY, mx, my)
|
||||||
|
makeOutputWidget(g, "this is a create before a mouse click")
|
||||||
|
} else {
|
||||||
|
log(logInfo, "output widget already exists", maxX, maxY, mx, my)
|
||||||
|
}
|
||||||
updateHighlightedView(g)
|
updateHighlightedView(g)
|
||||||
|
log(logInfo, "layout() END", maxX, maxY, mx, my)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,16 +36,27 @@ func showMsg(g *gocui.Gui, v *gocui.View) error {
|
||||||
}
|
}
|
||||||
// setOutput(me.rootNode)
|
// setOutput(me.rootNode)
|
||||||
|
|
||||||
maxX, maxY := g.Size()
|
makeOutputWidget(g, l)
|
||||||
if v, err := g.SetView("msg", maxX/2, maxY/2, maxX/2+outputW, maxY/2+outputH, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
v.Clear()
|
|
||||||
v.SelBgColor = gocui.ColorCyan
|
|
||||||
v.SelFgColor = gocui.ColorBlack
|
|
||||||
l += "foo\n" + "bar\n"
|
|
||||||
fmt.Fprintln(v, l)
|
|
||||||
}
|
|
||||||
// g.SetViewOnTop("msg")
|
|
||||||
g.SetViewBeneath("msg", "help", 24)
|
|
||||||
// g.SetViewOnBottom("msg")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) {
|
||||||
|
maxX, maxY := g.Size()
|
||||||
|
v, err := g.SetView("msg", maxX-32, maxY/2, maxX/2+outputW, maxY/2+outputH, 0)
|
||||||
|
// help, err := g.SetView("help", maxX-32, 0, maxX-1, 13, 0)
|
||||||
|
if errors.Is(err, gocui.ErrUnknownView) {
|
||||||
|
log("this is supposed to happen?", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err != nil) {
|
||||||
|
log("create output window failed", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
v.Clear()
|
||||||
|
v.SelBgColor = gocui.ColorCyan
|
||||||
|
v.SelFgColor = gocui.ColorBlack
|
||||||
|
fmt.Fprintln(v, "figure out how to capture STDOUT to here\n" + stringFromMouseClick)
|
||||||
|
g.SetViewOnBottom("msg")
|
||||||
|
return
|
||||||
|
}
|
|
@ -10,6 +10,8 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
|
"strconv"
|
||||||
"sync"
|
"sync"
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
"git.wit.org/wit/gui/toolkit"
|
"git.wit.org/wit/gui/toolkit"
|
||||||
|
@ -37,12 +39,12 @@ type config struct {
|
||||||
defaultHeight int
|
defaultHeight int
|
||||||
// nextW int // where the next window or tab flag should go
|
// nextW int // where the next window or tab flag should go
|
||||||
|
|
||||||
padW int
|
padW int `default:"3" dense:"2"`
|
||||||
padH int
|
padH int
|
||||||
|
|
||||||
// where the raw corner is
|
// the raw beginning of each window (or tab)
|
||||||
rawW int
|
rawW int `default:"7"`
|
||||||
rawH int
|
rawH int `default:"3"`
|
||||||
|
|
||||||
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
||||||
canvas bool // if set to true, the windows are a raw canvas
|
canvas bool // if set to true, the windows are a raw canvas
|
||||||
|
@ -52,8 +54,8 @@ type config struct {
|
||||||
margin bool // add space around the frames of windows
|
margin bool // add space around the frames of windows
|
||||||
|
|
||||||
horizontalPadding int
|
horizontalPadding int
|
||||||
groupPadding int
|
groupPadding int `default:"6" dense:"2"` // this is supposed to be how far to indent to the left
|
||||||
buttonPadding int
|
buttonPadding int `default:"4" dense:"3"` // if 3, buttons slightly overlap
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -156,3 +158,43 @@ func (w *cuiWidget) Write(p []byte) (n int, err error) {
|
||||||
|
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Set(ptr interface{}, tag string) error {
|
||||||
|
if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
|
||||||
|
return fmt.Errorf("Not a pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
v := reflect.ValueOf(ptr).Elem()
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
if defaultVal := t.Field(i).Tag.Get(tag); defaultVal != "-" {
|
||||||
|
if err := setField(v.Field(i), defaultVal); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func setField(field reflect.Value, defaultVal string) error {
|
||||||
|
|
||||||
|
if !field.CanSet() {
|
||||||
|
log("Can't set value\n")
|
||||||
|
return fmt.Errorf("Can't set value\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch field.Kind() {
|
||||||
|
case reflect.Int:
|
||||||
|
if val, err := strconv.ParseInt(defaultVal, 1, 64); err == nil {
|
||||||
|
field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
|
||||||
|
}
|
||||||
|
case reflect.String:
|
||||||
|
field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
|
||||||
|
case reflect.Bool:
|
||||||
|
field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue