reorg to final resting place at go.wit.com/gui/gui

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2024-01-01 15:43:50 -06:00
parent 3c26b3843f
commit d1d9c20168
108 changed files with 86 additions and 6188 deletions

2
box.go
View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewBox(name string, b bool) *Node {

View File

@ -1,6 +1,6 @@
package gui
import "go.wit.com/gui/toolkit"
import "go.wit.com/gui/gui/toolkit"
func (parent *Node) NewButton(name string, custom func()) *Node {
newNode := parent.newNode(name, toolkit.Button)

View File

@ -1,6 +1,6 @@
package gui
import "go.wit.com/gui/toolkit"
import "go.wit.com/gui/gui/toolkit"
func (n *Node) Checked() bool {
return n.B

View File

@ -4,7 +4,7 @@ package gui
import (
"regexp"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
newlog "go.wit.com/log"
)

View File

@ -5,7 +5,7 @@ package gui
import (
"strconv"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// various debugging flags
@ -159,9 +159,9 @@ func (n *Node) ListChildren(dump bool) {
if (listChildrenParent != nil) {
log(debugNode, "\t\t\tlistChildrenParent =",listChildrenParent.id)
if (listChildrenParent.id != n.parent.id) {
log("parent =",n.parent.id, n.parent.Name)
log("listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
log(listChildrenParent.id, "!=", n.parent.id)
log(true, "parent =",n.parent.id, n.parent.Name)
log(true, "listChildrenParent =",listChildrenParent.id, listChildrenParent.Name)
log(true, listChildrenParent.id, "!=", n.parent.id)
exit("parent.child does not match child.parent")
}
}

View File

@ -67,18 +67,22 @@ func (n *Node) DebugFlags() {
for _, lf := range logGadgets {
lf.Set(true)
}
newlog.All(true)
})
g.NewButton("log.All(false)", func () {
for _, lf := range logGadgets {
lf.Set(false)
}
newlog.All(false)
})
g.NewButton("Dump Flags", func () {
ShowDebugValues()
// ShowDebugValues()
newlog.ListFlags()
})
/*
g.NewButton("All On", func () {
SetDebug(true)
})
@ -86,6 +90,7 @@ func (n *Node) DebugFlags() {
g.NewButton("All Off", func () {
SetDebug(false)
})
*/
g = w.NewGroup("List")
g = g.NewGrid("flags grid", 2, 2)

View File

@ -22,10 +22,10 @@ func (n *Node) DebugGoChannels() {
// var debugWG sync.WaitGroup
g.NewButton("init()", func () {
if (debugNumberChan == nil) {
log("making debugNumberChan channel")
log(true, "making debugNumberChan channel")
debugNumberChan = make(chan int)
} else {
log("debugNumberChan already made")
log(true, "debugNumberChan already made")
}
debugWG = new(sync.WaitGroup)
})
@ -46,32 +46,32 @@ func (n *Node) DebugGoChannels() {
go sendNumber(7)
})
g.NewButton("send 4 numbers (chan <- int)", func () {
log("generateNumbers(4)")
log(true, "generateNumbers(4)")
go generateNumbers(4)
})
g.NewButton("debugWG.Done()", func () {
log("ran debugWG.Done()")
log(true, "ran debugWG.Done()")
debugWG.Done()
})
g.NewButton("close chan", func () {
log("close() on", debugNumberChan)
log(true, "close() on", debugNumberChan)
close(debugNumberChan)
})
g.NewButton("print", func () {
log("waitgroup counter is ?")
log(true, "waitgroup counter is ?")
})
}
func sendNumber(i int) {
log("START debugNumberChan <-", i, " (sending", i, "to channel)")
log(true, "START debugNumberChan <-", i, " (sending", i, "to channel)")
debugNumberChan <- i
debugWG.Wait()
log("END debugNumberChan sendNumber() done", i)
log(true, "END debugNumberChan sendNumber() done", i)
}
func generateNumbers(total int) {
fmt.Printf("START generateNumbers()\n")
for idx := 1; idx <= total; idx++ {
log("ran debugNumberChan <= idx where idx =", idx)
log(true, "ran debugNumberChan <= idx where idx =", idx)
fmt.Printf("S generateNumbers() sending %d to channel\n", idx)
debugNumberChan <- idx
// res, err := (<-r)()
@ -84,9 +84,9 @@ func generateNumbers(total int) {
// i equals the number of times to read values from the channel
func printInt(i int, name string) {
tmp := 1
log("START printInt", name, "read debugNumberChan()")
log(true, "START printInt", name, "read debugNumberChan()")
for num := range debugNumberChan {
log("printInt()",name, "read", num, "from channel")
log(true, "printInt()",name, "read", num, "from channel")
debugWG.Done()
if (tmp == i) {
return

View File

@ -69,7 +69,7 @@ func (n *Node) DebugGolangWindow() {
var tmp debug.GCStats
var out string
debug.ReadGCStats(&tmp)
log(tmp)
log(true, tmp)
out += fmt.Sprintln("LastGC:", tmp.LastGC, "// time.Time time of last collection")
out += fmt.Sprintln("NumGC:", tmp.NumGC, "// number of garbage collections")
out += fmt.Sprintln("PauseTotal:", tmp.PauseTotal, "// total pause for all collections")
@ -121,7 +121,7 @@ func (n *Node) DebugGolangWindow() {
og = w.NewGroup("output")
outputTextbox = og.NewTextbox("outputBox")
outputTextbox.Custom = func () {
log("custom TextBox() for golang output a =", outputTextbox.S, outputTextbox.id)
log(true, "custom TextBox() for golang output a =", outputTextbox.S, outputTextbox.id)
}
}

View File

@ -2,7 +2,7 @@ package gui
import (
"strconv"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
@ -165,7 +165,7 @@ func (n *Node) debugAddWidgetButtons() {
a.AddText("make something for tim for qflow")
a.AddText("and for riscv")
a.Custom = func () {
log("custom dropdown() a =", a.Name, a.S, "id=", a.id)
log(true, "custom dropdown() a =", a.Name, a.S, "id=", a.id)
}
})
n.NewButton("Combobox", func () {
@ -173,7 +173,7 @@ func (n *Node) debugAddWidgetButtons() {
a.AddText("mirrors.wit.com")
a.AddText("go.wit.com")
a.Custom = func () {
log("custom combobox() a =", a.Name, a.S, "id=", a.id)
log(true, "custom combobox() a =", a.Name, a.S, "id=", a.id)
}
})
n.NewButton("Grid", func () {
@ -247,12 +247,12 @@ func (n *Node) debugAddWidgetButton() {
activeWidget.SetNext(newX, newY)
name = name + " (" + strconv.Itoa(newX) + "," + strconv.Itoa(newY) + ")"
}
log("New Name =", name)
log("New Type =", activeLabelNewType.S)
log("New X =", newX)
log("New Y =", newY)
log("activeWidget.NextW =", activeWidget.NextW)
log("activeWidget.NextH =", activeWidget.NextH)
log(true, "New Name =", name)
log(true, "New Type =", activeLabelNewType.S)
log(true, "New X =", newX)
log(true, "New Y =", newY)
log(true, "activeWidget.NextW =", activeWidget.NextW)
log(true, "activeWidget.NextH =", activeWidget.NextH)
log(debugNow, "Add() size (X,Y)", activeWidget.X, activeWidget.Y, "put next thing at (W,H) =", activeWidget.NextW, activeWidget.NextH)
activeWidget.Dump()
@ -269,19 +269,19 @@ func (n *Node) debugAddWidgetButton() {
case "Button":
var n *Node
n = activeWidget.NewButton(name, func () {
log("got to button", name, n.id)
log(true, "got to button", name, n.id)
})
case "Checkbox":
a := activeWidget.NewCheckbox(name)
a.Custom = func () {
log("custom checkox func a=", a.B, "id=", a.id)
log(true, "custom checkox func a=", a.B, "id=", a.id)
}
case "Dropdown":
a := activeWidget.NewDropdown(name)
a.AddText(name + " yay")
a.AddText(name + " haha")
a.Custom = func () {
log("WTF a=", a.B, "id=", a.id)
log(true, "WTF a=", a.B, "id=", a.id)
}
case "Combobox":
a := activeWidget.NewCombobox(name)

View File

@ -16,10 +16,15 @@ var myButton *Node
/*
Creates a window helpful for debugging this package
*/
func (n *Node) DebugWindow() {
newlog.Warn("Don't use DebugWindow() directly anymore")
DebugWindow() // todo, remove the non-binary tree access
}
func DebugWindow() {
bugWin = me.rootNode.NewWindow("go.wit.com/gui debug window").DebugTab("Debug Tab")
bugWin.Custom = bugWin.StandardClose
if newlog.ArgDebug() {
if ArgDebug() {
newlog.SetTmp()
bugWin.DebugFlags()
}
@ -102,7 +107,7 @@ func (n *Node) DebugTab(title string) *Node {
g2.NewButton("List Plugins", func () {
for _, aplug := range allPlugins {
log("Loaded plugin:", aplug.name, aplug.filename)
log(true, "Loaded plugin:", aplug.name, aplug.filename)
}
})

View File

@ -6,7 +6,7 @@ package gui
// since it is the same. confusing names? maybe...
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// add a new entry to the dropdown name

View File

@ -1,29 +0,0 @@
# with andlabs plugin loaded:
# PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
# 180006 jcarr 20 0 1918460 41688 31152 S 0.7 0.3 0:00.27 buttonplugin
# with gocui plugin loaded:
# 180365 jcarr 20 0 1392668 24364 12596 S 2.0 0.2 0:00.09 buttonplugin
#
run: build
./buttons
debug:
./buttons --gui andlabs --gui-debug --log-debug
build-release:
go get -v -u -x .
go build
./buttons
build:
GO111MODULE="off" go get -v -x .
GO111MODULE="off" go build
update:
GO111MODULE="off" go get -v -u -x .
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

View File

@ -1,89 +0,0 @@
// This is a simple example
package main
import (
"log"
"strconv"
"go.wit.com/gui"
arg "github.com/alexflint/go-arg"
)
var title string = "Demo Plugin Window"
var myGui *gui.Node
var buttonCounter int = 5
var gridW int = 5
var gridH int = 3
func init() {
arg.MustParse()
}
func main() {
// This will turn on all debugging
// gui.SetDebug(true)
myGui = gui.New().Default()
buttonWindow()
// This is just a optional goroutine to watch that things are alive
gui.Watchdog()
gui.StandardExit()
}
// This creates a window
func buttonWindow() {
var w, t, g, more, more2 *gui.Node
log.Println("buttonWindow() START")
w = myGui.NewWindow(title).SetText("Nueva Ventana de Botones")
t = w.NewTab("buttonTab is this thing").Pad()
g = t.NewGroup("buttonGroup").Pad()
g1 := t.NewGroup("buttonGroup 2").Pad()
more = g1.NewGroup("more").Pad()
g1.NewButton("hello2", func () {
log.Println("world2")
})
more2 = g1.NewGrid("gridnuts", gridW, gridH).Pad()
more2.NewLabel("more2")
g.NewButton("hello", func () {
log.Println("world")
})
g.NewButton("NewButton(more)", func () {
name := "foobar " + strconv.Itoa(buttonCounter)
log.Println("NewButton(more) Adding button", name)
buttonCounter += 1
more.NewButton(name, func () {
log.Println("Got all the way to main() name =", name)
})
})
g.NewButton("NewButton(more2)", func () {
name := "foobar " + strconv.Itoa(buttonCounter)
log.Println("NewButton(more2) Adding button", name)
buttonCounter += 1
more2.NewButton(name, func () {
log.Println("Got all the way to main() name =", name)
})
})
g.NewButton("NewButton(more2 d)", func () {
name := "d" + strconv.Itoa(buttonCounter)
log.Println("NewButton(more2 d) Adding button", name)
buttonCounter += 1
more2.NewButton(name, func () {
log.Println("Got all the way to main() name =", name)
})
})
g.NewButton("NewGroup()", func () {
name := "neat " + strconv.Itoa(buttonCounter)
log.Println("NewGroup() Adding button", name)
buttonCounter += 1
more.NewGroup(name).Pad()
})
}

View File

@ -1,15 +0,0 @@
run: build
./console-ui-helloworld
reset
ldd ./console-ui-helloworld
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 .

View File

@ -1,130 +0,0 @@
// 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())
// 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
}

View File

@ -1,35 +0,0 @@
// 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")
}

View File

@ -1,83 +0,0 @@
// 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")
addGroup("blank")
addButton("world")
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
}

View File

@ -1,46 +0,0 @@
// 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
}

View File

@ -1,114 +0,0 @@
// 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
}

View File

@ -1,45 +0,0 @@
/*
* Copyright (c) 2013-2016 Dave Collins <dave@davec.name>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
package gui_test
import (
"go.wit.com/gui"
)
// This example demonstrates how to create a NewWindow()
//
// Interacting with a GUI in a cross platform fashion adds some
// unusual problems. To obvuscate those, andlabs/ui starts a
// goroutine that interacts with the native gui toolkits
// on the Linux, MacOS, Windows, etc.
//
// Because of this oddity, to initialize a new window, the
// function is not passed any arguements and instead passes
// the information via the Config type.
//
func ExampleNewWindow() {
// Define the name and size
gui.Config.Title = "WIT GUI Window 1"
gui.Config.Width = 640
gui.Config.Height = 480
// Create the Window
gui.NewWindow()
// Output:
// You get a window
}

View File

@ -1,14 +0,0 @@
run: build
./helloworld
build-release:
go get -v -u -x .
go build
./helloworld
build:
GO111MODULE="off" go get -v -x .
GO111MODULE="off" go build
update:
GO111MODULE="off" go get -v -u -x .

View File

@ -1,23 +0,0 @@
// This is a simple example
package main
import (
"log"
"go.wit.com/gui"
)
func main() {
helloworld()
// This is just a optional goroutine to watch that things are alive
gui.Watchdog()
}
// This creates a window
func helloworld() {
myGui := gui.New().Default()
myWindow := myGui.NewWindow("helloworld golang wit/gui window")
myWindow.NewButton("hello", func () {
log.Println("world")
})
}

View File

@ -1,15 +0,0 @@
# gadgets
Package gadgets are special collections of widgets
Things to avoid or keep in mind: Also Features these might enable:
```go
* These should never bypass the binary tree
* Hide complexity internally here
* These might require corresponding toolkit implementations?
* These might allow unique/good corresponding toolkit implementations (date/time selection?)
## Warning
Doing this / adding these might be a really bad idea that I will regret later

View File

@ -1,79 +0,0 @@
/*
A Labeled Combobox widget:
-----------------------------
| | |
| Food: | <dropdown> |
| | |
-----------------------------
The user can then edit the dropdown field and type anything into it
*/
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
type BasicCombobox struct {
ready bool
name string
parent *gui.Node // parent widget
l *gui.Node // label widget
d *gui.Node // dropdown widget
value string
label string
Custom func()
}
func (d *BasicCombobox) Get() string {
if ! d.Ready() {return ""}
return d.value
}
// Returns true if the status is valid
func (d *BasicCombobox) Ready() bool {
if d == nil {return false}
return d.ready
}
func (d *BasicCombobox) Add(value string) {
if ! d.Ready() {return}
log.Println("BasicCombobox.Add() =", value)
d.d.AddDropdownName(value)
return
}
func (d *BasicCombobox) Set(value string) bool {
if ! d.Ready() {return false}
log.Println("BasicCombobox.Set() =", value)
d.d.SetText(value)
d.value = value
return true
}
func NewBasicCombobox(p *gui.Node, name string) *BasicCombobox {
d := BasicCombobox {
parent: p,
name: name,
ready: false,
}
// various timeout settings
d.l = p.NewLabel(name)
d.d = p.NewCombobox("")
d.d.Custom = func() {
d.value = d.Get()
log.Println("BasicCombobox.Custom() user changed value to =", d.value)
if d.Custom != nil {
d.Custom()
}
}
d.ready = true
return &d
}

View File

@ -1,79 +0,0 @@
/*
A Labeled Dropdown widget:
-----------------------------
| | |
| Food: | <dropdown> |
| | |
-----------------------------
This being a 'Basic Dropdown', the dropdown names must be unique
*/
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
type BasicDropdown struct {
ready bool
name string
parent *gui.Node // parent widget
l *gui.Node // label widget
d *gui.Node // dropdown widget
value string
label string
Custom func()
}
func (d *BasicDropdown) Get() string {
if ! d.Ready() {return ""}
return d.d.GetText()
}
// Returns true if the status is valid
func (d *BasicDropdown) Ready() bool {
if d == nil {return false}
return d.ready
}
func (d *BasicDropdown) Add(value string) {
if ! d.Ready() {return}
log.Println("BasicDropdown.Set() =", value)
d.d.AddDropdownName(value)
return
}
func (d *BasicDropdown) Set(value string) bool {
if ! d.Ready() {return false}
log.Println("BasicDropdown.Set() =", value)
d.l.SetText(value)
d.value = value
return true
}
func NewBasicDropdown(p *gui.Node, name string) *BasicDropdown {
d := BasicDropdown {
parent: p,
name: name,
ready: false,
}
// various timeout settings
d.l = p.NewLabel(name)
d.d = p.NewDropdown("")
d.d.Custom = func() {
d.value = d.Get()
log.Println("BasicDropdown.Custom() user changed value to =", d.value)
if d.Custom != nil {
d.Custom()
}
}
d.ready = true
return &d
}

View File

@ -1,56 +0,0 @@
/*
A Labeled Single Line Entry widget:
-----------------------------
| | |
| Food: | <type here> |
| | |
-----------------------------
*/
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
type BasicEntry struct {
parent *gui.Node // parent widget
l *gui.Node // label widget
v *gui.Node // value widget
value string
label string
Custom func()
}
func (n *BasicEntry) Get() string {
return n.value
}
func (n *BasicEntry) Set(value string) *BasicEntry {
log.Println("BasicEntry.Set() =", value)
if (n.v != nil) {
n.v.Set(value)
}
n.value = value
return n
}
func NewBasicEntry(p *gui.Node, name string) *BasicEntry {
d := BasicEntry {
parent: p,
value: "",
}
// various timeout settings
d.l = p.NewLabel(name)
d.v = p.NewEntryLine("")
d.v.Custom = func() {
d.value = d.v.S
log.Println("BasicEntry.Custom() user changed value to =", d.value)
}
return &d
}

View File

@ -1,60 +0,0 @@
/*
A Labeled label:
-----------------------------
| | |
| Food: | Apple |
| | |
-----------------------------
*/
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
type Node gui.Node
type BasicLabel struct {
p *gui.Node // parent widget
l *gui.Node // label widget
v *gui.Node // value widget
value string
label string
Custom func()
}
func (n *BasicLabel) Get() string {
return n.value
}
func (n *BasicLabel) Set(value string) *BasicLabel {
log.Println("BasicLabel.Set() =", value)
if (n.v != nil) {
n.v.Set(value)
}
n.value = value
return n
}
func (ngui *Node) NewBasicLabel(name string) *BasicLabel {
var n *gui.Node
n = (*gui.Node)(ngui)
d := BasicLabel {
p: n,
value: "",
}
// various timeout settings
d.l = n.NewLabel(name)
d.v = n.NewLabel("")
d.v.Custom = func() {
d.value = d.v.S
log.Println("BasicLabel.Custom() user changed value to =", d.value)
}
return &d
}

View File

@ -1,79 +0,0 @@
/*
A slider that goes between a High and Low time
*/
package gadgets
import (
"log"
"fmt"
"time"
"go.wit.com/gui"
)
type Duration struct {
p *gui.Node // parent widget
l *gui.Node // label widget
s *gui.Node // slider widget
Label string
Low time.Duration
High time.Duration
Duration time.Duration
Custom func()
}
func (n *Duration) Set(d time.Duration) {
var timeRange, step, offset time.Duration
if (d > n.High) {
d = n.High
}
if (d < n.Low) {
d = n.Low
}
// set the duration
n.Duration = d
// figure out the integer offset for the Slider GUI Widget
timeRange = n.High - n.Low
step = timeRange / 1000
if (step == 0) {
log.Println("duration.Set() division by step == 0", n.Low, n.High, timeRange, step)
n.s.Set(0)
return
}
offset = d - n.Low
i := int(offset / step)
log.Println("duration.Set() =", n.Low, n.High, d, "i =", i)
n.s.I = i
n.s.Set(i)
n.s.Custom()
}
func NewDurationSlider(n *gui.Node, label string, low time.Duration, high time.Duration) *Duration {
d := Duration {
p: n,
Label: label,
High: high,
Low: low,
}
// various timeout settings
d.l = n.NewLabel(label)
d.s = n.NewSlider(label, 0, 1000)
d.s.Custom = func () {
d.Duration = low + (high - low) * time.Duration(d.s.I) / 1000
log.Println("d.Duration =", d.Duration)
s := fmt.Sprintf("%s (%v)", d.Label, d.Duration)
d.l.SetText(s)
if (d.Custom != nil) {
d.Custom()
}
}
return &d
}

View File

@ -1,72 +0,0 @@
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
var myLogGui *LogSettings
type LogSettings struct {
ready bool
hidden bool
err error
parent *gui.Node // should be the root of the 'gui' package binary tree
window *gui.Node // our window for displaying the log package settings
group *gui.Node //
grid *gui.Node //
// Primary Directives
status *OneLiner
summary *OneLiner
}
// This is initializes the main DO object
// You can only have one of these
func NewLogSettings(p *gui.Node) *LogSettings {
if myLogGui != nil {return myLogGui}
myLogGui = new(LogSettings)
myLogGui.parent = p
myLogGui.ready = false
myLogGui.window = p.NewWindow("Log Settings")
// make a group label and a grid
myLogGui.group = myLogGui.window.NewGroup("droplets:").Pad()
myLogGui.grid = myLogGui.group.NewGrid("grid", 2, 1).Pad()
myLogGui.ready = true
myLogGui.Hide()
return myLogGui
}
// Returns true if the status is valid
func (d *LogSettings) Ready() bool {
if d == nil {return false}
return d.ready
}
func (d *LogSettings) Show() {
if ! d.Ready() {return}
log.Info("LogSettings.Show() window")
if d.hidden {
d.window.Show()
}
d.hidden = false
}
func (d *LogSettings) Hide() {
if ! d.Ready() {return}
log.Info("LogSettings.Hide() window")
if ! d.hidden {
d.window.Hide()
}
d.hidden = true
}
func (d *LogSettings) Update() bool {
if ! d.Ready() {return false}
return true
}

View File

@ -1,56 +0,0 @@
/*
A Labeled label:
-----------------------------
| | |
| Food: | Apple |
| | |
-----------------------------
*/
package gadgets
import (
"go.wit.com/log"
"go.wit.com/gui"
)
type OneLiner struct {
p *gui.Node // parent widget
l *gui.Node // label widget
v *gui.Node // value widget
value string
label string
Custom func()
}
func (n *OneLiner) Get() string {
return n.value
}
func (n *OneLiner) Set(value string) *OneLiner {
log.Println("OneLiner.Set() =", value)
if (n.v != nil) {
n.v.Set(value)
}
n.value = value
return n
}
func NewOneLiner(n *gui.Node, name string) *OneLiner {
d := OneLiner {
p: n,
value: "",
}
// various timeout settings
d.l = n.NewLabel(name)
d.v = n.NewLabel("")
d.v.Custom = func() {
d.value = d.v.S
log.Println("OneLiner.Custom() user changed value to =", d.value)
}
return &d
}

14
go.mod
View File

@ -4,23 +4,13 @@ go 1.21.4
require (
github.com/alexflint/go-arg v1.4.3
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e
github.com/awesome-gocui/gocui v1.1.0
github.com/golang/protobuf v1.5.3
github.com/sourcegraph/conc v0.3.0
go.wit.com/log v0.0.0-20240101060000-bf41970f7793
)
require (
github.com/alexflint/go-scalar v1.1.0 // indirect
github.com/gdamore/encoding v1.0.0 // indirect
github.com/gdamore/tcell/v2 v2.4.0 // indirect
github.com/lucasb-eyer/go-colorful v1.0.3 // indirect
github.com/mattn/go-runewidth v0.0.10 // indirect
github.com/rivo/uniseg v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
go.uber.org/atomic v1.7.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 // indirect
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf // indirect
golang.org/x/text v0.3.3 // indirect
google.golang.org/protobuf v1.26.0 // indirect
)

34
go.sum
View File

@ -2,30 +2,11 @@ github.com/alexflint/go-arg v1.4.3 h1:9rwwEBpMXfKQKceuZfYcwuc/7YY7tWJbFsgG5cAU/u
github.com/alexflint/go-arg v1.4.3/go.mod h1:3PZ/wp/8HuqRZMUUgu7I+e1qcpUbvmS258mRXkFH4IA=
github.com/alexflint/go-scalar v1.1.0 h1:aaAouLLzI9TChcPXotr6gUhq+Scr8rl0P9P4PnltbhM=
github.com/alexflint/go-scalar v1.1.0/go.mod h1:LoFvNMqS1CPrMVltza4LvnGKhaSpc3oyLEBUZVhhS2o=
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e h1:wSQCJiig/QkoUnpvelSPbLiZNWvh2yMqQTQvIQqSUkU=
github.com/andlabs/ui v0.0.0-20200610043537-70a69d6ae31e/go.mod h1:5G2EjwzgZUPnnReoKvPWVneT8APYbyKkihDVAHUi0II=
github.com/awesome-gocui/gocui v1.1.0 h1:db2j7yFEoHZjpQFeE2xqiatS8bm1lO3THeLwE6MzOII=
github.com/awesome-gocui/gocui v1.1.0/go.mod h1:M2BXkrp7PR97CKnPRT7Rk0+rtswChPtksw/vRAESGpg=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
github.com/gdamore/tcell/v2 v2.4.0 h1:W6dxJEmaxYvhICFoTY3WrLLEXsQ11SaFnKGVEXW57KM=
github.com/gdamore/tcell/v2 v2.4.0/go.mod h1:cTTuF84Dlj/RqmaCIV5p4w8uG1zWdk0SF6oBpwHp4fU=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/lucasb-eyer/go-colorful v1.0.3 h1:QIbQXiugsb+q10B+MI+7DI1oQLdmnep86tWFlaaUAac=
github.com/lucasb-eyer/go-colorful v1.0.3/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-runewidth v0.0.10 h1:CoZ3S2P7pvtP45xOtBw+/mDL2z0RKI576gSkzRRpdGg=
github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY=
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -38,19 +19,8 @@ go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf h1:MZ2shdL+ZM/XzY3ZGOnh4Nlpnxz5GSOhOmtHo3iPU6M=
golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
go.wit.com/log v0.0.0-20240101060000-bf41970f7793 h1:kLs+rU96k6b48DqpkO4n3yDZ8hjiVnYjzPSEHU+93aY=
go.wit.com/log v0.0.0-20240101060000-bf41970f7793/go.mod h1:uXgfF8oPx5KYhtNZel6gsFYPMr9+z6sav5lSws1mN6A=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// Grid numbering examples (H) or (W,H)

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// TODO: make a "Group" a "Grid" ?

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewImage(name string) *Node {

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewLabel(text string) *Node {

10
log.go
View File

@ -1,7 +1,7 @@
package gui
import (
witlog "go.wit.com/gui/log"
witlog "go.wit.com/log"
)
// various debugging flags
@ -13,9 +13,9 @@ var logVerbose bool = false
// var log interface{}
func log(a ...any) {
witlog.Where = "wit/gui"
witlog.Log(a...)
func log(b bool, a ...any) {
// witlog.Where = "wit/gui"
witlog.Log(b, a...)
}
func sleep(a ...any) {
@ -39,5 +39,5 @@ func logindent(b bool, depth int, format string, a ...any) {
// array prepend(). Why isn't this a standard function. It should be:
// a.prepend(debugGui, newFormat)
a = append([]any{b, newFormat}, a...)
witlog.Log(a...)
witlog.Log(b, a...)
}

10
main.go
View File

@ -3,7 +3,7 @@ package gui
import (
"os"
"time"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// TODO: make a fake 'plugin' channel of communication to andlabs for mswindows
@ -15,7 +15,7 @@ const Xaxis = 0 // stack things horizontally
const Yaxis = 1 // stack things vertically
func init() {
log("init() has been run")
log(true, "init() has been run")
me.counter = 0
me.prefix = "wit"
@ -175,10 +175,10 @@ func (n *Node) StandardClose() {
// The window is destroyed and the application exits
// TODO: properly exit the plugin since Quit() doesn't do it
func StandardExit() {
log("wit/gui Standard Window Exit. running os.Exit()")
log("StandardExit() attempt to exit each toolkit plugin")
log(true, "wit/gui Standard Window Exit. running os.Exit()")
log(true, "StandardExit() attempt to exit each toolkit plugin")
for i, plug := range allPlugins {
log("NewButton()", i, plug)
log(true, "NewButton()", i, plug)
}
exit(0)
}

View File

@ -1,6 +1,6 @@
package gui
import "go.wit.com/gui/toolkit"
import "go.wit.com/gui/gui/toolkit"
/*
generic function to create a new node on the binary tree

View File

@ -10,7 +10,7 @@ import (
"embed"
"plugin"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
var err error
@ -143,7 +143,18 @@ func searchPaths(name string) *aplug {
if err != nil {
log(logError, "searchPaths() error. exiting here?")
} else {
filename = homeDir + "/go/src/go.wit.com/gui/toolkit/" + name + ".so"
filename = homeDir + "/go/src/go.wit.com/gui/toolkits/" + name + ".so"
p = initToolkit(name, filename)
if (p != nil) {
return p
}
}
homeDir, err = os.UserHomeDir()
if err != nil {
log(logError, "searchPaths() error. exiting here?")
} else {
filename = homeDir + "/go/src/go.wit.com/toolkits/" + name + ".so"
p = initToolkit(name, filename)
if (p != nil) {
return p

View File

@ -1,34 +0,0 @@
all:
# You must use the current protoc-gen-go
# protoc --version 3.6++ does not mean that protoc will generate version3 .go files
#
# apt remove golang-goprotobuf-dev
# apt install protobuf-compiler
#
# Then:
# go get -u github.com/golang/protobuf/protoc-gen-go
# cd ~/go/src/github.com/golang/protobuf/protoc-gen-go
# go install
#
# Then:
protoc --version
make widget.pb.go
clean:
rm -f *.pb.go
widget.pb.go: widget.proto
protoc --go_out=. widget.proto
compile:
protoc --go_out=. *.proto
deps:
apt install golang-goprotobuf-dev
apt install protobuf-compiler
push:
git pull
git add --all
git commit -a -s
git push

View File

@ -1,117 +0,0 @@
syntax = "proto3";
package guiProtobuf;
message Action {
WidgetType widgetType = 1;
ActionType actionType = 2;
int64 widgetId = 3;
int64 parentId = 4;
string text = 5; // what is visable to the user
string name = 6; // a name useful for programming
// This is how the values are passed back and forth
// values from things like checkboxes & dropdown's
bool b = 7;
int64 i = 8;
string s = 9;
// This is used for things like a slider(0,100)
int64 x = 10;
int64 y = 11;
// This is for the grid size & widget position
int64 w = 12;
int64 h = 13;
int64 atw = 14;
int64 ath = 15;
bool margin = 16; // Put space around elements to improve look & feel
bool expand = 17; // Make widgets fill up the space available
repeated Response results = 18;
repeated Network networks = 19;
repeated VM vms = 20;
enum WidgetType {
Unknown = 0;
Root = 1; // the master 'root' node of the binary tree
Flag = 2; // used to send configuration values to plugins
Window = 3; // in certain gui's (ncurses), these are tabs
Tab = 4; // internally, this is a window
Frame = 5; // deprecate?
Grid = 6; // like drawers in a chest
Group = 7; // like the 'Appetizers' section on a menu
Box = 8; // a vertical or horizontal stack of widgets
Button = 9;
Checkbox = 10; // select 'on' or 'off'
Dropdown = 11;
Combobox = 12; // dropdown with edit=true
Label = 13;
Textbox = 14; // is this a Label with edit=true
Slider = 15; // like a progress bar
Spinner = 16; // like setting the oven temperature
Separator = 17; // TODO
Image = 18; // TODO
Area = 19; // TODO
Form = 20; // TODO
Font = 21; // TODO
Color = 22; // TODO
Dialog = 23; // TODO
Stdout = 24; // can be used to capture and display log output
}
enum ActionType {
Health = 0;
Add = 1;
Delete = 2;
Get = 3;
Set = 4;
GetText = 5;
SetText = 6;
AddText = 7;
Show = 8;
Hide = 9;
Enable = 10;
Disable = 11;
Margin = 12;
Unmargin = 13;
Pad = 14;
Unpad = 15;
Append = 16;
Move = 17;
Dump = 18;
User = 19; // the user did something (mouse, keyboard, etc)
InitToolkit = 20; // initializes the toolkit
CloseToolkit = 21; // closes the toolkit
UserQuit = 22; // the user closed the GUI
EnableDebug = 23; // open the debugging window
}
message Response {
// ActionType type = 1;
int64 id = 2;
string name = 3;
string error = 4;
repeated string snippets = 5;
}
message Network {
int64 id = 1;
string name = 2;
int64 total_cpu = 3;
int64 total_mem = 4;
string login_url = 5;
}
message VM {
int64 id = 1;
string name = 2;
string hostname = 3;
int64 cpus = 4;
int64 memory = 5;
int64 disk = 6;
string IPv6 = 7;
string role = 8;
string baseImage = 9;
}
}

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// This recreates the whole GUI for a plugin

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewSlider(name string, x int, y int) *Node {

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewSpinner(name string, x int, y int) *Node {

View File

@ -3,7 +3,7 @@ package gui
import (
"sync"
"embed"
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
//

2
tab.go
View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
// This function should make a new node with the parent and

View File

@ -1,7 +1,7 @@
package gui
import (
"go.wit.com/gui/toolkit"
"go.wit.com/gui/gui/toolkit"
)
func (parent *Node) NewTextbox(name string) *Node {

View File

@ -1,7 +0,0 @@
all: plugin
plugin:
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../andlabs.so
goget:
GO111MODULE="off" go get -v -t -u

View File

@ -1,265 +0,0 @@
package main
import (
"strconv"
"github.com/andlabs/ui"
"go.wit.com/gui/toolkit"
)
func (n *node) show(b bool) {
if n.tk == nil {
return
}
if n.tk.uiControl == nil {
return
}
if (b) {
n.tk.uiControl.Show()
} else {
n.tk.uiControl.Hide()
}
}
func (n *node) enable(b bool) {
if n == nil {
panic("WHAT? enable was passed nil. How does this even happen?")
}
if n.tk == nil {
return
}
if n.tk.uiControl == nil {
return
}
if (b) {
n.tk.uiControl.Enable()
} else {
n.tk.uiControl.Disable()
}
}
func (n *node) pad(at toolkit.ActionType) {
log(logInfo, "pad() on WidgetId =", n.WidgetId)
t := n.tk
if (t == nil) {
log(logError, "pad() toolkit struct == nil. for", n.WidgetId)
return
}
switch n.WidgetType {
case toolkit.Group:
switch at {
case toolkit.Margin:
t.uiGroup.SetMargined(true)
case toolkit.Unmargin:
t.uiGroup.SetMargined(false)
case toolkit.Pad:
t.uiGroup.SetMargined(true)
case toolkit.Unpad:
t.uiGroup.SetMargined(false)
}
case toolkit.Tab:
switch at {
case toolkit.Margin:
tabSetMargined(t.uiTab, true)
case toolkit.Unmargin:
tabSetMargined(t.uiTab, false)
case toolkit.Pad:
tabSetMargined(t.uiTab, true)
case toolkit.Unpad:
tabSetMargined(t.uiTab, false)
}
case toolkit.Window:
switch at {
case toolkit.Margin:
t.uiWindow.SetMargined(true)
case toolkit.Unmargin:
t.uiWindow.SetMargined(false)
case toolkit.Pad:
t.uiWindow.SetBorderless(false)
case toolkit.Unpad:
t.uiWindow.SetBorderless(true)
}
case toolkit.Grid:
switch at {
case toolkit.Margin:
t.uiGrid.SetPadded(true)
case toolkit.Unmargin:
t.uiGrid.SetPadded(false)
case toolkit.Pad:
t.uiGrid.SetPadded(true)
case toolkit.Unpad:
t.uiGrid.SetPadded(false)
}
case toolkit.Box:
switch at {
case toolkit.Margin:
t.uiBox.SetPadded(true)
case toolkit.Unmargin:
t.uiBox.SetPadded(false)
case toolkit.Pad:
t.uiBox.SetPadded(true)
case toolkit.Unpad:
t.uiBox.SetPadded(false)
}
case toolkit.Textbox:
log(debugError, "TODO: implement ActionType =", at)
default:
log(debugError, "TODO: implement pad() for", at)
}
}
func (n *node) move(newParent *node) {
p := n.parent
switch p.WidgetType {
case toolkit.Group:
case toolkit.Tab:
// tabSetMargined(tParent.uiTab, true)
case toolkit.Window:
// t.uiWindow.SetBorderless(false)
case toolkit.Grid:
// t.uiGrid.SetPadded(true)
case toolkit.Box:
log(logInfo, "TODO: move() where =", p.ParentId)
log(logInfo, "TODO: move() for widget =", n.WidgetId)
stretchy = true
if (p.tk.uiBox != nil) {
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
}
// log(debugNow, "is there a tParent parent? =", tParent.parent)
// tParent.uiBox.Delete(0)
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
default:
log(logError, "TODO: need to implement move() for type =", n.WidgetType)
log(logError, "TODO: need to implement move() for where =", p.ParentId)
log(logError, "TODO: need to implement move() for widget =", n.WidgetId)
}
}
func (n *node) Delete() {
p := n.parent
log(debugNow, "uiDelete()", n.WidgetId, "to", p.WidgetId)
switch p.WidgetType {
case toolkit.Group:
// tParent.uiGroup.SetMargined(true)
case toolkit.Tab:
// tabSetMargined(tParent.uiTab, true)
case toolkit.Window:
// t.uiWindow.SetBorderless(false)
case toolkit.Grid:
// t.uiGrid.SetPadded(true)
case toolkit.Box:
log(debugNow, "tWidget.boxC =", p.Name)
log(debugNow, "is there a tParent parent? =", p.parent)
if (p.tk.boxC < 1) {
log(debugNow, "Can not delete from Box. already empty. tWidget.boxC =", p.tk.boxC)
return
}
p.tk.uiBox.Delete(0)
p.tk.boxC -= 1
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
default:
log(debugError, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
log(debugError, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
}
}
func rawAction(a *toolkit.Action) {
log(logInfo, "rawAction() START a.ActionType =", a.ActionType)
log(logInfo, "rawAction() START a.S =", a.S)
if (a.ActionType == toolkit.InitToolkit) {
// TODO: make sure to only do this once
// go uiMain.Do(func() {
// ui.Main(demoUI)
// go catchActionChannel()
// })
// try doing this on toolkit load in init()
return
}
log(logInfo, "rawAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
switch a.WidgetType {
case toolkit.Flag:
flag(a)
return
}
n := me.rootNode.findWidgetId(a.WidgetId)
if (a.ActionType == toolkit.Add) {
ui.QueueMain(func() {
add(a)
})
// TODO: remove this artificial delay
// sleep(.001)
return
}
if (a.ActionType == toolkit.Dump) {
log(debugNow, "rawAction() Dump =", a.ActionType, a.WidgetType, n.Name)
me.rootNode.listChildren(true)
return
}
if (n == nil) {
me.rootNode.listChildren(true)
log(true, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
log(true, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
log(true, "rawAction() ERROR findWidgetId found nil", a.ActionType, a.WidgetType)
log(true, "rawAction() ERROR findWidgetId found nil for id =", a.WidgetId)
return
panic("findWidgetId found nil for id = " + strconv.Itoa(a.WidgetId))
}
switch a.ActionType {
case toolkit.Show:
n.show(true)
case toolkit.Hide:
n.show(false)
case toolkit.Enable:
n.enable(true)
case toolkit.Disable:
n.enable(false)
case toolkit.Get:
n.setText(a)
case toolkit.GetText:
switch a.WidgetType {
case toolkit.Textbox:
a.S = n.S
}
case toolkit.Set:
n.setText(a)
case toolkit.SetText:
n.setText(a)
case toolkit.AddText:
n.setText(a)
case toolkit.Margin:
n.pad(toolkit.Unmargin)
case toolkit.Unmargin:
n.pad(toolkit.Margin)
case toolkit.Pad:
n.pad(toolkit.Pad)
case toolkit.Unpad:
n.pad(toolkit.Unpad)
case toolkit.Delete:
n.Delete()
case toolkit.Move:
log(debugNow, "rawAction() attempt to move() =", a.ActionType, a.WidgetType)
newParent := me.rootNode.findWidgetId(a.ParentId)
n.move(newParent)
default:
log(debugError, "rawAction() Unknown =", a.ActionType, a.WidgetType)
}
log(logInfo, "rawAction() END =", a.ActionType, a.WidgetType)
}

View File

@ -1,157 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
"go.wit.com/gui/toolkit"
)
func actionDump(b bool, a *toolkit.Action) {
log(b, "actionDump() Widget.Type =", a.ActionType)
log(b, "actionDump() Widget.S =", a.S)
log(b, "actionDump() Widget.I =", a.I)
log(b, "actionDump() WidgetId =", a.WidgetId)
log(b, "actionDump() ParentId =", a.ParentId)
}
func add(a *toolkit.Action) {
if (a.WidgetType == toolkit.Root) {
me.rootNode = addNode(a)
return
}
n := addNode(a)
p := n.parent
switch n.WidgetType {
case toolkit.Window:
newWindow(n)
return
case toolkit.Tab:
p.newTab(n)
return
case toolkit.Label:
p.newLabel(n)
return
case toolkit.Button:
p.newButton(n)
return
case toolkit.Grid:
p.newGrid(n)
return
case toolkit.Checkbox:
p.newCheckbox(n)
return
case toolkit.Spinner:
p.newSpinner(n)
return
case toolkit.Slider:
p.newSlider(n)
return
case toolkit.Dropdown:
p.newDropdown(n)
return
case toolkit.Combobox:
p.newCombobox(n)
return
case toolkit.Textbox:
p.newTextbox(n)
return
case toolkit.Group:
p.newGroup(n)
return
case toolkit.Box:
p.newBox(n)
return
case toolkit.Image:
p.newImage(n)
return
default:
log(debugError, "add() error TODO: ", n.WidgetType, n.Name)
}
}
// This routine is very specific to this toolkit
// It's annoying and has to be copied to each widget when there are changes
// it could be 'simplfied' maybe or made to be more generic, but this is as far as I've gotten
// it's probably not worth working much more on this toolkit, the andlabs/ui has been great and got me here!
// but it's time to write direct GTK, QT, macos and windows toolkit plugins
// -- jcarr 2023/03/09
// Grid numbering examples by (X,Y)
// ---------
// -- (1) --
// -- (2) --
// ---------
//
// -----------------------------
// -- (1,1) -- (1,2) -- (1,3) --
// -- (2,1) -- (2,2) -- (2,3) --
// -----------------------------
// internally for andlabs/ui
// (x&y flipped and start at zero)
// -----------------------------
// -- (0,0) -- (1,0) -- (1,0) --
// -- (0,1) -- (1,1) -- (1,1) --
// -----------------------------
func (p *node) place(n *node) bool {
log(logInfo, "place() START", n.WidgetType, n.Name)
if (p.tk == nil) {
log(logError, "p.tk == nil", p.Name, p.ParentId, p.WidgetType, p.tk)
log(logError, "n = ", n.Name, n.ParentId, n.WidgetType, n.tk)
panic("p.tk == nil")
}
log(logInfo, "place() switch", p.WidgetType)
switch p.WidgetType {
case toolkit.Grid:
log(logInfo, "place() Grid try at Parent X,Y =", n.X, n.Y)
n.tk.gridX = n.AtW - 1
n.tk.gridY = n.AtH - 1
log(logInfo, "place() Grid try at gridX,gridY", n.tk.gridX, n.tk.gridY)
// at the very end, subtract 1 from X & Y since andlabs/ui starts counting at zero
p.tk.uiGrid.Append(n.tk.uiControl,
n.tk.gridX, n.tk.gridY, 1, 1,
false, ui.AlignFill, false, ui.AlignFill)
return true
case toolkit.Group:
if (p.tk.uiBox == nil) {
p.tk.uiGroup.SetChild(n.tk.uiControl)
log(logInfo, "place() hack Group to use this as the box?", n.Name, n.WidgetType)
p.tk.uiBox = n.tk.uiBox
} else {
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
}
return true
case toolkit.Tab:
if (p.tk.uiTab == nil) {
log(logError, "p.tk.uiTab == nil for n.WidgetId =", n.WidgetId, "p.tk =", p.tk)
panic("p.tk.uiTab == nil")
}
if (n.tk.uiControl == nil) {
log(logError, "n.tk.uiControl == nil for n.WidgetId =", n.WidgetId, "n.tk =", n.tk)
panic("n.tk.uiControl == nil")
}
log(logError, "CHECK LOGIC ON THIS. APPENDING directly into a window without a tab")
// log(logError, "THIS SHOULD NEVER HAPPEN ??????? trying to place() node=", n.WidgetId, n.Name, n.Text, n.WidgetType)
// log(logError, "THIS SHOULD NEVER HAPPEN ??????? trying to place() on parent=", p.WidgetId, p.Name, p.Text, p.WidgetType)
// panic("n.tk.uiControl == nil")
p.tk.uiTab.Append(n.Text, n.tk.uiControl)
p.tk.boxC += 1
return true
case toolkit.Box:
log(logInfo, "place() uiBox =", p.tk.uiBox)
log(logInfo, "place() uiControl =", n.tk.uiControl)
p.tk.uiBox.Append(n.tk.uiControl, stretchy)
p.tk.boxC += 1
return true
case toolkit.Window:
p.tk.uiWindow.SetChild(n.tk.uiControl)
return true
default:
log(debugError, "place() how? Parent =", p.WidgetId, p.WidgetType)
}
return false
}

View File

@ -1,29 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// make new Box here
func (p *node) newBox(n *node) {
log(debugToolkit, "newBox()", n.Name)
newt := new(guiWidget)
var box *ui.Box
log(debugToolkit, "rawBox() create", n.Name)
if (n.B) {
box = ui.NewHorizontalBox()
} else {
box = ui.NewVerticalBox()
}
box.SetPadded(padded)
newt.uiBox = box
newt.uiControl = box
newt.boxC = 0
n.tk = newt
p.place(n)
}

View File

@ -1,31 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newButton(n *node) {
log(debugToolkit, "newButton() START", n.Name)
t := p.tk
if (t == nil) {
log(debugToolkit, "newButton() toolkit struct == nil. name=", n.Name)
return
}
newt := new(guiWidget)
b := ui.NewButton(n.Text)
newt.uiButton = b
newt.uiControl = b
newt.parent = t
b.OnClicked(func(*ui.Button) {
n.doUserEvent()
})
n.tk = newt
p.place(n)
log(debugToolkit, "newButton() END", n.Name)
}

View File

@ -1,27 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newCheckbox(n *node) {
newt := new(guiWidget)
log(debugToolkit, "newCheckbox()", n.Name, n.WidgetType)
newt.uiCheckbox = ui.NewCheckbox(n.Text)
newt.uiControl = newt.uiCheckbox
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {
n.B = newt.checked()
log(debugChange, "val =", n.B)
n.doUserEvent()
})
n.tk = newt
p.place(n)
}
func (t *guiWidget) checked() bool {
return t.uiCheckbox.Checked()
}

View File

@ -1,41 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newCombobox(n *node) {
newt := new(guiWidget)
log(debugToolkit, "newCombobox() START", n.Name)
cb := ui.NewEditableCombobox()
newt.uiEditableCombobox = cb
newt.uiControl = cb
// initialize the index
newt.c = 0
newt.val = make(map[int]string)
cb.OnChanged(func(spin *ui.EditableCombobox) {
n.S = spin.Text()
n.doUserEvent()
})
n.tk = newt
p.place(n)
}
func (t *guiWidget) AddComboboxName(title string) {
t.uiEditableCombobox.Append(title)
if (t.val == nil) {
log(debugToolkit, "make map didn't work")
return
}
t.val[t.c] = title
// If this is the first menu added, set the dropdown to it
// if (t.c == 0) {
// }
t.c = t.c + 1
}

View File

@ -1 +0,0 @@
../nocui/common.go

View File

@ -1,168 +0,0 @@
package main
import (
"strconv"
"go.wit.com/gui/toolkit"
)
var defaultBehavior bool = true
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
var canvas bool // if set to true, the windows are a raw canvas
var menubar bool // for windows
var stretchy bool // expand things like buttons to the maximum size
var padded bool // add space between things like buttons
var margin bool // add space around the frames of windows
var debugToolkit bool = false
var debugChange bool = false
var debugPlugin bool = false
var debugAction bool = false
var debugFlags bool = false
var debugGrid bool = false
var debugNow bool = true
var debugError bool = true
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func setDefaultBehavior(s bool) {
defaultBehavior = s
if (defaultBehavior) {
log(debugToolkit, "Setting this toolkit to use the default behavior.")
log(debugToolkit, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
stretchy = false
padded = true
menubar = true
margin = true
canvas = false
bookshelf = true // 99% of the time, things make a vertical stack of objects
} else {
log(debugToolkit, "This toolkit is set to ignore the default behavior.")
}
}
func ShowDebug () {
log(true, "debugToolkit =", debugToolkit)
log(true, "debugChange =", debugChange)
log(true, "debugAction =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugNow =", debugNow)
log(true, "debugError =", debugError)
}
func (t *guiWidget) Dump(b bool) {
if ! b {
return
}
log(b, "Name = ", t.Width, t.Height)
if (t.uiBox != nil) {
log(b, "uiBox =", t.uiBox)
}
if (t.uiButton != nil) {
log(b, "uiButton =", t.uiButton)
}
if (t.uiCombobox != nil) {
log(b, "uiCombobox =", t.uiCombobox)
}
if (t.uiWindow != nil) {
log(b, "uiWindow =", t.uiWindow)
}
if (t.uiTab != nil) {
log(b, "uiTab =", t.uiTab)
}
if (t.uiGroup != nil) {
log(b, "uiGroup =", t.uiGroup)
}
if (t.uiEntry != nil) {
log(b, "uiEntry =", t.uiEntry)
}
if (t.uiMultilineEntry != nil) {
log(b, "uiMultilineEntry =", t.uiMultilineEntry)
}
if (t.uiSlider != nil) {
log(b, "uiSlider =", t.uiSlider)
}
if (t.uiCheckbox != nil) {
log(b, "uiCheckbox =", t.uiCheckbox)
}
}
/*
func GetDebugToolkit () bool {
return debugToolkit
}
*/
func flag(a *toolkit.Action) {
// should set the checkbox to this value
switch a.S {
case "Quiet":
logInfo = a.B
logVerbose = a.B
logWarn = a.B
logError = a.B
case "Error":
logError = a.B
case "Info":
logInfo = a.B
case "Verbose":
logInfo = a.B
logVerbose = a.B
logWarn = a.B
logError = a.B
debugToolkit = a.B
debugChange = a.B
debugPlugin = a.B
debugFlags = a.B
case "Toolkit":
debugToolkit = a.B
case "Change":
debugChange = a.B
case "Plugin":
debugPlugin = a.B
case "Flags":
debugFlags = a.B
case "Now":
debugNow = a.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", a.S)
}
}
func (n *node) dumpWidget(b bool) {
var info, d string
if (n == nil) {
log(debugError, "dumpWidget() node == nil")
return
}
info = n.WidgetType.String()
d = strconv.Itoa(n.WidgetId) + " " + info + " " + n.Name
var tabs string
for i := 0; i < listChildrenDepth; i++ {
tabs = tabs + defaultPadding
}
log(b, tabs + d)
}
var defaultPadding string = " "
var listChildrenDepth int = 0
func (n *node) listChildren(dump bool) {
if (n == nil) {
return
}
n.dumpWidget(dump)
if len(n.children) == 0 {
return
}
for _, child := range n.children {
listChildrenDepth += 1
child.listChildren(dump)
listChildrenDepth -= 1
}
}

View File

@ -1,51 +0,0 @@
package main
// if you include more than just this import
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
import "go.wit.com/gui/toolkit"
// delete the child widget from the parent
// p = parent, c = child
func (n *node) destroy() {
pId := n.parent.WidgetId
cId := n.WidgetId
log(logNow, "delete()", pId, cId)
pt := n.parent.tk
ct := n.tk
if (ct == nil) {
log(true, "delete FAILED (ct = mapToolkit[c] == nil) for c", pId, cId)
// this pukes out a whole universe of shit
// listMap()
return
}
switch n.WidgetType {
case toolkit.Button:
log(true, "Should delete Button here:", n.Name)
log(true, "Parent:")
pt.Dump(true)
log(true, "Child:")
ct.Dump(true)
if (pt.uiBox == nil) {
log(true, "Don't know how to destroy this")
} else {
log(true, "Fuck it, destroy the whole box", n.parent.Name)
// pt.uiBox.Destroy() // You have a bug: You cannot destroy a uiControl while it still has a parent.
pt.uiBox.SetPadded(false)
pt.uiBox.Delete(4)
ct.uiButton.Disable()
// ct.uiButton.Hide()
ct.uiButton.Destroy()
}
case toolkit.Window:
log(true, "Should delete Window here:", n.Name)
default:
log(true, "Fuckit, let's destroy a button")
if (ct.uiButton != nil) {
pt.uiBox.Delete(4)
ct.uiButton.Destroy()
}
}
}

View File

@ -1,90 +0,0 @@
package main
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
/*
This is a code example taken directly from the toolkit andlabs/ui
This code is here to double check that the toolkit itself still works
the same way. This is intended as a sanity check.
*/
func BlankWindow(w *ui.Window) *ui.Box {
hbox := ui.NewHorizontalBox()
hbox.SetPadded(true)
w.SetChild(hbox)
return hbox
}
func (t *guiWidget) DemoNumbersPage() {
var w *ui.Window
log(debugToolkit, "Starting wit/gui toolkit andlabs/ui DemoNumbersPage()")
w = t.uiWindow
t.uiBox = makeNumbersPage()
t.uiBox.SetPadded(true)
w.SetChild(t.uiBox)
w.SetTitle("Internal demo of andlabs/ui toolkit")
}
func makeNumbersPage() *ui.Box {
hbox := ui.NewHorizontalBox()
hbox.SetPadded(true)
group := ui.NewGroup("Numbers")
group.SetMargined(true)
hbox.Append(group, true)
vbox := ui.NewVerticalBox()
vbox.SetPadded(true)
group.SetChild(vbox)
spinbox := ui.NewSpinbox(0, 100)
slider := ui.NewSlider(0, 100)
pbar := ui.NewProgressBar()
spinbox.OnChanged(func(*ui.Spinbox) {
slider.SetValue(spinbox.Value())
pbar.SetValue(spinbox.Value())
})
slider.OnChanged(func(*ui.Slider) {
spinbox.SetValue(slider.Value())
pbar.SetValue(slider.Value())
})
vbox.Append(spinbox, false)
vbox.Append(slider, false)
vbox.Append(pbar, false)
ip := ui.NewProgressBar()
ip.SetValue(-1)
vbox.Append(ip, false)
group = ui.NewGroup("Lists")
group.SetMargined(true)
hbox.Append(group, true)
vbox = ui.NewVerticalBox()
vbox.SetPadded(true)
group.SetChild(vbox)
cbox := ui.NewCombobox()
cbox.Append("Combobox Item 1")
cbox.Append("Combobox Item 2")
cbox.Append("Combobox Item 3")
vbox.Append(cbox, false)
ecbox := ui.NewEditableCombobox()
ecbox.Append("Editable Item 1")
ecbox.Append("Editable Item 2")
ecbox.Append("Editable Item 3")
vbox.Append(ecbox, false)
rb := ui.NewRadioButtons()
rb.Append("Radio Button 1")
rb.Append("Radio Button 2")
rb.Append("Radio Button 3")
vbox.Append(rb, false)
return hbox
}

View File

@ -1,79 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
"go.wit.com/gui/toolkit"
)
func (p *node) newDropdown(n *node) {
newt := new(guiWidget)
log(debugToolkit, "gui.Toolbox.newDropdown() START", n.Name)
cb := ui.NewCombobox()
newt.uiCombobox = cb
newt.uiControl = cb
// initialize the index
newt.c = 0
newt.val = make(map[int]string)
cb.OnSelected(func(spin *ui.Combobox) {
i := spin.Selected()
if (newt.val == nil) {
log(logError, "make map didn't work")
n.S = "map did not work. ui.Combobox error"
} else {
n.S = newt.val[i]
}
n.doUserEvent()
})
n.tk = newt
p.place(n)
}
func (t *guiWidget) addDropdownName(title string) {
t.uiCombobox.Append(title)
if (t.val == nil) {
log(debugToolkit, "make map didn't work")
return
}
t.val[t.c] = title
// If this is the first menu added, set the dropdown to it
if (t.c == 0) {
log(debugChange, "THIS IS THE FIRST Dropdown", title)
t.uiCombobox.SetSelected(0)
}
t.c = t.c + 1
}
func (t *guiWidget) SetDropdown(i int) {
t.uiCombobox.SetSelected(i)
}
func (n *node) AddDropdownName(s string) {
log(logInfo, "AddDropdownName()", n.WidgetId, "add:", s)
t := n.tk
if (t == nil) {
log(logInfo, "AddDropdownName() toolkit struct == nil. name=", n.Name, s)
return
}
t.addDropdownName(s)
}
func (n *node) SetDropdownName(a *toolkit.Action, s string) {
log(logInfo, "SetDropdown()", n.WidgetId, ",", s)
t := n.tk
if (t == nil) {
log(debugError, "SetDropdown() FAILED mapToolkits[w] == nil. name=", n.WidgetId, s)
return
}
t.SetDropdown(1)
// TODO: send back to wit/gui goroutine with the chan
n.S = s
}

View File

@ -1,25 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// Grid numbering by (X,Y)
// -----------------------------
// -- (1,1) -- (2,1) -- (3,1) --
// -- (1,2) -- (2,1) -- (3,1) --
// -----------------------------
func (p *node) newGrid(n *node) {
var newt *guiWidget
log(debugToolkit, "newGrid()", n.WidgetId, "to", n.ParentId)
newt = new(guiWidget)
c := ui.NewGrid()
newt.uiGrid = c
newt.uiControl = c
n.tk = newt
p.place(n)
}

View File

@ -1,22 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newGroup(n *node) {
log(debugToolkit, "NewGroup()", n.Name)
newt := new(guiWidget)
log(debugToolkit, "NewGroup() create", n.Name)
g := ui.NewGroup(n.Name)
g.SetMargined(margin)
newt.uiGroup = g
newt.uiControl = g
n.tk = newt
p.place(n)
}

View File

@ -1,27 +0,0 @@
package main
var rawImage = []byte{
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10,
0x08, 0x06, 0x00, 0x00, 0x00, 0x1f, 0xf3, 0xff, 0x61, 0x00, 0x00, 0x00,
0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xae, 0xce, 0x1c, 0xe9, 0x00, 0x00,
0x00, 0xca, 0x49, 0x44, 0x41, 0x54, 0x38, 0x11, 0xa5, 0x93, 0xb1, 0x0d,
0xc2, 0x40, 0x0c, 0x45, 0x1d, 0xc4, 0x14, 0x0c, 0x12, 0x41, 0x0f, 0x62,
0x12, 0x46, 0x80, 0x8a, 0x2e, 0x15, 0x30, 0x02, 0x93, 0x20, 0x68, 0x11,
0x51, 0x06, 0x61, 0x0d, 0x88, 0x2d, 0x7f, 0xdb, 0x07, 0x87, 0x08, 0xdc,
0x49, 0x91, 0x7d, 0xf6, 0xf7, 0xf3, 0x4f, 0xa4, 0x54, 0xbb, 0xeb, 0xf6,
0x41, 0x05, 0x67, 0xcc, 0xb3, 0x9b, 0xfa, 0xf6, 0x17, 0x62, 0xdf, 0xcd,
0x48, 0x00, 0x32, 0xbd, 0xa8, 0x1d, 0x72, 0xee, 0x3c, 0x47, 0x16, 0xfb,
0x5c, 0x53, 0x8d, 0x03, 0x30, 0x14, 0x84, 0xf7, 0xd5, 0x89, 0x26, 0xc7,
0x25, 0x10, 0x36, 0xe4, 0x05, 0xa2, 0x51, 0xbc, 0xc4, 0x1c, 0xc3, 0x1c,
0xed, 0x30, 0x1c, 0x8f, 0x16, 0x3f, 0x02, 0x78, 0x33, 0x20, 0x06, 0x60,
0x97, 0x70, 0xaa, 0x45, 0x7f, 0x85, 0x60, 0x5d, 0xb6, 0xf4, 0xc2, 0xc4,
0x3e, 0x0f, 0x44, 0xcd, 0x1b, 0x20, 0x90, 0x0f, 0xed, 0x85, 0xa8, 0x55,
0x05, 0x42, 0x43, 0xb4, 0x9e, 0xce, 0x71, 0xb3, 0xe8, 0x0e, 0xb4, 0xc4,
0xc3, 0x39, 0x21, 0xb7, 0x73, 0xbd, 0xe4, 0x1b, 0xe4, 0x04, 0xb6, 0xaa,
0x4f, 0x18, 0x2c, 0xee, 0x42, 0x31, 0x01, 0x84, 0xfa, 0xe0, 0xd4, 0x00,
0xdf, 0xb6, 0x83, 0xf8, 0xea, 0xc2, 0x00, 0x10, 0xfc, 0x1a, 0x05, 0x30,
0x74, 0x3b, 0xe0, 0xd1, 0x45, 0xb1, 0x83, 0xaa, 0xf4, 0x77, 0x7e, 0x02,
0x87, 0x1f, 0x42, 0x7f, 0x9e, 0x2b, 0xe8, 0xdf, 0x00, 0x00, 0x00, 0x00,
0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
}

View File

@ -1,50 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
// make new Image using andlabs/ui
func (p *node) newImage(n *node) {
newt := new(guiWidget)
var img *ui.Image
log(debugToolkit, "rawImage() create", n.Name)
img = ui.NewImage(16, 16)
newt.uiImage = img
// newt.uiControl = img
n.tk = newt
p.place(n)
}
/*
if (a.Name == "image") {
log(true, "NewTextbox() trying to add a new image")
i := ui.NewImage(16, 16)
img, _, err := image.Decode(bytes.NewReader(rawImage))
if err != nil {
panic(err)
}
nr, ok := img.(*image.RGBA)
if !ok {
i2 := image.NewRGBA(img.Bounds())
draw.Draw(i2, i2.Bounds(), img, img.Bounds().Min, draw.Src)
nr = i2
}
i.Append(nr)
t.uiBox.Append(i, true)
var img *ui.Image
var icon []byte
var imgA image.Image
icon, _ = res.ReadFile("resources/ping6.working.png")
// imgA, _, err := image.Decode(bytes.NewReader(b))
imgA, _, _ = image.Decode(icon)
img.Append(imgA)
img.Append(icon)
}
*/

View File

@ -1,18 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newLabel(n *node) {
log(logInfo, "NewLabel()", n.Name)
newt := new(guiWidget)
c := ui.NewLabel(n.Name)
newt.uiLabel = c
newt.uiControl = c
n.tk = newt
p.place(n)
}

View File

@ -1,25 +0,0 @@
package main
import (
witlog "go.wit.com/gui/log"
)
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = true
var logInfo bool = false
var logVerbose bool = false
func log(a ...any) {
witlog.Where = "wit/gui/andlabs"
witlog.Log(a...)
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
witlog.Exit(a...)
}

View File

@ -1,57 +0,0 @@
package main
import (
"sync"
"go.wit.com/gui/toolkit"
"github.com/andlabs/ui"
// the _ means we only need this for the init()
_ "github.com/andlabs/ui/winmanifest"
)
var uiMainUndef bool = true
var uiMain sync.Once
var muAction sync.Mutex
func catchActionChannel() {
log(logInfo, "catchActionChannel() START")
for {
log(logInfo, "catchActionChannel() for loop")
select {
case a := <-pluginChan:
log(logInfo, "catchActionChannel() SELECT widget id =", a.WidgetId, a.Name)
log(logInfo, "catchActionChannel() STUFF", a.WidgetId, a.ActionType, a.WidgetType)
muAction.Lock()
// TODO ui.QueueMain(f)
// TODO ui.QueueMain( func() {rawAction(a)} )
ui.QueueMain( func() {rawAction(&a)} )
// rawAction(a)
muAction.Unlock()
log(logInfo, "catchActionChannel() STUFF END", a.WidgetId, a.ActionType, a.WidgetType)
}
}
}
// This is important. This sets the defaults for the gui. Without this, there isn't correct padding, etc
func init() {
log(logNow, "Init() START")
log(debugToolkit, "Init()")
// Can you pass values to a plugin init() ? Otherwise, there is no way to safely print
// log(debugToolkit, "init() Setting defaultBehavior = true")
setDefaultBehavior(true)
// TODO: this is messed up. run ui.Main() from the first add? Initialize it with an empty thing first?
// fake out the OS toolkit by making a fake window. This is probably needed for macos & windows
// actually, this probably breaks the macos build
go ui.Main(func() {
demoUI()
})
// andlabs = make(map[int]*andlabsT)
pluginChan = make(chan toolkit.Action, 1)
log(logNow, "Init() start channel reciever")
go catchActionChannel()
log(logNow, "Init() END")
}

View File

@ -1,128 +0,0 @@
package main
import (
"go.wit.com/gui/toolkit"
)
func (n *node) setText(a *toolkit.Action) {
log(debugChange, "setText() START with a.S =", a.S)
t := n.tk
if (t == nil) {
log(debugError, "setText error. tk == nil", n.Name, n.WidgetId)
actionDump(debugError, a)
return
}
log(debugChange, "setText() Attempt on", n.WidgetType, "with", a.S)
switch n.WidgetType {
case toolkit.Window:
t.uiWindow.SetTitle(a.S)
case toolkit.Tab:
case toolkit.Group:
t.uiGroup.SetTitle(a.S)
case toolkit.Checkbox:
switch a.ActionType {
case toolkit.SetText:
t.uiCheckbox.SetText(a.S)
case toolkit.Get:
n.B = t.uiCheckbox.Checked()
case toolkit.Set:
// TODO: commented out while working on chan
t.uiCheckbox.SetChecked(a.B)
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
case toolkit.Textbox:
switch a.ActionType {
case toolkit.Set:
if (t.uiEntry != nil) {
t.uiEntry.SetText(a.S)
}
if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.SetText(a.S)
}
case toolkit.SetText:
if (t.uiEntry != nil) {
t.uiEntry.SetText(a.S)
}
if (t.uiMultilineEntry != nil) {
t.uiMultilineEntry.SetText(a.S)
}
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
case toolkit.Label:
t.uiLabel.SetText(a.S)
case toolkit.Button:
t.uiButton.SetText(a.S)
case toolkit.Slider:
switch a.ActionType {
case toolkit.Get:
n.I = t.uiSlider.Value()
case toolkit.Set:
t.uiSlider.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
case toolkit.Spinner:
switch a.ActionType {
case toolkit.Get:
n.I = t.uiSpinbox.Value()
case toolkit.Set:
t.uiSpinbox.SetValue(a.I)
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
case toolkit.Dropdown:
switch a.ActionType {
case toolkit.AddText:
n.AddDropdownName(a.S)
case toolkit.Set:
var orig int
var i int = -1
var s string
orig = t.uiCombobox.Selected()
log(debugChange, "try to set the Dropdown to", a.S, "from", orig)
// try to find the string
for i, s = range t.val {
log(debugChange, "i, s", i, s)
if (a.S == s) {
t.uiCombobox.SetSelected(i)
log(debugChange, "setText() Dropdown worked.", n.S)
return
}
}
log(debugError, "setText() Dropdown did not find:", a.S)
// if i == -1, then there are not any things in the menu to select
if (i == -1) {
return
}
// if the string was never set, then set the dropdown to the last thing added to the menu
if (orig == -1) {
t.uiCombobox.SetSelected(i)
}
case toolkit.Get:
// t.S = t.s
case toolkit.GetText:
// t.S = t.s
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
case toolkit.Combobox:
switch a.ActionType {
case toolkit.AddText:
t.AddComboboxName(a.S)
case toolkit.Set:
t.uiEditableCombobox.SetText(a.S)
n.S = a.S
case toolkit.SetText:
t.uiEditableCombobox.SetText(a.S)
n.S = a.S
default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", n.Name)
}
default:
log(debugError, "plugin Send() Don't know how to setText on", n.WidgetType, "yet", a.ActionType)
}
log(debugChange, "setText() END with a.S =", a.S)
}

View File

@ -1,22 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newSlider(n *node) {
newt := new(guiWidget)
s := ui.NewSlider(n.X, n.Y)
newt.uiSlider = s
newt.uiControl = s
s.OnChanged(func(spin *ui.Slider) {
n.I = newt.uiSlider.Value()
n.doUserEvent()
})
n.tk = newt
p.place(n)
}

View File

@ -1,22 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newSpinner(n *node) {
newt := new(guiWidget)
s := ui.NewSpinbox(n.X, n.Y)
newt.uiSpinbox = s
newt.uiControl = s
s.OnChanged(func(s *ui.Spinbox) {
n.I = newt.uiSpinbox.Value()
n.doUserEvent()
})
n.tk = newt
p.place(n)
}

View File

@ -1,60 +0,0 @@
package main
// import "go.wit.com/gui/toolkit"
import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest"
// var andlabs map[int]*andlabsT
// var callback func(int) bool
// var callback chan toolkit.Action
// It's probably a terrible idea to call this 'me'
var me config
type config struct {
rootNode *node // the base of the binary tree. it should have id == 0
}
// stores the raw toolkit internals
type guiWidget struct {
Width int
Height int
// tw *toolkit.Widget
parent *guiWidget
children []*guiWidget
// used to track if a tab has a child widget yet
child bool
uiControl ui.Control
uiBox *ui.Box
uiButton *ui.Button
uiCombobox *ui.Combobox
uiCheckbox *ui.Checkbox
uiEntry *ui.Entry
uiGroup *ui.Group
uiLabel *ui.Label
uiSlider *ui.Slider
uiSpinbox *ui.Spinbox
uiTab *ui.Tab
uiWindow *ui.Window
uiMultilineEntry *ui.MultilineEntry
uiEditableCombobox *ui.EditableCombobox
uiImage *ui.Image
uiGrid *ui.Grid
gridX int
gridY int
// used as a counter to work around limitations of widgets like combobox
// this is probably fucked up and in many ways wrong because of unsafe goroutine threading
// but it's working for now due to the need for need for a correct interaction layer betten toolkits
c int
val map[int]string
// andlabs/ui only accesses widget id numbers
boxC int // how many things on in a box or how many tabs
}

View File

@ -1,116 +0,0 @@
package main
import (
"go.wit.com/gui/toolkit"
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
/*
This adds a tab
andlabs/ui is goofy in the sense that you have to determine
if the ui.Window already has a tab in it. If it does, then
you need to add this tab and not run SetChild() on the window
or instead it replaces the existing tab with the new one
I work around this by always sending a Toolkit that is a tab
once there is one. If you send a Window here, it will replace
any existing tabs rather than adding a new one
*/
func (p *node) newTab(n *node) {
var newt *guiWidget
if (p == nil) {
log(debugError, "newTab() p == nil. how the fuck does this happen?", n.WidgetId, n.ParentId)
}
if (p.WidgetType != toolkit.Window) {
log(debugError, "newTab() uiWindow == nil. I can't add a toolbar without window", n.WidgetId, n.ParentId)
return
}
t := p.tk
log(debugToolkit, "newTab() START", n.WidgetId, n.ParentId)
if (t.uiTab == nil) {
// this means you have to make a new tab
log(debugToolkit, "newTab() GOOD. This should be the first tab:", n.WidgetId, n.ParentId)
newt = rawTab(t.uiWindow, n.Text)
t.uiTab = newt.uiTab
} else {
// this means you have to append a tab
log(debugToolkit, "newTab() GOOD. This should be an additional tab:", n.WidgetId, n.ParentId)
if (n.WidgetType == toolkit.Tab) {
// andlabs doesn't have multiple tab widgets so make a fake one?
// this makes a guiWidget internal structure with the parent values
newt = new(guiWidget)
newt.uiWindow = t.uiWindow
newt.uiTab = t.uiTab
} else {
newt = t.appendTab(n.Text)
}
}
n.tk = newt
}
// This sets _all_ the tabs to Margin = true
//
// TODO: do proper tab tracking (will be complicated). low priority
func tabSetMargined(tab *ui.Tab, b bool) {
c := tab.NumPages()
for i := 0; i < c; i++ {
log(debugToolkit, "SetMargined", i, b)
tab.SetMargined(i, b)
}
}
func rawTab(w *ui.Window, name string) *guiWidget {
var newt guiWidget
log(debugToolkit, "rawTab() START", name)
if (w == nil) {
log(debugError, "UiWindow == nil. I can't add a tab without a window")
log(debugError, "UiWindow == nil. I can't add a tab without a window")
log(debugError, "UiWindow == nil. I can't add a tab without a window")
// sleep(1)
return nil
}
tab := ui.NewTab()
w.SetChild(tab)
newt.uiTab = tab
newt.uiControl = tab
log(debugToolkit, "rawTab() END", name)
return &newt
}
func (t *guiWidget) appendTab(name string) *guiWidget {
var newT guiWidget
log(debugToolkit, "appendTab() ADD", name)
if (t.uiTab == nil) {
log(debugToolkit, "UiWindow == nil. I can't add a widget without a place to put it")
panic("should never have happened. wit/gui/toolkit has ui.Tab == nil")
}
log(debugToolkit, "appendTab() START name =", name)
var hbox *ui.Box
if (defaultBehavior) {
hbox = ui.NewHorizontalBox()
} else {
if (bookshelf) {
hbox = ui.NewHorizontalBox()
} else {
hbox = ui.NewVerticalBox()
}
}
hbox.SetPadded(padded)
t.uiTab.Append(name, hbox)
newT.uiWindow = t.uiWindow
newT.uiTab = t.uiTab
newT.uiBox = hbox
return &newT
}

View File

@ -1,32 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (p *node) newTextbox(n *node) {
newt := new(guiWidget)
if (n.X == 1) {
e := ui.NewEntry()
newt.uiEntry = e
newt.uiControl = e
e.OnChanged(func(spin *ui.Entry) {
n.S = spin.Text()
n.doUserEvent()
})
} else {
e := ui.NewNonWrappingMultilineEntry()
newt.uiMultilineEntry = e
newt.uiControl = e
e.OnChanged(func(spin *ui.MultilineEntry) {
n.S = spin.Text()
n.doUserEvent()
})
}
n.tk = newt
p.place(n)
}

View File

@ -1,97 +0,0 @@
package main
import (
"github.com/andlabs/ui"
)
// Example showing how to update the UI using the QueueMain function
// especially if the update is coming from another goroutine
//
// see QueueMain in 'main.go' for detailed description
var count int
func demoUI() {
mainWindow := ui.NewWindow("libui Updating UI", 640, 480, true)
mainWindow.OnClosing(func(*ui.Window) bool {
ui.Quit()
return true
})
ui.OnShouldQuit(func() bool {
mainWindow.Destroy()
return true
})
vbContainer := ui.NewVerticalBox()
vbContainer.SetPadded(true)
inputGroup := ui.NewGroup("Input")
inputGroup.SetMargined(true)
vbInput := ui.NewVerticalBox()
vbInput.SetPadded(true)
inputForm := ui.NewForm()
inputForm.SetPadded(true)
message := ui.NewEntry()
message.SetText("Hello World")
inputForm.Append("What message do you want to show?", message, false)
showMessageButton := ui.NewButton("Show message")
clearMessageButton := ui.NewButton("Clear message")
vbInput.Append(inputForm, false)
vbInput.Append(showMessageButton, false)
vbInput.Append(clearMessageButton, false)
inputGroup.SetChild(vbInput)
messageGroup := ui.NewGroup("Message")
messageGroup.SetMargined(true)
vbMessage := ui.NewVerticalBox()
vbMessage.SetPadded(true)
messageLabel := ui.NewLabel("")
vbMessage.Append(messageLabel, false)
messageGroup.SetChild(vbMessage)
countGroup := ui.NewGroup("Counter")
countGroup.SetMargined(true)
vbCounter := ui.NewVerticalBox()
vbCounter.SetPadded(true)
countLabel := ui.NewLabel("blah")
vbCounter.Append(countLabel, false)
countGroup.SetChild(vbCounter)
vbContainer.Append(inputGroup, false)
vbContainer.Append(messageGroup, false)
vbContainer.Append(countGroup, false)
mainWindow.SetChild(vbContainer)
showMessageButton.OnClicked(func(*ui.Button) {
// Update the UI directly as it is called from the main thread
messageLabel.SetText(message.Text())
})
clearMessageButton.OnClicked(func(*ui.Button) {
// Update the UI directly as it is called from the main thread
messageLabel.SetText("")
})
// this is messed up.
// mainWindow.Show()
}
/*
func main() {
ui.Main(setupUI)
}
*/

View File

@ -1,29 +0,0 @@
package main
import (
"go.wit.com/gui/toolkit"
)
// this is specific to the nocui toolkit
func initWidget(n *node) *guiWidget {
var w *guiWidget
w = new(guiWidget)
// Set(w, "default")
if n.WidgetType == toolkit.Root {
log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
n.WidgetId = 0
me.rootNode = n
return w
}
if (n.WidgetType == toolkit.Box) {
if (n.B) {
n.horizontal = true
} else {
n.horizontal = false
}
}
return w
}

View File

@ -1,46 +0,0 @@
package main
import (
"github.com/andlabs/ui"
_ "github.com/andlabs/ui/winmanifest"
)
func (t *guiWidget) MessageWindow(msg1 string, msg2 string) {
ui.MsgBox(t.uiWindow, msg1, msg2)
}
func (t *guiWidget) ErrorWindow(msg1 string, msg2 string) {
ui.MsgBoxError(t.uiWindow, msg1, msg2)
}
func newWindow(n *node) {
var newt *guiWidget
newt = new(guiWidget)
// menubar bool is if the OS defined border on the window should be used
win := ui.NewWindow(n.Name, n.X, n.Y, menubar)
win.SetBorderless(canvas)
win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool {
n.doUserEvent()
return true
})
newt.uiWindow = win
newt.uiControl = win
n.tk = newt
win.Show()
return
}
func (n *node) SetWindowTitle(title string) {
log(debugToolkit, "toolkit NewWindow", n.Text, "title", title)
win := n.tk.uiWindow
if (win == nil) {
log(debugError, "Error: no window", n.WidgetId)
} else {
win.SetTitle(title)
log(debugToolkit, "Setting the window title", title)
}
}

View File

@ -1,15 +0,0 @@
all: plugin
ldd ../gocui.so
goget:
go get -v -t -u
plugin:
go build -v -x -buildmode=plugin -o ../gocui.so
objdump:
objdump -t ../gocui.so |less
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

View File

@ -1,78 +0,0 @@
package main
import (
"go.wit.com/gui/toolkit"
)
var fakeStartWidth int = me.FakeW
var fakeStartHeight int = me.TabH + me.FramePadH
// setup fake labels for non-visible things off screen
func (n *node) setFake() {
w := n.tk
w.isFake = true
n.gocuiSetWH(fakeStartWidth, fakeStartHeight)
fakeStartHeight += w.gocuiSize.Height()
// TODO: use the actual max hight of the terminal window
if (fakeStartHeight > 24) {
fakeStartHeight = me.TabH
fakeStartWidth += me.FakeW
}
if (logInfo) {
n.showView()
}
}
// set the widget start width & height
func (n *node) addWidget() {
nw := n.tk
log(logInfo, "setStartWH() w.id =", n.WidgetId, "n.name", n.Name)
switch n.WidgetType {
case toolkit.Root:
log(logInfo, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.Name)
nw.color = &colorRoot
n.setFake()
return
case toolkit.Flag:
nw.color = &colorFlag
n.setFake()
return
case toolkit.Window:
nw.frame = false
nw.color = &colorWindow
// redoWindows(0,0)
return
case toolkit.Tab:
nw.color = &colorTab
// redoWindows(0,0)
return
case toolkit.Button:
nw.color = &colorButton
case toolkit.Box:
nw.color = &colorBox
nw.isFake = true
n.setFake()
return
case toolkit.Grid:
nw.color = &colorGrid
nw.isFake = true
n.setFake()
return
case toolkit.Group:
nw.color = &colorGroup
nw.frame = false
return
case toolkit.Label:
nw.color = &colorLabel
nw.frame = false
return
default:
/*
if n.IsCurrent() {
n.updateCurrent()
}
*/
}
n.showWidgetPlacement(logInfo, "addWidget()")
}

View File

@ -1,33 +0,0 @@
package main
import (
// "github.com/awesome-gocui/gocui"
"go.wit.com/gui/toolkit"
)
func (n *node) setCheckbox(b bool) {
w := n.tk
if (n.WidgetType != toolkit.Checkbox) {
return
}
if (b) {
n.B = b
n.Text = "X " + n.Name
} else {
n.B = b
n.Text = " " + n.Name
}
t := len(n.Text) + 1
w.gocuiSize.w1 = w.gocuiSize.w0 + t
// w.realWidth = w.gocuiSize.Width() + me.PadW
// w.realHeight = w.gocuiSize.Height() + me.PadH
// if w.frame {
// w.realWidth += me.FramePadW
// w.realHeight += me.FramePadH
// }
n.deleteView()
n.showView()
}

View File

@ -1,356 +0,0 @@
package main
import (
"fmt"
"github.com/awesome-gocui/gocui"
"go.wit.com/gui/toolkit"
)
// set isCurrent = false everywhere
func unsetCurrent(n *node) {
w := n.tk
w.isCurrent = false
if n.WidgetType == toolkit.Tab {
// n.tk.color = &colorTab
// n.setColor()
}
for _, child := range n.children {
unsetCurrent(child)
}
}
// when adding a new widget, this will update the display
// of the current widgets if that widget is supposed
// to be in current display
func (n *node) updateCurrent() {
log("updateCurrent()", n.Name)
if n.WidgetType == toolkit.Tab {
if n.IsCurrent() {
// n.tk.color = &colorActiveT
n.setColor(&colorActiveT)
n.hideView()
n.showView()
setCurrentTab(n)
} else {
// n.tk.color = &colorTab
// n.setColor()
}
return
}
if n.WidgetType == toolkit.Window {
if n.IsCurrent() {
// setCurrentWindow(n)
}
return
}
if n.WidgetType == toolkit.Root {
return
}
n.parent.updateCurrent()
}
// shows the widgets in a window
func setCurrentWindow(n *node) {
if n.IsCurrent() {
return
}
w := n.tk
if n.WidgetType != toolkit.Window {
return
}
unsetCurrent(me.rootNode)
if n.hasTabs {
// set isCurrent = true on the first tab
for _, child := range n.children {
child.tk.isCurrent = true
break
}
} else {
w.isCurrent = true
}
}
// shows the widgets in a tab
func setCurrentTab(n *node) {
w := n.tk
if n.WidgetType != toolkit.Tab {
return
}
unsetCurrent(me.rootNode)
w.isCurrent = true
p := n.parent.tk
p.isCurrent = true
log("setCurrent()", n.Name)
}
func (n *node) doWidgetClick() {
switch n.WidgetType {
case toolkit.Root:
// THIS IS THE BEGINING OF THE LAYOUT
log("doWidgetClick()", n.Name)
redoWindows(0,0)
case toolkit.Flag:
log("doWidgetClick() FLAG widget name =", n.Name)
log("doWidgetClick() if this is the dropdown menu, handle it here?")
case toolkit.Window:
if (me.currentWindow == n) {
return
}
if (me.currentWindow != nil) {
unsetCurrent(me.currentWindow)
me.currentWindow.setColor(&colorWindow)
me.currentWindow.hideWidgets()
}
n.hideWidgets()
me.currentWindow = n
// setCurrentWindow(n) // probably delete this
n.setColor(&colorActiveW)
n.redoTabs(me.TabW, me.TabH)
for _, child := range n.children {
if (child.currentTab == true) {
log(true, "FOUND CURRENT TAB", child.Name)
setCurrentTab(child)
child.placeWidgets(me.RawW, me.RawH)
child.showWidgets()
return
}
}
/* FIXME: redo this
if ! n.hasTabs {
}
*/
case toolkit.Tab:
if (n.IsCurrent()) {
return // do nothing if you reclick on the already selected tab
}
// find the window and disable the active tab
p := n.parent
if (p != nil) {
p.hideWidgets()
p.redoTabs(me.TabW, me.TabH)
unsetCurrent(p)
for _, child := range p.children {
if child.WidgetType == toolkit.Tab {
child.setColor(&colorTab)
n.currentTab = false
}
}
}
n.currentTab = true
n.setColor(&colorActiveT)
setCurrentTab(n)
n.placeWidgets(me.RawW, me.RawH)
n.showWidgets()
case toolkit.Group:
// n.placeWidgets(p.tk.startH, newH)
n.toggleTree()
case toolkit.Checkbox:
if (n.B) {
n.setCheckbox(false)
} else {
n.setCheckbox(true)
}
n.doUserEvent()
case toolkit.Grid:
newR := n.realGocuiSize()
// w,h := n.logicalSize()
// w := newR.w1 - newR.w0
// h := newR.h1 - newR.h0
n.placeGrid(newR.w0, newR.h0)
n.showWidgets()
case toolkit.Box:
// w.showWidgetPlacement(logNow, "drawTree()")
if (n.horizontal) {
log("BOX IS HORIZONTAL", n.Name)
} else {
log("BOX IS VERTICAL", n.Name)
}
// n.placeWidgets()
n.toggleTree()
case toolkit.Button:
n.doUserEvent()
case toolkit.Dropdown:
log(true, "do the dropdown here")
if (me.ddview == nil) {
me.ddview = addDropdown()
tk := me.ddview.tk
tk.gocuiSize.w0 = 20
tk.gocuiSize.w1 = 40
tk.gocuiSize.h0 = 10
tk.gocuiSize.h1 = 25
tk.v, _ = me.baseGui.SetView("ddview",
tk.gocuiSize.w0,
tk.gocuiSize.h0,
tk.gocuiSize.w1,
tk.gocuiSize.h1, 0)
if (tk.v == nil) {
return
}
tk.v.Wrap = true
tk.v.Frame = true
tk.v.Clear()
fmt.Fprint(tk.v, "example.com\nwit.com")
me.ddview.SetVisible(true)
return
}
log(true, "doWidgetClick() visible =", me.ddview.Visible())
if (me.ddview.Visible()) {
me.ddview.SetVisible(false)
me.baseGui.DeleteView("ddview")
me.ddview.tk.v = nil
} else {
var dnsList string
for i, s := range n.vals {
log(logNow, "AddText()", n.Name, i, s)
dnsList += s + "\n"
}
me.ddNode = n
log(logNow, "new dns list should be set to:", dnsList)
me.ddview.Text = dnsList
me.ddview.SetText(dnsList)
me.ddview.SetVisible(true)
}
for i, s := range n.vals {
log(logNow, "AddText()", n.Name, i, s)
}
default:
}
}
var toggle bool = true
func (n *node) toggleTree() {
if (toggle) {
n.drawTree(toggle)
toggle = false
} else {
n.hideWidgets()
toggle = true
}
}
// display the widgets in the binary tree
func (n *node) drawTree(draw bool) {
w := n.tk
if (w == nil) {
return
}
n.showWidgetPlacement(logNow, "drawTree()")
if (draw) {
// w.textResize()
n.showView()
} else {
n.deleteView()
}
for _, child := range n.children {
child.drawTree(draw)
}
}
func click(g *gocui.Gui, v *gocui.View) error {
// var l string
// var err error
log(logVerbose, "click() START", v.Name())
// n := me.rootNode.findWidgetName(v.Name())
n := findUnderMouse()
if (n != nil) {
log(logNow, "click() Found widget =", n.WidgetId, n.Name, ",", n.Text)
if (n.Name == "DropBox") {
log(logNow, "click() this is the dropdown menu. set a flag here what did I click? where is the mouse?")
log(logNow, "click() set a global dropdown clicked flag=true here")
me.ddClicked = true
}
n.doWidgetClick()
} else {
log(logNow, "click() could not find node name =", v.Name())
}
if _, err := g.SetCurrentView(v.Name()); err != nil {
log(logNow, "click() END err =", err)
return err
}
log(logVerbose, "click() END")
return nil
}
func findUnderMouse() *node {
var found *node
var widgets []*node
var f func (n *node)
w, h := me.baseGui.MousePosition()
// find buttons that are below where the mouse button click
f = func(n *node) {
widget := n.tk
// ignore widgets that are not visible
if n.Visible() {
if ((widget.gocuiSize.w0 <= w) && (w <= widget.gocuiSize.w1) &&
(widget.gocuiSize.h0 <= h) && (h <= widget.gocuiSize.h1)) {
widgets = append(widgets, n)
found = n
}
}
if (n == me.ddview) {
log(true, "findUnderMouse() found ddview")
if n.Visible() {
log(true, "findUnderMouse() and ddview is visable. hide it here. TODO: find highlighted row")
found = n
// find the actual value here and set the dropdown widget
me.baseGui.DeleteView("ddview")
} else {
log(true, "findUnderMouse() I was lying, actually it's not found")
}
}
for _, child := range n.children {
f(child)
}
}
f(me.rootNode)
// widgets has everything that matches
// TODO: pop up menu with a list of them
for _, n := range widgets {
//log(logNow, "ctrlDown() FOUND widget", widget.id, widget.name)
n.showWidgetPlacement(logNow, "findUnderMouse() FOUND")
}
return found
}
// find the widget under the mouse click
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
var found *node
// var widgets []*node
// var f func (n *node)
found = findUnderMouse()
if (me.ctrlDown == nil) {
setupCtrlDownWidget()
me.ctrlDown.Text = found.Name
me.ctrlDown.tk.cuiName = "ctrlDown"
// me.ctrlDown.parent = me.rootNode
}
cd := me.ctrlDown.tk
if (found == nil) {
found = me.rootNode
}
me.ctrlDown.Text = found.Name
newR := found.realGocuiSize()
cd.gocuiSize.w0 = newR.w0
cd.gocuiSize.h0 = newR.h0
cd.gocuiSize.w1 = newR.w1
cd.gocuiSize.h1 = newR.h1
if me.ctrlDown.Visible() {
me.ctrlDown.hideView()
} else {
me.ctrlDown.showView()
}
me.ctrlDown.showWidgetPlacement(logNow, "ctrlDown:")
return nil
}

View File

@ -1,117 +0,0 @@
package main
import (
"math/rand"
"github.com/awesome-gocui/gocui"
)
//w.v.SelBgColor = gocui.ColorCyan
//color.go: w.v.SelFgColor = gocui.ColorBlack
//color.go: w.v.BgColor = gocui.ColorGreen
type colorT struct {
frame gocui.Attribute
fg gocui.Attribute
bg gocui.Attribute
selFg gocui.Attribute
selBg gocui.Attribute
name string
}
var none gocui.Attribute = gocui.AttrNone
var lightPurple gocui.Attribute = gocui.GetColor("#DDDDDD") // light purple
var darkPurple gocui.Attribute = gocui.GetColor("#FFAA55") // Dark Purple
var heavyPurple gocui.Attribute = gocui.GetColor("#88AA55") // heavy purple
var powdererBlue gocui.Attribute = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
var superLightGrey gocui.Attribute = gocui.GetColor("#55AAFF") // super light grey
// Standard defined colors from gocui:
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
// v.BgColor = gocui.GetColor("#111111") // crazy red
// v.BgColor = gocui.GetColor("#FF9911") // heavy red
// v.SelBgColor = gocui.GetColor("#FFEE11") // blood red
// v.BgColor = gocui.GetColor("#55AAFF") // super light grey
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
// Normal Text On mouseover
// Widget Frame Text background Text background
var colorWindow colorT = colorT{ none , gocui.ColorBlue, none , none , powdererBlue , "normal window"}
var colorActiveW colorT = colorT{ none , none , powdererBlue , none , powdererBlue , "active window"}
var colorTab colorT = colorT{gocui.ColorBlue, gocui.ColorBlue, none , none , powdererBlue , "normal tab"}
var colorActiveT colorT = colorT{gocui.ColorBlue, none , powdererBlue , none , powdererBlue , "active tab"}
var colorButton colorT = colorT{gocui.ColorGreen, none , gocui.ColorWhite, gocui.ColorGreen, gocui.ColorBlack, "normal button"}
var colorLabel colorT = colorT{ none , none , superLightGrey , none , superLightGrey , "normal label"}
var colorGroup colorT = colorT{ none , none , superLightGrey , none , superLightGrey , "normal group"}
// widget debugging colors. these widgets aren't displayed unless you are debugging
var colorRoot colorT = colorT{gocui.ColorRed , none , powdererBlue , none , gocui.ColorBlue, "debug root"}
var colorFlag colorT = colorT{gocui.ColorRed , none , powdererBlue , none , gocui.ColorGreen, "debug flag"}
var colorBox colorT = colorT{gocui.ColorRed , none , lightPurple , none , gocui.ColorCyan, "debug box"}
var colorGrid colorT = colorT{gocui.ColorRed , none , lightPurple , none , gocui.ColorRed, "debug grid"}
var colorNone colorT = colorT{ none , none , none , none , none , "debug none"}
// actually sets the colors for the gocui element
// the user will see the colors change when this runs
// TODO: add black/white only flag for ttyS0
// TODO: or fix kvm/qemu serial console & SIGWINCH.
// TODO: and minicom and uboot and 5 million other things.
// TODO: maybe enough of us could actually do that if we made it a goal.
// TODO: start with riscv boards and fix it universally there
// TODO: so just a small little 'todo' item here
func (n *node) setColor(newColor *colorT) {
tk := n.tk
if (tk.color == newColor) {
// nothing to do since the colors have nto changed
return
}
tk.color = newColor
if (tk.v == nil) {
return
}
if (tk.color == nil) {
log(true, "Set the node to color = nil")
tk.color = &colorNone
}
log(true, "Set the node to color =", tk.color.name)
n.recreateView()
}
func (n *node) setDefaultWidgetColor() {
n.showView()
}
func (n *node) setDefaultHighlight() {
w := n.tk
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorGreen
w.v.SelFgColor = gocui.ColorBlack
}
func randColor() gocui.Attribute {
colors := []string{"Green", "#FFAA55", "Yellow", "Blue", "Red", "Black", "White"}
i := rand.Intn(len(colors))
log("randColor() i =", i)
return gocui.GetColor(colors[i])
}
func (n *node) redoColor(draw bool) {
w := n.tk
if (w == nil) {
return
}
sleep(.05)
n.setDefaultHighlight()
n.setDefaultWidgetColor()
for _, child := range n.children {
child.redoColor(draw)
}
}

View File

@ -1 +0,0 @@
../nocui/common.go

View File

@ -1,73 +0,0 @@
package main
import (
"fmt"
"go.wit.com/gui/toolkit"
)
func (n *node) dumpTree(draw bool) {
w := n.tk
if (w == nil) {
return
}
n.showWidgetPlacement(logNow, "dumpTree()")
for _, child := range n.children {
child.dumpTree(draw)
}
}
func (n *node) showWidgetPlacement(b bool, s string) {
if (n == nil) {
log(logError, "WTF w == nil")
return
}
w := n.tk
var s1 string
var pId int
if (n.parent == nil) {
log(logVerbose, "showWidgetPlacement() parent == nil", n.WidgetId, w.cuiName)
pId = 0
} else {
pId = n.parent.WidgetId
}
s1 = fmt.Sprintf("(wId,pId)=(%2d,%2d) ", n.WidgetId, pId)
if n.Visible() {
s1 += fmt.Sprintf("gocui=(%2d,%2d)(%2d,%2d,%2d,%2d)",
w.gocuiSize.Width(), w.gocuiSize.Height(),
w.gocuiSize.w0, w.gocuiSize.h0, w.gocuiSize.w1, w.gocuiSize.h1)
} else {
s1 += fmt.Sprintf(" ")
}
if (n.parent != nil) {
if (n.parent.WidgetType == toolkit.Grid) {
s1 += fmt.Sprintf("At(%2d,%2d) ", n.AtW, n.AtH)
}
}
tmp := "." + n.Name + "."
log(b, s1, s, n.WidgetType, ",", tmp) // , "text=", w.text)
}
func (n *node) dumpWidget(pad string) {
log(true, "node:", pad, n.WidgetId, "At(", n.AtW, n.AtH, ") ,", n.WidgetType, ", n.Name =", n.Name, ", n.Text =", n.Text)
}
func (n *node) listWidgets() {
if (n == nil) {
return
}
var pad string
for i := 0; i < me.depth; i++ {
pad = pad + " "
}
n.dumpWidget(pad)
for _, child := range n.children {
me.depth += 1
child.listWidgets()
me.depth -= 1
}
return
}

View File

@ -1,58 +0,0 @@
package main
import (
"bytes"
"io"
"errors"
)
type FakeFile struct {
reader *bytes.Reader
buffer *bytes.Buffer
offset int64
}
func (f *FakeFile) Read(p []byte) (n int, err error) {
n, err = f.reader.ReadAt(p, f.offset)
f.offset += int64(n)
return n, err
}
func (f *FakeFile) Write(p []byte) (n int, err error) {
n, err = f.buffer.Write(p)
f.offset += int64(n)
f.reader.Reset(f.buffer.Bytes())
return n, err
}
func (f *FakeFile) Seek(offset int64, whence int) (int64, error) {
newOffset := f.offset
switch whence {
case io.SeekStart:
newOffset = offset
case io.SeekCurrent:
newOffset += offset
case io.SeekEnd:
newOffset = int64(f.buffer.Len()) + offset
default:
return 0, errors.New("Seek: whence not at start,current or end")
}
// never can get here right?
if newOffset < 0 {
return 0, errors.New("Seek: offset < 0")
}
f.offset = newOffset
return f.offset, nil
}
func NewFakeFile() *FakeFile {
buf := &bytes.Buffer{}
return &FakeFile{
reader: bytes.NewReader(buf.Bytes()),
buffer: buf,
offset: 0,
}
}

View File

@ -1,100 +0,0 @@
// 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"
"github.com/awesome-gocui/gocui"
)
// This initializes the gocui package
// it runs SetManagerFunc which passes every input
// event (keyboard, mouse, etc) to the function "gocuiEvent()"
func gocuiMain() {
g, err := gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
panic(err)
}
defer g.Close()
me.baseGui = g
g.Cursor = true
g.Mouse = true
// this sets the function that is run on every event. For example:
// When you click the mouse, move the mouse, or press a key on the keyboard
// This is equivalent to xev or similar to cat /dev/input on linux
g.SetManagerFunc(gocuiEvent)
if err := defaultKeybindings(g); err != nil {
panic(err)
}
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
panic(err)
}
}
// Thanks to the gocui developers -- your package kicks ass
// This function is called on every event. It is a callback function from the gocui package
// which has an excellent implementation. While gocui handles things like text highlighting
// and the layout of the text areas -- also things like handling SIGWINCH and lots of really
// complicated console handling, it sends events here in a clean way.
// This is equivalent to the linux command xev (apt install x11-utils)
func gocuiEvent(g *gocui.Gui) error {
maxX, maxY := g.Size()
mx, my := g.MousePosition()
log(logVerbose, "handleEvent() START", maxX, maxY, mx, my, msgMouseDown)
if _, err := g.View("msg"); msgMouseDown && err == nil {
moveMsg(g)
}
if widgetView, _ := g.View("msg"); widgetView == nil {
log(logNow, "handleEvent() create output widget now", maxX, maxY, mx, my)
makeOutputWidget(g, "this is a create before a mouse click")
if (me.logStdout != nil) {
// setOutput(me.logStdout)
}
} else {
log(logInfo, "output widget already exists", maxX, maxY, mx, my)
}
mouseMove(g)
log(logVerbose, "handleEvent() END ", maxX, maxY, mx, my, msgMouseDown)
return nil
}
func dragOutputWindow() {
}
// turns off the frame on the global window
func setFrame(b bool) {
// TODO: figure out what this might be useful for
// what is this do? I made it just 2 lines for now. Is this useful for something?
v := SetView("global", 5, 10, 5, 10, 0) // x0, x1, y1, y2, overlap
if (v == nil) {
log(logError, "setFrame() global failed")
}
v.Frame = b
}
func quit(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}
func SetView(name string, x0, y0, x1, y1 int, overlaps byte) *gocui.View {
if (me.baseGui == nil) {
log(logError, "SetView() ERROR: me.baseGui == nil")
return nil
}
v, err := me.baseGui.SetView(name, x0, y0, x1, y1, overlaps)
if err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
log(logError, "SetView() global failed on name =", name)
}
return nil
}
return v
}

View File

@ -1,71 +0,0 @@
// 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"
"strings"
"github.com/awesome-gocui/gocui"
)
var helpText []string = []string{"KEYBINDINGS",
"",
"?: toggle help",
"d: toggle debugging",
"r: redraw widgets",
"s/h: show/hide all widgets",
"L: list all widgets",
"M: list all widgets positions",
"q: quit()",
"p: panic()",
"o: show Stdout",
"l: log to /tmp/witgui.log",
"Ctrl-D: Toggle Debugging",
"Ctrl-V: Toggle Verbose Debugging",
"Ctrl-C: Exit",
"",
}
func hidehelplayout() {
me.baseGui.DeleteView("help")
// n.deleteView()
// child.hideFake()
}
func helplayout() error {
g := me.baseGui
var err error
maxX, _ := g.Size()
var newW int = 8
for _, s := range(helpText) {
if newW < len(s) {
newW = len(s)
}
}
help, err := g.SetView("help", maxX-(newW + me.FramePadW), 0, maxX-1, len(helpText) + me.FramePadH, 0)
if err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
help.SelBgColor = gocui.ColorGreen
help.SelFgColor = gocui.ColorBlack
// fmt.Fprintln(help, "Enter: Click Button")
// fmt.Fprintln(help, "Tab/Space: Switch Buttons")
// fmt.Fprintln(help, "Backspace: Delete Button")
// fmt.Fprintln(help, "Arrow keys: Move Button")
fmt.Fprintln(help, strings.Join(helpText, "\n"))
if _, err := g.SetCurrentView("help"); err != nil {
return err
}
}
me.helpLabel = help
return nil
}

View File

@ -1,175 +0,0 @@
// 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 (
"os"
"github.com/awesome-gocui/gocui"
"go.wit.com/gui/toolkit"
)
func defaultKeybindings(g *gocui.Gui) error {
if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
return err
}
for _, n := range []string{"but1", "but2", "help", "but3"} {
if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
return err
}
}
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
return err
}
// mouseDown() runs whenever you click on an unknown view (?)
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown); err != nil {
return err
}
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown); err != nil {
return err
}
// if err := g.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click); err != nil {
// return err
// }
/*
if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
return err
}
*/
if err := g.SetKeybinding("msg", gocui.MouseLeft, gocui.ModNone, msgDown); err != nil {
return err
}
addDebugKeys(g)
return nil
}
func addDebugKeys(g *gocui.Gui) {
// show debugging buttons
g.SetKeybinding("", 'd', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
fakeStartWidth = me.FakeW
fakeStartHeight = me.TabH + me.FramePadH
if (showDebug) {
me.rootNode.showFake()
showDebug = false
} else {
me.rootNode.hideFake()
showDebug = true
}
return nil
})
// display the help menu
g.SetKeybinding("", '?', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
if (showHelp) {
helplayout()
showHelp = false
} else {
me.baseGui.DeleteView("help")
showHelp = true
}
return nil
})
// redraw all the widgets
g.SetKeybinding("", 'r', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
if (redoWidgets) {
redoWindows(0,0)
redoWidgets = false
} else {
me.rootNode.hideWidgets()
redoWidgets = true
}
return nil
})
// hide all widgets
g.SetKeybinding("", 'h', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.rootNode.hideWidgets()
return nil
})
// show all widgets
g.SetKeybinding("", 's', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.rootNode.showWidgets()
return nil
})
// list all widgets
g.SetKeybinding("", 'L', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.rootNode.listWidgets()
return nil
})
// list all widgets with positions
g.SetKeybinding("", 'M', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
me.rootNode.dumpTree(true)
return nil
})
// log to output window
g.SetKeybinding("", 'o', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
if me.logStdout.Visible() {
me.logStdout.SetVisible(false)
setOutput(os.Stdout)
} else {
me.logStdout.SetVisible(true)
setOutput(me.logStdout.tk)
}
return nil
})
// exit
g.SetKeybinding("", 'q', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
standardExit()
return nil
})
g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
standardExit()
return nil
})
g.SetKeybinding("", gocui.KeyCtrlD, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
if (showDebug) {
var a toolkit.Action
a.B = true
a.ActionType = toolkit.EnableDebug
callback <- a
logInfo = true
logVerbose = true
} else {
logInfo = false
logVerbose = false
}
return nil
})
g.SetKeybinding("", gocui.KeyCtrlV, gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
if (logVerbose) {
logInfo = false
logVerbose = false
} else {
logInfo = true
logVerbose = true
}
return nil
})
// panic
g.SetKeybinding("", 'p', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
standardExit()
panic("forced panic in gocui")
return nil
})
}

View File

@ -1,56 +0,0 @@
package main
import (
"io"
// "fmt"
// "strings"
witlog "go.wit.com/gui/log"
)
// various debugging flags
var logNow bool = true // useful for active development
var logError bool = true
var logWarn bool = false
var logInfo bool = false
var logVerbose bool = false
var outputS []string
func log(a ...any) {
witlog.Where = "wit/gocui"
witlog.Log(a...)
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
witlog.Exit(a...)
}
/*
func newLog(a ...any) {
s := fmt.Sprint(a...)
tmp := strings.Split(s, "\n")
outputS = append(outputS, tmp...)
if (len(outputS) > 50) {
outputS = outputS[10:]
}
if (me.baseGui != nil) {
v, _ := me.baseGui.View("msg")
if (v != nil) {
v.Clear()
fmt.Fprintln(v, strings.Join(outputS, "\n"))
}
}
}
*/
func setOutput(w io.Writer) {
if (w == nil) {
return
}
witlog.SetOutput(w)
// witlog.SetToolkitOutput(newLog)
}

View File

@ -1,101 +0,0 @@
// 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 (
"os"
"go.wit.com/gui/toolkit"
)
// sets defaults and establishes communication
// to this toolkit from the wit/gui golang package
func init() {
log(logInfo, "Init() of awesome-gocui")
// init the config struct default values
Set(&me, "default")
pluginChan = make(chan toolkit.Action)
log(logNow, "Init() start pluginChan")
go catchActionChannel()
sleep(.1) // probably not needed, but in here for now under development
go main()
sleep(.1) // probably not needed, but in here for now under development
}
/*
recieves requests from the program to do things like:
* add new widgets
* change the text of a label
* etc..
*/
func catchActionChannel() {
log(logInfo, "catchActionChannel() START")
for {
log(logInfo, "catchActionChannel() infinite for() loop restarted select on channel")
select {
case a := <-pluginChan:
if (me.baseGui == nil) {
// something went wrong initializing the gocui
log(logError,"ERROR: console did not initialize")
continue
}
log(logInfo, "catchActionChannel()", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
action(&a)
}
}
}
func Exit() {
// TODO: what should actually happen here?
log(true, "Exit() here. doing standardExit()")
standardExit()
}
func standardExit() {
log(true, "standardExit() doing baseGui.Close()")
me.baseGui.Close()
log(true, "standardExit() doing outf.Close()")
outf.Close()
// log(true, "standardExit() setOutput(os.Stdout)")
// setOutput(os.Stdout)
log(true, "standardExit() send back Quit()")
go sendBackQuit() // don't stall here in case the
// induces a delay in case the callback channel is broken
sleep(1)
log(true, "standardExit() exit()")
exit()
}
func sendBackQuit() {
// send 'Quit' back to the program (?)
var a toolkit.Action
a.ActionType = toolkit.UserQuit
callback <- a
}
var outf *os.File
func main() {
var err error
log(logInfo, "main() start Init()")
outf, err = os.OpenFile("/tmp/witgui.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
if err != nil {
exit("error opening file: %v", err)
}
os.Stdout = outf
defer outf.Close()
// setOutput(outf)
// log("This is a test log entry")
ferr, _ := os.OpenFile("/tmp/witgui.err", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
os.Stderr = ferr
gocuiMain()
log(true, "MouseMain() closed")
standardExit()
}

View File

@ -1,149 +0,0 @@
// 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"
"github.com/awesome-gocui/gocui"
)
// this function uses the mouse position to highlight & unhighlight things
// this is run every time the user moves the mouse over the terminal window
func mouseMove(g *gocui.Gui) {
mx, my := g.MousePosition()
for _, view := range g.Views() {
view.Highlight = false
}
if v, err := g.ViewByPosition(mx, my); err == nil {
v.Highlight = true
}
}
func msgDown(g *gocui.Gui, v *gocui.View) error {
initialMouseX, initialMouseY = g.MousePosition()
log(true, "msgDown() X,Y", initialMouseX, initialMouseY)
if vx, vy, _, _, err := g.ViewPosition("msg"); err == nil {
xOffset = initialMouseX - vx
yOffset = initialMouseY - vy
msgMouseDown = true
}
return nil
}
func hideDDview() error {
w, h := me.baseGui.MousePosition()
log(true, "hide dropdown menu() view msgMouseDown (w,h) =", w, h)
if (me.ddview == nil) {
return gocui.ErrUnknownView
}
if (me.ddview.tk.v == nil) {
return gocui.ErrUnknownView
}
me.ddview.SetVisible(false)
return nil
}
func showDDview() error {
w, h := me.baseGui.MousePosition()
log(true, "show dropdown menu() view msgMouseDown (w,h) =", w, h)
if (me.ddview == nil) {
return gocui.ErrUnknownView
}
if (me.ddview.tk.v == nil) {
return gocui.ErrUnknownView
}
me.ddview.SetVisible(true)
return nil
}
func mouseUp(g *gocui.Gui, v *gocui.View) error {
w, h := g.MousePosition()
log(true, "mouseUp() view msgMouseDown (check here for dropdown menu click) (w,h) =", w, h)
if (me.ddClicked) {
me.ddClicked = false
log(true, "mouseUp() ddview is the thing that was clicked", w, h)
log(true, "mouseUp() find out what the string is here", w, h, me.ddview.tk.gocuiSize.h1)
var newZone string = ""
if (me.ddNode != nil) {
value := h - me.ddview.tk.gocuiSize.h0 - 1
log(true, "mouseUp() me.ddview.tk.gocuiSize.h1 =", me.ddview.tk.gocuiSize.h1)
log(true, "mouseUp() me.ddNode.vals =", me.ddNode.vals)
valsLen := len(me.ddNode.vals)
log(true, "mouseUp() value =", value, "valsLen =", valsLen)
log(true, "mouseUp() me.ddNode.vals =", me.ddNode.vals)
if ((value >= 0) && (value < valsLen)) {
newZone = me.ddNode.vals[value]
log(true, "mouseUp() value =", value, "newZone =", newZone)
}
}
hideDDview()
if (newZone != "") {
if (me.ddNode != nil) {
me.ddNode.SetText(newZone)
me.ddNode.S = newZone
me.ddNode.doUserEvent()
}
}
return nil
}
/*
// if there is a drop down view active, treat it like a dialog box and close it
if (hideDDview() == nil) {
return nil
}
*/
if msgMouseDown {
msgMouseDown = false
if movingMsg {
movingMsg = false
return nil
} else {
g.DeleteView("msg")
}
} else if globalMouseDown {
globalMouseDown = false
g.DeleteView("globalDown")
}
return nil
}
func mouseDown(g *gocui.Gui, v *gocui.View) error {
mx, my := g.MousePosition()
if vx0, vy0, vx1, vy1, err := g.ViewPosition("msg"); err == nil {
if mx >= vx0 && mx <= vx1 && my >= vy0 && my <= vy1 {
return msgDown(g, v)
}
}
globalMouseDown = true
maxX, _ := g.Size()
test := findUnderMouse()
msg := fmt.Sprintf("Mouse really down at: %d,%d", mx, my) + "foobar"
if (test == me.ddview) {
if (me.ddview.Visible()) {
log(true, "hide DDview() Mouse really down at:", mx, my)
hideDDview()
} else {
log(true, "show DDview() Mouse really down at:", mx, my)
showDDview()
}
return nil
}
x := mx - len(msg)/2
if x < 0 {
x = 0
} else if x+len(msg)+1 > maxX-1 {
x = maxX - 1 - len(msg) - 1
}
log(true, "mouseDown() about to write out message to 'globalDown' view. msg =", msg)
if v, err := g.SetView("globalDown", x, my-1, x+len(msg)+1, my+1, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) {
return err
}
v.WriteString(msg)
}
return nil
}

View File

@ -1,186 +0,0 @@
package main
import (
"strings"
"go.wit.com/gui/toolkit"
)
func (n *node) placeBox(startW int, startH int) {
if (n.WidgetType != toolkit.Box) {
return
}
n.showWidgetPlacement(logNow, "boxS()")
newW := startW
newH := startH
for _, child := range n.children {
child.placeWidgets(newW, newH)
// n.showWidgetPlacement(logNow, "boxS()")
newR := child.realGocuiSize()
w := newR.w1 - newR.w0
h := newR.h1 - newR.h0
if (n.horizontal) {
log(logNow, "BOX IS HORIZONTAL", n.Name, "newWH()", newW, newH, "child()", w, h, child.Name)
// expand based on the child width
newW += w
} else {
log(logNow, "BOX IS VERTICAL ", n.Name, "newWH()", newW, newH, "child()", w, h, child.Name)
// expand based on the child height
newH += h
}
}
// just compute this every time?
// newR := n.realGocuiSize()
n.showWidgetPlacement(logNow, "boxE()")
}
func (n *node) placeWidgets(startW int, startH int) {
if (n == nil) {
return
}
if (me.rootNode == nil) {
return
}
switch n.WidgetType {
case toolkit.Window:
for _, child := range n.children {
child.placeWidgets(me.RawW, me.RawH)
return
}
case toolkit.Tab:
for _, child := range n.children {
child.placeWidgets(me.RawW, me.RawH)
return
}
case toolkit.Grid:
n.placeGrid(startW, startH)
case toolkit.Box:
n.placeBox(startW, startH)
case toolkit.Group:
// move the group to the parent's next location
n.gocuiSetWH(startW, startH)
n.showWidgetPlacement(logNow, "group()")
newW := startW + me.GroupPadW
newH := startH + 3 // normal hight of the group label
// now move all the children aka: run place() on them
for _, child := range n.children {
child.placeWidgets(newW, newH)
newR := child.realGocuiSize()
// w := newR.w1 - newR.w0
h := newR.h1 - newR.h0
// increment straight down
newH += h
}
default:
n.gocuiSetWH(startW, startH)
// n.moveTo(startW, startH)
}
}
func (n *node) placeGrid(startW int, startH int) {
w := n.tk
n.showWidgetPlacement(logInfo, "grid0:")
if (n.WidgetType != toolkit.Grid) {
return
}
// first compute the max sizes of the rows and columns
for _, child := range n.children {
newR := child.realGocuiSize()
childW := newR.w1 - newR.w0
childH := newR.h1 - newR.h0
// set the child's realWidth, and grid offset
if (w.widths[child.AtW] < childW) {
w.widths[child.AtW] = childW
}
if (w.heights[child.AtH] < childH) {
w.heights[child.AtH] = childH
}
// child.showWidgetPlacement(logInfo, "grid: ")
log(logVerbose, "placeGrid:", child.Name, "child()", childW, childH, "At()", child.AtW, child.AtH)
}
// find the width and height offset of the grid for AtW,AtH
for _, child := range n.children {
child.showWidgetPlacement(logInfo, "grid1:")
var totalW, totalH int
for i, w := range w.widths {
if (i < child.AtW) {
totalW += w
}
}
for i, h := range w.heights {
if (i < child.AtH) {
totalH += h
}
}
// the new corner to move the child to
newW := startW + totalW
newH := startH + totalH
log(logVerbose, "placeGrid:", child.Name, "new()", newW, newH, "At()", child.AtW, child.AtH)
child.placeWidgets(newW, newH)
child.showWidgetPlacement(logInfo, "grid2:")
}
n.showWidgetPlacement(logInfo, "grid3:")
}
// computes the real, actual size of all the gocli objects in a widget
func (n *node) realGocuiSize() *rectType {
var f func (n *node, r *rectType)
newR := new(rectType)
// initialize the values to opposite
newR.w0 = 80
newR.h0 = 24
if me.baseGui != nil {
maxW, maxH := me.baseGui.Size()
newR.w0 = maxW
newR.h0 = maxH
}
newR.w1 = 0
newR.h1 = 0
// expand the rectangle to the biggest thing displayed
f = func(n *node, r *rectType) {
newR := n.tk.gocuiSize
if ! n.tk.isFake {
if r.w0 > newR.w0 {
r.w0 = newR.w0
}
if r.h0 > newR.h0 {
r.h0 = newR.h0
}
if r.w1 < newR.w1 {
r.w1 = newR.w1
}
if r.h1 < newR.h1 {
r.h1 = newR.h1
}
}
for _, child := range n.children {
f(child, r)
}
}
f(n, newR)
return newR
}
func (n *node) textSize() (int, int) {
var width, height int
for _, s := range strings.Split(n.Text, "\n") {
if (width < len(s)) {
width = len(s)
}
height += 1
}
return width, height
}

View File

@ -1,126 +0,0 @@
package main
import (
// if you include more than just this import
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
"go.wit.com/gui/toolkit"
)
func action(a *toolkit.Action) {
log(logInfo, "action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
n := me.rootNode.findWidgetId(a.WidgetId)
var w *guiWidget
if (n != nil) {
w = n.tk
}
switch a.ActionType {
case toolkit.Add:
if (w == nil) {
n := addNode(a)
// w = n.tk
n.addWidget()
} else {
// this is done to protect the plugin being 'refreshed' with the
// widget binary tree. TODO: find a way to keep them in sync
log(logError, "action() Add ignored for already defined widget",
a.WidgetId, a.ActionType, a.WidgetType, a.Name)
}
case toolkit.Show:
if (a.B) {
n.showView()
} else {
n.hideWidgets()
}
case toolkit.Set:
if a.WidgetType == toolkit.Flag {
log(logNow, "TODO: set flag here", a.ActionType, a.WidgetType, a.Name)
log(logNow, "TODO: n.WidgetType =", n.WidgetType, "n.Name =", a.Name)
} else {
if (a.A == nil) {
log(logError, "TODO: Set here. a == nil", a.ActionType, "WidgetType =", a.WidgetType, "Name =", a.Name)
} else {
n.Set(a.A)
}
}
case toolkit.SetText:
n.SetText(a.S)
case toolkit.AddText:
n.AddText(a.S)
case toolkit.Move:
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
case toolkit.CloseToolkit:
log(logNow, "attempting to close the plugin and release stdout and stderr")
standardExit()
case toolkit.Enable:
if n.Visible() {
// widget was already shown
} else {
log(logInfo, "Setting Visable to true", a.Name)
n.SetVisible(true)
}
case toolkit.Disable:
if n.Visible() {
log(logInfo, "Setting Visable to false", a.Name)
n.SetVisible(false)
} else {
// widget was already hidden
}
default:
log(logError, "action() ActionType =", a.ActionType, "WidgetType =", a.WidgetType, "Name =", a.Name)
}
log(logInfo, "action() END")
}
func (n *node) AddText(text string) {
if (n == nil) {
log(logNow, "widget is nil")
return
}
n.vals = append(n.vals, text)
for i, s := range n.vals {
log(logNow, "AddText()", n.Name, i, s)
}
n.SetText(text)
}
func (n *node) SetText(text string) {
var changed bool = false
if (n == nil) {
log(logNow, "widget is nil")
return
}
if (n.Text != text) {
n.Text = text
changed = true
}
if (n.S != text) {
n.S = text
changed = true
}
if (! changed) {
return
}
if (n.Visible()) {
n.textResize()
n.deleteView()
n.showView()
}
}
func (n *node) Set(val any) {
// w := n.tk
log(logInfo, "Set() value =", val)
switch v := val.(type) {
case bool:
n.B = val.(bool)
n.setCheckbox(val.(bool))
case string:
n.SetText(val.(string))
case int:
n.I = val.(int)
default:
log(logError, "Set() unknown type =", val, v)
}
}

View File

@ -1,97 +0,0 @@
package main
import (
"errors"
"fmt"
"github.com/awesome-gocui/gocui"
"go.wit.com/gui/toolkit"
)
var outputW int = 180
var outputH int = 24
func moveMsg(g *gocui.Gui) {
mx, my := g.MousePosition()
if !movingMsg && (mx != initialMouseX || my != initialMouseY) {
movingMsg = true
}
g.SetView("msg", mx-xOffset, my-yOffset, mx-xOffset+outputW, my-yOffset+outputH + me.FramePadH, 0)
g.SetViewOnBottom("msg")
}
func showMsg(g *gocui.Gui, v *gocui.View) error {
var l string
var err error
log(true, "showMsg() v.name =", v.Name())
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
makeOutputWidget(g, l)
return nil
}
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
maxX, maxY := g.Size()
if (me.rootNode == nil) {
// keep skipping this until the binary tree is initialized
return nil
}
if (me.logStdout == nil) {
a := new(toolkit.Action)
a.Name = "stdout"
a.Text = "stdout"
a.WidgetType = toolkit.Stdout
a.WidgetId = -3
a.ParentId = 0
n := addNode(a)
me.logStdout = n
me.logStdout.tk.gocuiSize.w0 = maxX - 32
me.logStdout.tk.gocuiSize.h0 = maxY/2
me.logStdout.tk.gocuiSize.w1 = me.logStdout.tk.gocuiSize.w0 + outputW
me.logStdout.tk.gocuiSize.h1 = me.logStdout.tk.gocuiSize.h0 + outputH
}
v, err := g.View("msg")
if (v == nil) {
log("makeoutputwindow() this is supposed to happen. v == nil", err)
} else {
log("makeoutputwindow() msg != nil. WTF now? err =", err)
}
// help, err := g.SetView("help", maxX-32, 0, maxX-1, 13, 0)
// v, err = g.SetView("msg", 3, 3, 30, 30, 0)
v, err = g.SetView("msg", maxX-32, maxY/2, maxX/2+outputW, maxY/2+outputH, 0)
if errors.Is(err, gocui.ErrUnknownView) {
log("makeoutputwindow() this is supposed to happen?", err)
}
if (err != nil) {
log("makeoutputwindow() create output window failed", err)
return nil
}
if (v == nil) {
log("makeoutputwindow() msg == nil. WTF now? err =", err)
return nil
} else {
me.logStdout.tk.v = v
}
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")
// g.SetViewOnBottom(v.Name())
return v
}

View File

@ -1,225 +0,0 @@
// LICENSE: same as the go language itself
// Copyright 2023 WIT.COM
// all structures and variables are local (aka lowercase)
// since the plugin should be isolated to access only
// by functions() to insure everything here is run
// inside a dedicated goroutine
package main
import (
"fmt"
"reflect"
"strconv"
"sync"
"strings"
"github.com/awesome-gocui/gocui"
// "go.wit.com/gui/toolkit"
)
// It's probably a terrible idea to call this 'me'
var me config
var showDebug bool = true
var showHelp bool = true
var redoWidgets bool = true
// This is the window that is currently active
var currentWindow *node
type config struct {
baseGui *gocui.Gui // the main gocui handle
rootNode *node // the base of the binary tree. it should have id == 0
ctrlDown *node // shown if you click the mouse when the ctrl key is pressed
currentWindow *node // this is the current tab or window to show
logStdout *node // where to show STDOUT
helpLabel *gocui.View
ddview *node // the gocui view to select dropdrown lists
ddClicked bool // the dropdown menu view was clicked
ddNode *node // the dropdown menu is for this widget
/*
// this is the channel we send user events like
// mouse clicks or keyboard events back to the program
callback chan toolkit.Action
// this is the channel we get requests to make widgets
pluginChan chan toolkit.Action
*/
// When the widget has a frame, like a button, it adds 2 lines runes on each side
// so you need 3 char spacing in each direction to not have them overlap
// the amount of padding when there is a frame
FramePadW int `default:"1" dense:"0"`
FramePadH int `default:"1" dense:"0"`
PadW int `default:"1" dense:"0"`
PadH int `default:"1" dense:"0"`
// how far down to start Window or Tab headings
WindowW int `default:"8" dense:"0"`
WindowH int `default:"-1"`
TabW int `default:"5" dense:"0"`
TabH int `default:"1" dense:"0"`
// additional amount of space to put between window & tab widgets
WindowPadW int `default:"8" dense:"0"`
TabPadW int `default:"4" dense:"0"`
// additional amount of space to indent on a group
GroupPadW int `default:"6" dense:"2"`
// the raw beginning of each window (or tab)
RawW int `default:"1"`
RawH int `default:"5"`
// offset for the hidden widgets
FakeW int `default:"20"`
padded bool // add space between things like buttons
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
menubar bool // for windows
stretchy bool // expand things like buttons to the maximum size
margin bool // add space around the frames of windows
// writeMutex protects locks the write process
writeMutex sync.Mutex
// used for listWidgets() debugging
depth int
}
// deprecate these
var (
initialMouseX, initialMouseY, xOffset, yOffset int
globalMouseDown, msgMouseDown, movingMsg bool
)
// this is the gocui way
// corner starts at in the upper left corner
type rectType struct {
w0, h0, w1, h1 int // left top right bottom
}
func (r *rectType) Width() int {
return r.w1 - r.w0
}
func (r *rectType) Height() int {
return r.h1 - r.h0
}
type guiWidget struct {
// the gocui package variables
v *gocui.View // this is nil if the widget is not displayed
cuiName string // what gocui uses to reference the widget
// the logical size of the widget
// For example, 40x12 would be the center of a normal terminal
// size rectType
// the actual gocui display view of this widget
// sometimes this isn't visible like with a Box or Grid
gocuiSize rectType
isCurrent bool // is this the currently displayed Window or Tab?
isFake bool // widget types like 'box' are 'false'
// used to track the size of grids
widths map[int]int // how tall each row in the grid is
heights map[int]int // how wide each column in the grid is
tainted bool
frame bool
// for a window, this is currently selected tab
selectedTab *node
// what color to use
color *colorT
}
// from the gocui devs:
// Write appends a byte slice into the view's internal buffer. Because
// View implements the io.Writer interface, it can be passed as parameter
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
// be called to clear the view's buffer.
func (w *guiWidget) Write(p []byte) (n int, err error) {
w.tainted = true
me.writeMutex.Lock()
defer me.writeMutex.Unlock()
if (me.logStdout.tk.v == nil) {
// optionally write the output to /tmp
s := fmt.Sprint(string(p))
s = strings.TrimSuffix(s, "\n")
fmt.Fprintln(outf, s)
v, _ := me.baseGui.View("msg")
if (v != nil) {
// fmt.Fprintln(outf, "found msg")
me.logStdout.tk.v = v
}
} else {
// display the output in the gocui window
me.logStdout.tk.v.Clear()
s := fmt.Sprint(string(p))
s = strings.TrimSuffix(s, "\n")
tmp := strings.Split(s, "\n")
outputS = append(outputS, tmp...)
if (len(outputS) > outputH) {
l := len(outputS) - outputH
outputS = outputS[l:]
}
fmt.Fprintln(me.logStdout.tk.v, strings.Join(outputS, "\n"))
}
return len(p), nil
}
func Set(ptr interface{}, tag string) error {
if reflect.TypeOf(ptr).Kind() != reflect.Ptr {
log(logError, "Set() Not a pointer", ptr, "with tag =", tag)
return fmt.Errorf("Not a pointer")
}
v := reflect.ValueOf(ptr).Elem()
t := v.Type()
for i := 0; i < t.NumField(); i++ {
defaultVal := t.Field(i).Tag.Get(tag)
name := t.Field(i).Name
// log("Set() try name =", name, "defaultVal =", defaultVal)
setField(v.Field(i), defaultVal, name)
}
return nil
}
func setField(field reflect.Value, defaultVal string, name string) error {
if !field.CanSet() {
// log("setField() Can't set value", field, defaultVal)
return fmt.Errorf("Can't set value\n")
} else {
log("setField() Can set value", name, defaultVal)
}
switch field.Kind() {
case reflect.Int:
val, _ := strconv.Atoi(defaultVal)
field.Set(reflect.ValueOf(int(val)).Convert(field.Type()))
case reflect.String:
field.Set(reflect.ValueOf(defaultVal).Convert(field.Type()))
case reflect.Bool:
if defaultVal == "true" {
field.Set(reflect.ValueOf(true))
} else {
field.Set(reflect.ValueOf(false))
}
}
return nil
}

View File

@ -1,109 +0,0 @@
package main
// implements widgets 'Window' and 'Tab'
import (
"strings"
"go.wit.com/gui/toolkit"
)
func (w *guiWidget) Width() int {
if w.frame {
return w.gocuiSize.w1 - w.gocuiSize.w0
}
return w.gocuiSize.w1 - w.gocuiSize.w0 - 1
}
func (w *guiWidget) Height() int {
if w.frame {
return w.gocuiSize.h1 - w.gocuiSize.h0
}
return w.gocuiSize.h1 - w.gocuiSize.h0 - 1
}
func (n *node) gocuiSetWH(sizeW, sizeH int) {
w := len(n.Text)
lines := strings.Split(n.Text, "\n")
h := len(lines)
tk := n.tk
if tk.isFake {
tk.gocuiSize.w0 = sizeW
tk.gocuiSize.h0 = sizeH
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
return
}
if tk.frame {
tk.gocuiSize.w0 = sizeW
tk.gocuiSize.h0 = sizeH
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH
} else {
tk.gocuiSize.w0 = sizeW - 1
tk.gocuiSize.h0 = sizeH - 1
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + 1
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + 1
}
}
func redoWindows(nextW int, nextH int) {
for _, n := range me.rootNode.children {
if n.WidgetType != toolkit.Window {
continue
}
w := n.tk
var tabs bool
for _, child := range n.children {
if (child.WidgetType == toolkit.Tab) {
tabs = true
}
}
if (tabs) {
// window is tabs. Don't show it as a standard button
w.frame = false
n.hasTabs = true
} else {
w.frame = false
n.hasTabs = false
}
n.gocuiSetWH(nextW, nextH)
n.deleteView()
n.showView()
sizeW := w.Width() + me.WindowPadW
sizeH := w.Height()
nextW += sizeW
log(logNow, "redoWindows() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, n.Name)
if n.hasTabs {
n.redoTabs(me.TabW, me.TabH)
}
}
}
func (p *node) redoTabs(nextW int, nextH int) {
for _, n := range p.children {
if n.WidgetType != toolkit.Tab {
continue
}
w := n.tk
w.frame = true
n.gocuiSetWH(nextW, nextH)
n.deleteView()
// setCurrentTab(n)
// if (len(w.cuiName) < 4) {
// w.cuiName = "abcd"
// }
n.showView()
sizeW := w.Width() + me.TabPadW
sizeH := w.Height()
log(logNow, "redoTabs() start nextW,H =", nextW, nextH, "gocuiSize.W,H =", sizeW, sizeH, n.Name)
nextW += sizeW
}
}

View File

@ -1,232 +0,0 @@
package main
import (
"fmt"
"errors"
"strconv"
"bufio"
"strings"
"github.com/awesome-gocui/gocui"
"go.wit.com/gui/toolkit"
)
func splitLines(s string) []string {
var lines []string
sc := bufio.NewScanner(strings.NewReader(s))
for sc.Scan() {
lines = append(lines, sc.Text())
}
return lines
}
func (n *node) textResize() bool {
w := n.tk
var width, height int = 0, 0
var changed bool = false
for i, s := range splitLines(n.Text) {
log(logInfo, "textResize() len =", len(s), i, s)
if (width < len(s)) {
width = len(s)
}
height += 1
}
if (w.gocuiSize.w1 != w.gocuiSize.w0 + width + me.FramePadW) {
w.gocuiSize.w1 = w.gocuiSize.w0 + width + me.FramePadW
changed = true
}
if (w.gocuiSize.h1 != w.gocuiSize.h0 + height + me.FramePadH) {
w.gocuiSize.h1 = w.gocuiSize.h0 + height + me.FramePadH
changed = true
}
if (changed) {
n.showWidgetPlacement(logNow, "textResize() changed")
}
return changed
}
func (n *node) hideView() {
n.SetVisible(false)
}
// display's the text of the widget in gocui
// will create a new gocui view if there isn't one or if it has been moved
func (n *node) showView() {
var err error
w := n.tk
if (w.cuiName == "") {
log(logError, "showView() w.cuiName was not set for widget", w)
w.cuiName = strconv.Itoa(n.WidgetId)
}
// if the gocui element doesn't exist, create it
if (w.v == nil) {
n.recreateView()
}
x0, y0, x1, y1, err := me.baseGui.ViewPosition(w.cuiName)
log(logInfo, "showView() w.v already defined for widget", n.Name, err)
// n.smartGocuiSize()
changed := n.textResize()
if (changed) {
log(logNow, "showView() textResize() changed. Should recreateView here wId =", w.cuiName)
} else {
log(logNow, "showView() Clear() and Fprint() here wId =", w.cuiName)
w.v.Clear()
fmt.Fprint(w.v, n.Text)
n.SetVisible(false)
n.SetVisible(true)
return
}
// if the gocui element has changed where it is supposed to be on the screen
// recreate it
if (x0 != w.gocuiSize.w0) {
n.recreateView()
return
}
if (y0 != w.gocuiSize.h0) {
log(logError, "showView() start hight mismatch id=", w.cuiName, "gocui h vs computed h =", w.gocuiSize.h0, y0)
n.recreateView()
return
}
if (x1 != w.gocuiSize.w1) {
log(logError, "showView() too wide", w.cuiName, "w,w", w.gocuiSize.w1, x1)
n.recreateView()
return
}
if (y1 != w.gocuiSize.h1) {
log(logError, "showView() too high", w.cuiName, "h,h", w.gocuiSize.h1, y1)
n.recreateView()
return
}
n.SetVisible(true)
}
// create or recreate the gocui widget visible
// deletes the old view if it exists and recreates it
func (n *node) recreateView() {
var err error
w := n.tk
log(logError, "recreateView() START", n.WidgetType, n.Name)
if (me.baseGui == nil) {
log(logError, "recreateView() ERROR: me.baseGui == nil", w)
return
}
// this deletes the button from gocui
me.baseGui.DeleteView(w.cuiName)
w.v = nil
if (n.Name == "CLOUDFLARE_EMAIL") {
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
n.dumpWidget("jwc")
n.textResize()
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
}
a := w.gocuiSize.w0
b := w.gocuiSize.h0
c := w.gocuiSize.w1
d := w.gocuiSize.h1
w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
if err == nil {
n.showWidgetPlacement(logError, "recreateView()")
log(logError, "recreateView() internal plugin error err = nil")
return
}
if !errors.Is(err, gocui.ErrUnknownView) {
n.showWidgetPlacement(logError, "recreateView()")
log(logError, "recreateView() internal plugin error error.IS()", err)
return
}
// this sets up the keybinding for the name of the window
// does this really need to be done? I think we probably already
// know everything about where all the widgets are so we could bypass
// the gocui package and just handle all the mouse events internally here (?)
// for now, the w.v.Name is a string "1", "2", "3", etc from the widgetId
// set the binding for this gocui view now that it has been created
// gocui handles overlaps of views so it will run on the view that is clicked on
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
// this actually sends the text to display to gocui
w.v.Wrap = true
w.v.Frame = w.frame
w.v.Clear()
fmt.Fprint(w.v, n.Text)
// n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
// n.dumpWidget("jwc 2")
// if you don't do this here, it will be black & white only
if (w.color != nil) {
w.v.FrameColor = w.color.frame
w.v.FgColor = w.color.fg
w.v.BgColor = w.color.bg
w.v.SelFgColor = w.color.selFg
w.v.SelBgColor = w.color.selBg
}
if (n.Name == "CLOUDFLARE_EMAIL") {
n.showWidgetPlacement(logNow, "n.Name=" + n.Name + " n.Text=" + n.Text + " " + w.cuiName)
n.dumpTree(true)
}
log(logError, "recreateView() END")
}
func (n *node) hideWidgets() {
w := n.tk
w.isCurrent = false
switch n.WidgetType {
case toolkit.Root:
case toolkit.Flag:
case toolkit.Window:
case toolkit.Box:
case toolkit.Grid:
default:
n.hideView()
}
for _, child := range n.children {
child.hideWidgets()
}
}
func (n *node) hideFake() {
w := n.tk
if (w.isFake) {
n.hideView()
}
for _, child := range n.children {
child.hideFake()
}
}
func (n *node) showFake() {
w := n.tk
if (w.isFake) {
n.setFake()
n.showWidgetPlacement(logNow, "showFake:")
n.showView()
}
for _, child := range n.children {
child.showFake()
}
}
func (n *node) showWidgets() {
w := n.tk
if (w.isFake) {
// don't display by default
} else {
n.showWidgetPlacement(logInfo, "current:")
n.showView()
}
for _, child := range n.children {
child.showWidgets()
}
}

View File

@ -1,147 +0,0 @@
package main
import (
"strconv"
"go.wit.com/gui/toolkit"
)
func initWidget(n *node) *guiWidget {
var w *guiWidget
w = new(guiWidget)
// Set(w, "default")
w.frame = true
// set the name used by gocui to the id
w.cuiName = strconv.Itoa(n.WidgetId)
if n.WidgetType == toolkit.Root {
log(logInfo, "setupWidget() FOUND ROOT w.id =", n.WidgetId)
n.WidgetId = 0
me.rootNode = n
return w
}
if (n.WidgetType == toolkit.Box) {
if (n.B) {
n.horizontal = true
} else {
n.horizontal = false
}
}
if (n.WidgetType == toolkit.Grid) {
w.widths = make(map[int]int) // how tall each row in the grid is
w.heights = make(map[int]int) // how wide each column in the grid is
}
return w
}
func setupCtrlDownWidget() {
a := new(toolkit.Action)
a.Name = "ctrlDown"
a.WidgetType = toolkit.Dialog
a.WidgetId = -1
a.ParentId = 0
n := addNode(a)
me.ctrlDown = n
}
func (n *node) deleteView() {
w := n.tk
if (w.v != nil) {
w.v.Visible = false
return
}
// make sure the view isn't really there
me.baseGui.DeleteView(w.cuiName)
w.v = nil
}
// searches the binary tree for a WidgetId
func (n *node) findWidgetName(name string) *node {
if (n == nil) {
return nil
}
if n.tk.cuiName == name {
return n
}
for _, child := range n.children {
newN := child.findWidgetName(name)
if (newN != nil) {
return newN
}
}
return nil
}
func (n *node) IsCurrent() bool {
w := n.tk
if (n.WidgetType == toolkit.Tab) {
return w.isCurrent
}
if (n.WidgetType == toolkit.Window) {
return w.isCurrent
}
if (n.WidgetType == toolkit.Root) {
return false
}
return n.parent.IsCurrent()
}
func (n *node) Visible() bool {
if (n == nil) {
return false
}
if (n.tk == nil) {
return false
}
if (n.tk.v == nil) {
return false
}
return n.tk.v.Visible
}
func (n *node) SetVisible(b bool) {
if (n == nil) {
return
}
if (n.tk == nil) {
return
}
if (n.tk.v == nil) {
return
}
n.tk.v.Visible = b
}
func addDropdown() *node {
n := new(node)
n.WidgetType = toolkit.Flag
n.WidgetId = -2
n.ParentId = 0
// copy the data from the action message
n.Name = "DropBox"
n.Text = "DropBox text"
// store the internal toolkit information
n.tk = new(guiWidget)
n.tk.frame = true
// set the name used by gocui to the id
n.tk.cuiName = "-1 dropbox"
n.tk.color = &colorFlag
// add this new widget on the binary tree
n.parent = me.rootNode
if n.parent != nil {
n.parent.children = append(n.parent.children, n)
}
return n
}

View File

@ -1,5 +0,0 @@
all: plugin
ldd ../nocui.so
plugin:
GO111MODULE="off" go build -v -x -buildmode=plugin -o ../nocui.so

View File

@ -1,5 +0,0 @@
# nogui
Package gui implements a abstraction layer for Go visual elements.
This is a sample plugin. It's a skeleton intended to be used when making a new toolkit plugin.

View File

@ -1,153 +0,0 @@
package main
import (
"go.wit.com/gui/toolkit"
)
func (n *node) show(b bool) {
}
func (n *node) enable(b bool) {
}
func (n *node) pad(at toolkit.ActionType) {
switch n.WidgetType {
case toolkit.Group:
switch at {
case toolkit.Margin:
// SetMargined(true)
case toolkit.Unmargin:
// SetMargined(false)
case toolkit.Pad:
// SetMargined(true)
case toolkit.Unpad:
// SetMargined(false)
}
case toolkit.Tab:
case toolkit.Window:
case toolkit.Grid:
case toolkit.Box:
case toolkit.Textbox:
log(logError, "TODO: implement ActionType =", at)
default:
log(logError, "TODO: implement pad() for", at)
}
}
func (n *node) move(newParent *node) {
p := n.parent
switch p.WidgetType {
case toolkit.Group:
case toolkit.Tab:
// tabSetMargined(tParent.uiTab, true)
case toolkit.Window:
// t.uiWindow.SetBorderless(false)
case toolkit.Grid:
// t.uiGrid.SetPadded(true)
case toolkit.Box:
log(logInfo, "TODO: move() where =", p.ParentId)
log(logInfo, "TODO: move() for widget =", n.WidgetId)
default:
log(logError, "TODO: need to implement move() for type =", n.WidgetType)
log(logError, "TODO: need to implement move() for where =", p.ParentId)
log(logError, "TODO: need to implement move() for widget =", n.WidgetId)
}
}
func (n *node) Delete() {
p := n.parent
log(logNow, "uiDelete()", n.WidgetId, "to", p.WidgetId)
switch p.WidgetType {
case toolkit.Group:
// tParent.uiGroup.SetMargined(true)
case toolkit.Tab:
// tabSetMargined(tParent.uiTab, true)
case toolkit.Window:
// t.uiWindow.SetBorderless(false)
case toolkit.Grid:
// t.uiGrid.SetPadded(true)
case toolkit.Box:
log(logNow, "tWidget.boxC =", p.Name)
log(logNow, "is there a tParent parent? =", p.parent)
// this didn't work:
// tWidget.uiControl.Disable()
// sleep(.8)
// tParent.uiBox.Append(tWidget.uiControl, stretchy)
default:
log(logError, "TODO: need to implement uiDelete() for widget =", n.WidgetId, n.WidgetType)
log(logError, "TODO: need to implement uiDelete() for parent =", p.WidgetId, p.WidgetType)
}
}
func doAction(a *toolkit.Action) {
log(logNow, "doAction() START a.ActionType =", a.ActionType)
log(logNow, "doAction() START a.S =", a.S)
if (a.ActionType == toolkit.InitToolkit) {
// TODO: make sure to only do this once
// go uiMain.Do(func() {
// ui.Main(demoUI)
// go catchActionChannel()
// })
// try doing this on toolkit load in init()
return
}
log(logNow, "doAction() START a.WidgetId =", a.WidgetId, "a.ParentId =", a.ParentId)
switch a.WidgetType {
case toolkit.Root:
me.rootNode = addNode(a)
log(logNow, "doAction() found rootNode")
return
case toolkit.Flag:
// flag(&a)
return
}
n := me.rootNode.findWidgetId(a.WidgetId)
switch a.ActionType {
case toolkit.Add:
addNode(a)
case toolkit.Show:
n.show(true)
case toolkit.Hide:
n.show(false)
case toolkit.Enable:
n.enable(true)
case toolkit.Disable:
n.enable(false)
case toolkit.Get:
// n.setText(a.S)
case toolkit.GetText:
switch a.WidgetType {
case toolkit.Textbox:
a.S = n.S
}
case toolkit.Set:
// n.setText(a.S)
case toolkit.SetText:
// n.setText(a.S)
case toolkit.AddText:
// n.setText(a.S)
case toolkit.Margin:
n.pad(toolkit.Unmargin)
case toolkit.Unmargin:
n.pad(toolkit.Margin)
case toolkit.Pad:
n.pad(toolkit.Pad)
case toolkit.Unpad:
n.pad(toolkit.Unpad)
case toolkit.Delete:
n.Delete()
case toolkit.Move:
log(logNow, "doAction() attempt to move() =", a.ActionType, a.WidgetType)
newParent := me.rootNode.findWidgetId(a.ParentId)
n.move(newParent)
default:
log(logError, "doAction() Unknown =", a.ActionType, a.WidgetType)
}
log(logInfo, "doAction() END =", a.ActionType, a.WidgetType)
}

Some files were not shown because too many files have changed in this diff Show More