gocui: working towards correct layout

make a gocui widget binary tree
    more debugging cleanups
    sample button app displays in gocui
    geometry logic closer to correct
    improvements in gocui layout
    continued attempts to clean up tabs
    dump binary tree
    moving towards proper chan callback()
    deprecate Widget.Name

Signed-off-by: Jeff Carr <jcarr@wit.com>
This commit is contained in:
Jeff Carr 2023-04-03 10:26:47 -05:00
parent 678b867f1e
commit 7f907e2b19
67 changed files with 1208 additions and 1546 deletions

View File

@ -73,14 +73,11 @@ clean:
rm -f toolkit/*.so rm -f toolkit/*.so
cd debian && make clean cd debian && make clean
plugins: plugins-gocui plugins-democui plugins-andlabs plugins: plugins-gocui plugins-andlabs
plugins-gocui: plugins-gocui:
make -C toolkit/gocui make -C toolkit/gocui
plugins-democui:
make -C toolkit/democui
plugins-andlabs: plugins-andlabs:
cd toolkit/andlabs/ && GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so cd toolkit/andlabs/ && GO111MODULE="off" go build -buildmode=plugin -o ../andlabs.so
# make -C toolkit/andlabs # make -C toolkit/andlabs

View File

@ -123,7 +123,7 @@ Creates a window helpful for debugging this package
`func ExampleCatcher(f func())` `func ExampleCatcher(f func())`
### func [Indent](/debug.go#L125) ### func [Indent](/debug.go#L120)
`func Indent(b bool, a ...interface{})` `func Indent(b bool, a ...interface{})`

View File

@ -15,6 +15,35 @@ func (n *Node) NewButton(name string, custom func()) *Node {
return newNode return newNode
} }
func callback(i int) { func callback(i int) bool {
log(debugError, "button callback() i =", i) log(debugError, "callback() for widget id =", i)
n := Config.rootNode.FindId(i)
log(debugError, "callback() found node =", n)
// running custom here means the button get's clicked twice
if (n.Custom == nil) {
log(debugError, "callback() = nil. SKIPPING")
return false
}
n.Custom()
return true
} }
// find widget by number
func (n *Node) FindId(i int) (*Node) {
if (n == nil) {
return nil
}
if (n.id == i) {
return n
}
for _, child := range n.children {
newN := child.FindId(i)
if (newN != nil) {
return newN
}
}
return nil
}

View File

@ -7,7 +7,6 @@
# #
run: build run: build
# ./buttonplugin >/tmp/buttonplugin.log 2>&1
./buttonplugin >/tmp/witgui.log.stderr 2>&1 ./buttonplugin >/tmp/witgui.log.stderr 2>&1
build-release: build-release:

View File

@ -58,6 +58,12 @@ func buttonWindow() {
w = gui.NewWindow() w = gui.NewWindow()
t = w.NewTab("buttonTab") t = w.NewTab("buttonTab")
g = t.NewGroup("buttonGroup") g = t.NewGroup("buttonGroup")
g1 := t.NewGroup("buttonGroup 2")
more = g1.NewGroup("more")
g1.NewButton("hello2", func () {
log.Println("world2")
})
more2 = g1.NewGroup("more2")
g.NewButton("this app is useful for plugin debuggin", func () { g.NewButton("this app is useful for plugin debuggin", func () {
}) })
@ -66,17 +72,16 @@ func buttonWindow() {
g.NewButton("hello", func () { g.NewButton("hello", func () {
log.Println("world") log.Println("world")
}) })
more = g.NewGroup("more")
g.NewButton("Load 'democui'", func () { g.NewButton("Load 'gocui'", func () {
// this set the xterm and mate-terminal window title. maybe works generally? // this set the xterm and mate-terminal window title. maybe works generally?
fmt.Println("\033]0;" + title + "blah \007") fmt.Println("\033]0;" + title + "blah \007")
gui.StartS("democui") gui.StartS("gocui")
}) })
g.NewButton("Redraw 'democui'", func () { g.NewButton("Redraw 'gocui'", func () {
fmt.Println("\033]0;" + title + "blah2 \007") fmt.Println("\033]0;" + title + "blah2 \007")
gui.Redraw("democui") gui.Redraw("gocui")
}) })
g.NewButton("NewButton(more)", func () { g.NewButton("NewButton(more)", func () {
@ -107,6 +112,4 @@ func buttonWindow() {
g.NewButton("gui.DebugWindow()", func () { g.NewButton("gui.DebugWindow()", func () {
gui.DebugWindow() gui.DebugWindow()
}) })
more2 = g.NewGroup("more2")
} }

View File

@ -8,7 +8,6 @@ import (
func main() { func main() {
gui.InitPlugins([]string{"gocui"}) gui.InitPlugins([]string{"gocui"})
// gui.InitPlugins([]string{"democui"})
gui.Main(helloworld) gui.Main(helloworld)
} }

View File

@ -26,7 +26,6 @@ func main() {
// gui.SetDebug(true) // gui.SetDebug(true)
// gui.InitPlugins([]string{"gocui"}) // gui.InitPlugins([]string{"gocui"})
// gui.InitPlugins([]string{"democui"})
gui.Main(initGUI) gui.Main(initGUI)
} }

View File

@ -102,11 +102,6 @@ func (n *Node) Dump(b bool) {
Indent(b, "Height = ", n.Height) Indent(b, "Height = ", n.Height)
Indent(b, "(X,Y) = ", n.X, n.Y) Indent(b, "(X,Y) = ", n.X, n.Y)
Indent(b, "Next (X,Y) = ", n.NextX, n.NextY) Indent(b, "Next (X,Y) = ", n.NextX, n.NextY)
/*
Indent(b, "Widget Name = ", n.widget.Name)
Indent(b, "Widget Type = ", n.widget.Type)
Indent(b, "Widget Id = ", n.widget.Id)
*/
if (n.parent == nil) { if (n.parent == nil) {
Indent(b, "parent = nil") Indent(b, "parent = nil")
@ -133,13 +128,9 @@ func (n *Node) dumpWidget(b bool) string {
log(debugError, "dumpWidget() node == nil") log(debugError, "dumpWidget() node == nil")
return "" return ""
} }
info = n.widget.Type.String() info = n.WidgetType.String()
info += ", " + n.widget.Name if (n.WidgetType == toolkit.Checkbox) {
if (n.Name != n.widget.Name) {
info += " NAME MISMATCH"
}
if (n.widget.Type == toolkit.Checkbox) {
info += " = " + strconv.FormatBool(n.widget.B) info += " = " + strconv.FormatBool(n.widget.B)
} }

View File

@ -39,7 +39,7 @@ func (n *Node) DebugFlags(makeWindow bool) {
g.NewLabel("like verbose=1") g.NewLabel("like verbose=1")
cb1.Custom = func() { cb1.Custom = func() {
debugGui = cb1.widget.B debugGui = cb1.widget.B
log(debugGui, "Custom() n.widget =", cb1.widget.Name, cb1.widget.B) log(debugGui, "Custom() n.widget =", cb1.Name, cb1.widget.B)
} }
// errors. by default these always output somewhere // errors. by default these always output somewhere

View File

@ -43,7 +43,7 @@ func setActiveWidget(w *Node) {
// TODO: make a fake binary tree for this(?) // TODO: make a fake binary tree for this(?)
return return
} }
title := "ID =" + strconv.Itoa(w.id) + " " + w.widget.Name title := "ID =" + strconv.Itoa(w.id) + " " + w.Name
activeLabel.SetText(title) activeLabel.SetText(title)
activeLabelType.SetText("widget.Type = " + w.widget.Type.String()) activeLabelType.SetText("widget.Type = " + w.widget.Type.String())
return return
@ -180,7 +180,7 @@ func (n *Node) debugAddWidgetButtons() {
a.AddText("make something for tim for qflow") a.AddText("make something for tim for qflow")
a.AddText("and for riscv") a.AddText("and for riscv")
a.Custom = func () { a.Custom = func () {
log("custom dropdown() a =", a.widget.Name, a.widget.S, "id=", a.id) log("custom dropdown() a =", a.Name, a.widget.S, "id=", a.id)
} }
}) })
n.NewButton("Combobox", func () { n.NewButton("Combobox", func () {
@ -188,7 +188,7 @@ func (n *Node) debugAddWidgetButtons() {
a.AddText("mirrors.wit.com") a.AddText("mirrors.wit.com")
a.AddText("go.wit.com") a.AddText("go.wit.com")
a.Custom = func () { a.Custom = func () {
log("custom combobox() a =", a.widget.Name, a.widget.S, "id=", a.id) log("custom combobox() a =", a.Name, a.widget.S, "id=", a.id)
} }
}) })
n.NewButton("Grid", func () { n.NewButton("Grid", func () {

View File

@ -40,7 +40,7 @@ func (n *Node) DebugTab(title string) *Node {
cb := gog.NewCheckbox("Seperate windows") cb := gog.NewCheckbox("Seperate windows")
cb.Custom = func() { cb.Custom = func() {
makeTabs = cb.widget.B makeTabs = cb.widget.B
log(debugGui, "Custom() n.widget =", cb.widget.Name, cb.widget.B) log(debugGui, "Custom() n.widget =", cb.Name, cb.widget.B)
} }
makeTabs = false makeTabs = false
cb.Set(false) cb.Set(false)
@ -97,12 +97,8 @@ func (n *Node) DebugTab(title string) *Node {
StartS("gocui") StartS("gocui")
}) })
g2.NewButton("load plugin 'democui'", func () { g2.NewButton("Redraw(gocui)", func () {
StartS("democui") Redraw("gocui")
})
g2.NewButton("Redraw(democui)", func () {
Redraw("democui")
}) })
return newN return newN

View File

@ -36,6 +36,7 @@ func (n *Node) NewGrid(name string, x int, y int) *Node {
func (n *Node) NewBox(name string, b bool) *Node { func (n *Node) NewBox(name string, b bool) *Node {
newNode := n.New(name, toolkit.Box, nil) newNode := n.New(name, toolkit.Box, nil)
newNode.B = b
var a toolkit.Action var a toolkit.Action
a.ActionType = toolkit.Add a.ActionType = toolkit.Add

View File

@ -13,6 +13,8 @@ func (n *Node) NewGroup(name string) *Node {
var a toolkit.Action var a toolkit.Action
a.ActionType = toolkit.Add a.ActionType = toolkit.Add
a.Name = name
a.Text = name
newaction(&a, newNode, n) newaction(&a, newNode, n)
newBox := newNode.NewBox("group vBox", false) newBox := newNode.NewBox("group vBox", false)

View File

@ -26,10 +26,10 @@ func (n *Node) New(title string, t toolkit.WidgetType, custom func()) *Node {
log(debugChange, "newT.Custom() == nil. Not doing anything. SEND SOMETHING TO THE CHANNEL") log(debugChange, "newT.Custom() == nil. Not doing anything. SEND SOMETHING TO THE CHANNEL")
return return
} }
log(debugChange, "newT.Custom() START SEND SOMETHING TO THE CHANNEL widget.Name =", newN.widget.Name) log(debugChange, "newT.Custom() START SEND SOMETHING TO THE CHANNEL node =", newN.Name)
// send something to the channel here???? // send something to the channel here????
newN.Custom() newN.Custom()
log(debugChange, "newT.Custom() END SEND SOMETHING TO THE CHANNEL widget.Name =", newN.widget.Name) log(debugChange, "newT.Custom() END SEND SOMETHING TO THE CHANNEL node =", newN.Name)
} }
n.Append(newN) n.Append(newN)
@ -44,7 +44,6 @@ func addNode(title string) *Node {
n := new(Node) n := new(Node)
n.Name = title n.Name = title
n.Text = title n.Text = title
n.widget.Name = title
n.id = Config.counter n.id = Config.counter
n.widget.Id = n.id n.widget.Id = n.id
log(debugNode, "addNode = widget setid =", n.id) log(debugNode, "addNode = widget setid =", n.id)

View File

@ -37,18 +37,35 @@ func (n *Node) Redraw(p *aplug) {
} }
func (n *Node) redo(p *aplug) { func (n *Node) redo(p *aplug) {
log(logNow, "redo() on n.Widget") log(logNow, "redo()", n.id, n.WidgetType, n.Name)
var a *toolkit.Action var a *toolkit.Action
a = new(toolkit.Action) a = new(toolkit.Action)
a.Name = n.Name a.Name = n.Name
a.Text = n.Text a.Text = n.Text
a.ActionType = toolkit.Add a.ActionType = toolkit.Add
a.WidgetType = n.WidgetType a.WidgetType = n.WidgetType
a.WidgetId = n.id a.WidgetId = n.id
// used for Windows
a.Width = n.Width a.Width = n.Width
a.Height = n.Height a.Height = n.Height
// used for anything that needs a range
a.X = n.X
a.Y = n.Y
// used for grids and tables
// a.NextX = n.NextX
// a.NextY = n.NextY
// used for values
a.I = n.I
a.S = n.S
a.B = n.B
if (n.parent == nil) { if (n.parent == nil) {
a.ParentId = 0 a.ParentId = 0
} else { } else {

View File

@ -57,7 +57,7 @@ func pad(a *toolkit.Action) {
return return
} }
switch t.Type { switch t.WidgetType {
case toolkit.Group: case toolkit.Group:
switch a.ActionType { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
@ -138,7 +138,7 @@ func move(a *toolkit.Action) {
return return
} }
switch tParent.Type { switch tParent.WidgetType {
case toolkit.Group: case toolkit.Group:
switch a.ActionType { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:
@ -202,7 +202,7 @@ func uiDelete(a *toolkit.Action) {
return return
} }
switch tParent.Type { switch tParent.WidgetType {
case toolkit.Group: case toolkit.Group:
switch a.ActionType { switch a.ActionType {
case toolkit.Margin: case toolkit.Margin:

View File

@ -121,7 +121,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
if (andlabs[a.WidgetId] == nil) { if (andlabs[a.WidgetId] == nil) {
log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId) log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId)
andlabs[a.WidgetId] = newt andlabs[a.WidgetId] = newt
newt.Type = a.WidgetType newt.WidgetType = a.WidgetType
} else { } else {
log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId) log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId)
log(debugError, "THIS IS BAD") log(debugError, "THIS IS BAD")
@ -138,7 +138,7 @@ func place(a *toolkit.Action, t *andlabsT, newt *andlabsT) bool {
return false return false
} }
switch where.Type { switch where.WidgetType {
case toolkit.Grid: case toolkit.Grid:
log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y) log(debugGrid, "add() Grid try at Parent X,Y =", a.X, a.Y)
newt.gridX = a.X newt.gridX = a.X

View File

@ -24,7 +24,7 @@ func newButton(a *toolkit.Action) {
newt.uiButton = b newt.uiButton = b
newt.uiControl = b newt.uiControl = b
newt.tw = a.Widget newt.tw = a.Widget
newt.Type = a.WidgetType newt.WidgetType = a.WidgetType
newt.parent = t newt.parent = t
b.OnClicked(func(*ui.Button) { b.OnClicked(func(*ui.Button) {

View File

@ -9,12 +9,14 @@ import (
func (t *andlabsT) newCheckbox(a *toolkit.Action) *andlabsT { func (t *andlabsT) newCheckbox(a *toolkit.Action) *andlabsT {
var newt andlabsT var newt andlabsT
w := a.Widget w := a.Widget
log(debugToolkit, "newCheckbox()", w.Name, w.Type) log(debugToolkit, "newCheckbox()", a.Name, a.WidgetType)
newt.tw = w newt.tw = w
newt.Type = w.Type newt.WidgetType = a.WidgetType
newt.wId = a.WidgetId newt.wId = a.WidgetId
newt.Name = a.Name
newt.Text = a.Text
newt.uiCheckbox = ui.NewCheckbox(w.Name) newt.uiCheckbox = ui.NewCheckbox(a.Text)
newt.uiControl = newt.uiCheckbox newt.uiControl = newt.uiCheckbox
newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) { newt.uiCheckbox.OnToggled(func(spin *ui.Checkbox) {

View File

@ -9,11 +9,11 @@ import (
func (t *andlabsT) newCombobox(a *toolkit.Action) *andlabsT { func (t *andlabsT) newCombobox(a *toolkit.Action) *andlabsT {
var newt andlabsT var newt andlabsT
w := a.Widget w := a.Widget
log(debugToolkit, "newCombobox() START", w.Name) log(debugToolkit, "newCombobox() START", a.Name)
newt.tw = w newt.tw = w
newt.wId = a.WidgetId newt.wId = a.WidgetId
newt.Type = w.Type newt.WidgetType = a.WidgetType
s := ui.NewEditableCombobox() s := ui.NewEditableCombobox()
newt.uiEditableCombobox = s newt.uiEditableCombobox = s
newt.uiControl = s newt.uiControl = s

View File

@ -5,13 +5,17 @@ import (
) )
func (t *andlabsT) commonChange(tw *toolkit.Widget, wId int) { func (t *andlabsT) commonChange(tw *toolkit.Widget, wId int) {
log(debugChange, "commonChange() START widget =", t.tw.Name, t.tw.Type) log(debugChange, "commonChange() START widget =", t.Name, t.WidgetType)
if (sendToChan(wId)) {
log(debugChange, "commonChange() END attempted channel worked", t.Name, t.WidgetType)
return
}
if (tw == nil) { if (tw == nil) {
log(true, "commonChange() What the fuck. there is no widget t.tw == nil") log(true, "commonChange() What the fuck. there is no widget t.tw == nil")
return return
} }
if (tw.Custom == nil) { if (tw.Custom == nil) {
log(debugChange, "commonChange() END Widget.Custom() = nil", t.tw.Name, t.tw.Type) log(debugChange, "commonChange() END Widget.Custom() = nil", t.Name, t.WidgetType)
return return
} }
tw.Custom() tw.Custom()
@ -20,16 +24,15 @@ func (t *andlabsT) commonChange(tw *toolkit.Widget, wId int) {
log(debugError, "commonChange() ERROR: wId map == nil", wId) log(debugError, "commonChange() ERROR: wId map == nil", wId)
return return
} }
sendToChan(wId)
log(debugChange, "commonChange() END Widget.Custom()", t.tw.Name, t.tw.Type) log(debugChange, "commonChange() END Widget.Custom()", t.Name, t.WidgetType)
} }
func sendToChan(i int) { func sendToChan(i int) bool {
if (callback == nil) { if (callback == nil) {
log(debugError, "commonChange() SHOULD SEND int back here, but callback == nil", i) log(debugError, "commonChange() SHOULD SEND int back here, but callback == nil", i)
return return false
} }
log(debugError, "commonChange() Running callback() i =", i) log(debugError, "commonChange() Running callback() i =", i)
callback(i) return callback(i)
} }

View File

@ -18,7 +18,7 @@ func destroy(pId int, cId int) {
return return
} }
switch ct.Type { switch ct.WidgetType {
case toolkit.Button: case toolkit.Button:
log(true, "Should delete Button here:", ct.Name) log(true, "Should delete Button here:", ct.Name)
log(true, "Parent:") log(true, "Parent:")
@ -40,8 +40,8 @@ func destroy(pId int, cId int) {
case toolkit.Window: case toolkit.Window:
log(true, "Should delete Window here:", ct.Name) log(true, "Should delete Window here:", ct.Name)
default: default:
log(true, "Don't know how to delete pt =", pt.tw.Type, pt.tw.Name, pt.uiButton) log(true, "Don't know how to delete pt =", pt.WidgetType, pt.Name, pt.uiButton)
log(true, "Don't know how to delete ct =", ct.tw.Type, ct.tw.Name, ct.uiButton) log(true, "Don't know how to delete ct =", ct.WidgetType, ct.Name, ct.uiButton)
log(true, "Parent:") log(true, "Parent:")
pt.Dump(true) pt.Dump(true)
log(true, "Child:") log(true, "Child:")

View File

@ -12,7 +12,7 @@ func (t *andlabsT) newDropdown(a *toolkit.Action) *andlabsT {
log(debugToolkit, "gui.Toolbox.newDropdown() START", a.Name) log(debugToolkit, "gui.Toolbox.newDropdown() START", a.Name)
newt.tw = w newt.tw = w
newt.Type = w.Type newt.WidgetType = a.WidgetType
newt.wId = a.WidgetId newt.wId = a.WidgetId
s := ui.NewCombobox() s := ui.NewCombobox()
newt.uiCombobox = s newt.uiCombobox = s
@ -60,7 +60,7 @@ func AddDropdownName(a *toolkit.Action) {
t := andlabs[a.WidgetId] t := andlabs[a.WidgetId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", a.Widget.Name, a.S) log(debugToolkit, "go.andlabs.AddDropdownName() toolkit struct == nil. name=", a.Name, a.S)
listMap(debugToolkit) listMap(debugToolkit)
return return
} }

View File

@ -22,7 +22,7 @@ func newGrid(a *toolkit.Action) {
newt.uiGrid = c newt.uiGrid = c
newt.uiControl = c newt.uiControl = c
newt.tw = a.Widget newt.tw = a.Widget
newt.Type = toolkit.Grid newt.WidgetType = toolkit.Grid
newt.gridX = 0 newt.gridX = 0
newt.gridY = 0 newt.gridY = 0

View File

@ -8,15 +8,15 @@ import (
) )
func newGroup(a *toolkit.Action) { func newGroup(a *toolkit.Action) {
w := a.Widget // w := a.Widget
log(debugToolkit, "NewGroup()", w.Name) log(debugToolkit, "NewGroup()", a.Name)
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "NewGroup() toolkit struct == nil. name=", w.Name) log(debugToolkit, "NewGroup() toolkit struct == nil. name=", a.Name)
listMap(debugToolkit) listMap(debugToolkit)
} }
newt := t.rawGroup(w.Name) newt := t.rawGroup(a.Name)
place(a, t, newt) place(a, t, newt)
} }

View File

@ -9,15 +9,14 @@ import (
// make new Image here // make new Image here
func newImage(a *toolkit.Action) { func newImage(a *toolkit.Action) {
w := a.Widget log(debugToolkit, "newImage()", a.Name)
log(debugToolkit, "newImage()", w.Name)
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "newImage() toolkit struct == nil. name=", w.Name) log(debugToolkit, "newImage() toolkit struct == nil. name=", a.Name)
listMap(debugToolkit) listMap(debugToolkit)
} }
newt := t.rawImage(w.Name) newt := t.rawImage(a.Name)
place(a, t, newt) place(a, t, newt)
} }
@ -37,7 +36,7 @@ func (t *andlabsT) rawImage(title string) *andlabsT {
return &newt return &newt
} }
/* /*
if (w.Name == "image") { if (a.Name == "image") {
log(true, "NewTextbox() trying to add a new image") log(true, "NewTextbox() trying to add a new image")
i := ui.NewImage(16, 16) i := ui.NewImage(16, 16)
img, _, err := image.Decode(bytes.NewReader(rawImage)) img, _, err := image.Decode(bytes.NewReader(rawImage))

View File

@ -9,8 +9,7 @@ import (
func newLabel(a *toolkit.Action) { func newLabel(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget log(debugToolkit, "NewLabel()", a.Name)
log(debugToolkit, "NewLabel()", w.Name)
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
@ -21,11 +20,11 @@ func newLabel(a *toolkit.Action) {
return return
} }
log(debugToolkit, "NewLabel()", w.Name) log(debugToolkit, "NewLabel()", a.Name)
newt = new(andlabsT) newt = new(andlabsT)
c := ui.NewLabel(w.Name) c := ui.NewLabel(a.Name)
newt.uiLabel = c newt.uiLabel = c
newt.uiControl = c newt.uiControl = c

View File

@ -138,9 +138,9 @@ func setText(a *toolkit.Action) {
actionDump(debugError, a) actionDump(debugError, a)
return return
} }
log(debugChange, "setText() Attempt on", t.Type, "with", a.S) log(debugChange, "setText() Attempt on", t.WidgetType, "with", a.S)
switch t.Type { switch t.WidgetType {
case toolkit.Window: case toolkit.Window:
t.uiWindow.SetTitle(a.S) t.uiWindow.SetTitle(a.S)
case toolkit.Tab: case toolkit.Tab:
@ -157,7 +157,7 @@ func setText(a *toolkit.Action) {
// t.uiCheckbox.SetChecked(a.B) // t.uiCheckbox.SetChecked(a.B)
t.tw.B = a.B t.tw.B = a.B
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
case toolkit.Textbox: case toolkit.Textbox:
switch a.ActionType { switch a.ActionType {
@ -170,7 +170,7 @@ func setText(a *toolkit.Action) {
case toolkit.GetText: case toolkit.GetText:
t.tw.S = t.s t.tw.S = t.s
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
case toolkit.Label: case toolkit.Label:
t.uiLabel.SetText(a.S) t.uiLabel.SetText(a.S)
@ -183,7 +183,7 @@ func setText(a *toolkit.Action) {
case toolkit.Set: case toolkit.Set:
t.uiSlider.SetValue(a.I) t.uiSlider.SetValue(a.I)
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
case toolkit.Spinner: case toolkit.Spinner:
switch a.ActionType { switch a.ActionType {
@ -192,7 +192,7 @@ func setText(a *toolkit.Action) {
case toolkit.Set: case toolkit.Set:
t.uiSpinbox.SetValue(a.I) t.uiSpinbox.SetValue(a.I)
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
case toolkit.Dropdown: case toolkit.Dropdown:
switch a.ActionType { switch a.ActionType {
@ -227,7 +227,7 @@ func setText(a *toolkit.Action) {
case toolkit.GetText: case toolkit.GetText:
t.tw.S = t.s t.tw.S = t.s
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
case toolkit.Combobox: case toolkit.Combobox:
switch a.ActionType { switch a.ActionType {
@ -244,9 +244,9 @@ func setText(a *toolkit.Action) {
case toolkit.GetText: case toolkit.GetText:
t.tw.S = t.s t.tw.S = t.s
default: default:
log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.tw.Name) log(debugError, "setText() unknown", a.ActionType, "on checkbox", t.Name)
} }
default: default:
log(debugError, "plugin Send() Don't know how to setText on", t.tw.Type, "yet", a.ActionType) log(debugError, "plugin Send() Don't know how to setText on", t.WidgetType, "yet", a.ActionType)
} }
} }

View File

@ -10,13 +10,12 @@ import (
func (t *andlabsT) newSlider(a *toolkit.Action) *andlabsT { func (t *andlabsT) newSlider(a *toolkit.Action) *andlabsT {
var newt andlabsT var newt andlabsT
w := a.Widget w := a.Widget
// log(debugToolkit, w.Name, w.Type, w.X, w.Y)
s := ui.NewSlider(a.X, a.Y) s := ui.NewSlider(a.X, a.Y)
newt.uiSlider = s newt.uiSlider = s
newt.uiControl = s newt.uiControl = s
newt.tw = w newt.tw = w
newt.Type = toolkit.Slider newt.WidgetType = toolkit.Slider
newt.wId = a.WidgetId newt.wId = a.WidgetId
s.OnChanged(func(spin *ui.Slider) { s.OnChanged(func(spin *ui.Slider) {
@ -29,16 +28,13 @@ func (t *andlabsT) newSlider(a *toolkit.Action) *andlabsT {
func newSlider(a *toolkit.Action) { func newSlider(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget log(debugToolkit, "newSlider()", a.Name)
log(debugToolkit, "newSlider()", w.Name)
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugError, "newSlider() ERROR toolkit struct == nil. name=", w.Name) log(debugError, "newSlider() ERROR toolkit struct == nil. name=", a.Name)
return return
} }
// w.X = a.X
// w.Y = a.Y
newt = t.newSlider(a) newt = t.newSlider(a)
place(a, t, newt) place(a, t, newt)
} }

View File

@ -17,7 +17,7 @@ func (t *andlabsT) newSpinner(a *toolkit.Action) *andlabsT {
newt.uiControl = s newt.uiControl = s
newt.tw = w newt.tw = w
newt.wId = a.WidgetId newt.wId = a.WidgetId
newt.Type = toolkit.Spinner newt.WidgetType = toolkit.Spinner
s.OnChanged(func(s *ui.Spinbox) { s.OnChanged(func(s *ui.Spinbox) {
newt.tw.I = newt.uiSpinbox.Value() newt.tw.I = newt.uiSpinbox.Value()
@ -29,11 +29,10 @@ func (t *andlabsT) newSpinner(a *toolkit.Action) *andlabsT {
func newSpinner(a *toolkit.Action) { func newSpinner(a *toolkit.Action) {
var newt *andlabsT var newt *andlabsT
w := a.Widget
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugError, "NewSpinner() toolkit struct == nil. name=", w.Name) log(debugError, "NewSpinner() toolkit struct == nil. name=", a.Name)
return return
} }
newt = t.newSpinner(a) newt = t.newSpinner(a)

View File

@ -6,14 +6,15 @@ import "github.com/andlabs/ui"
import _ "github.com/andlabs/ui/winmanifest" import _ "github.com/andlabs/ui/winmanifest"
var andlabs map[int]*andlabsT var andlabs map[int]*andlabsT
var callback func(int) var callback func(int) bool
// stores the raw toolkit internals // stores the raw toolkit internals
type andlabsT struct { type andlabsT struct {
wId int // widget ID wId int // widget ID
Type toolkit.WidgetType WidgetType toolkit.WidgetType
Name string Name string
Text string
// Type toolkit.WidgetType // Type toolkit.WidgetType
Width int Width int
Height int Height int

View File

@ -44,7 +44,7 @@ func (t *andlabsT) newTab(a *toolkit.Action) {
if (andlabs[a.WidgetId] == nil) { if (andlabs[a.WidgetId] == nil) {
log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId) log(logInfo, "newTab() MAPPED", a.WidgetId, a.ParentId)
andlabs[a.WidgetId] = newt andlabs[a.WidgetId] = newt
newt.Type = a.Widget.Type newt.WidgetType = a.WidgetType
} else { } else {
log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId) log(debugError, "newTab() DO WHAT?", a.WidgetId, a.ParentId)
log(debugError, "THIS IS BAD") log(debugError, "THIS IS BAD")

View File

@ -15,9 +15,8 @@ func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
newt.uiMultilineEntry = c newt.uiMultilineEntry = c
newt.uiControl = c newt.uiControl = c
newt.Name = w.Name
newt.tw = w newt.tw = w
newt.Type = toolkit.Textbox newt.WidgetType = toolkit.Textbox
c.OnChanged(func(spin *ui.MultilineEntry) { c.OnChanged(func(spin *ui.MultilineEntry) {
t.s = spin.Text() t.s = spin.Text()
@ -30,14 +29,15 @@ func (t *andlabsT) newTextbox(w *toolkit.Widget) *andlabsT {
func newTextbox(a *toolkit.Action) { func newTextbox(a *toolkit.Action) {
w := a.Widget w := a.Widget
log(debugToolkit, "newCombobox()", w.Name) log(debugToolkit, "newCombobox()", a.Name)
t := andlabs[a.ParentId] t := andlabs[a.ParentId]
if (t == nil) { if (t == nil) {
log(debugToolkit, "newCombobox() toolkit struct == nil. name=", w.Name) log(debugToolkit, "newCombobox() toolkit struct == nil. name=", a.Name)
listMap(debugToolkit) listMap(debugToolkit)
return return
} }
newt := t.newTextbox(w) newt := t.newTextbox(w)
newt.Name = a.Name
place(a, t, newt) place(a, t, newt)
} }

View File

@ -16,22 +16,14 @@ func (t *andlabsT) ErrorWindow(msg1 string, msg2 string) {
} }
func newWindow(a *toolkit.Action) { func newWindow(a *toolkit.Action) {
w := a.Widget
var newt *andlabsT var newt *andlabsT
// log(debugToolkit, "toolkit NewWindow", w.Name, w.Width, w.Height)
if (w == nil) {
log(debugToolkit, "wit/gui plugin error. widget == nil")
return
}
newt = new(andlabsT) newt = new(andlabsT)
newt.tw = w newt.WidgetType = toolkit.Window
newt.Type = toolkit.Window
newt.wId = a.WidgetId newt.wId = a.WidgetId
// menubar bool is if the OS defined border on the window should be used // menubar bool is if the OS defined border on the window should be used
win := ui.NewWindow(w.Name, a.Width, a.Height, menubar) win := ui.NewWindow(a.Name, a.Width, a.Height, menubar)
win.SetBorderless(canvas) win.SetBorderless(canvas)
win.SetMargined(margin) win.SetMargined(margin)
win.OnClosing(func(*ui.Window) bool { win.OnClosing(func(*ui.Window) bool {
@ -41,8 +33,7 @@ func newWindow(a *toolkit.Action) {
win.Show() win.Show()
newt.uiWindow = win newt.uiWindow = win
newt.uiControl = win newt.uiControl = win
// newt.UiWindowBad = win // deprecate this as soon as possible newt.Name = a.Name
newt.Name = w.Name
andlabs[a.WidgetId] = newt andlabs[a.WidgetId] = newt
return return

View File

@ -1,15 +0,0 @@
all: plugin
ldd ../democui.so
build:
GO111MODULE="off" go build
plugin:
GO111MODULE="off" go build -buildmode=plugin -o ../democui.so
objdump:
objdump -t ../democui.so |less
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

View File

@ -1,49 +0,0 @@
package main
import (
"fmt"
"errors"
"strconv"
"github.com/awesome-gocui/gocui"
// "git.wit.org/wit/gui/toolkit"
)
func click(g *gocui.Gui, v *gocui.View) error {
var l string
var err error
log(logNow, "click() START", v.Name())
i, err := strconv.Atoi(v.Name())
if (err != nil) {
log(logNow, "click() Can't find widget. error =", err)
} else {
log(logNow, "click() Found widget id =", i)
if (me.widgets[i] != nil) {
w := me.widgets[i]
log(logNow, "click() Found widget =", w)
}
}
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
maxX, maxY := g.Size()
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
}
// this seems to delete the button(?)
// g.SetViewOnBottom(v.Name())
log(logNow, "click() END")
return nil
}

View File

@ -1,90 +0,0 @@
package main
import (
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func setupWidgetT(a *toolkit.Action) *cuiWidget {
var w *cuiWidget
w = new(cuiWidget)
w.name = a.Name
w.text = a.Text
w.widgetType = a.WidgetType
w.id = a.WidgetId
if (w.id > me.highest) {
me.highest = w.id
}
w.parentId = a.ParentId
me.widgets[w.id] = w
// w.showWidgetPlacement(logNow)
return w
}
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
// gocui.GetColor("#FFAA55") // Dark Purple
func (w *cuiWidget) SetDefaultWidgetColor() {
log(logInfo, "SetDefaultWidgetColor() on", w.widgetType, w.name)
if (w.v == nil) {
log(logError, "SetDefaultWidgetColor() failed on view == nil")
return
}
w.SetDefaultHighlight()
switch w.widgetType {
case toolkit.Button:
w.v.BgColor = gocui.ColorGreen
w.v.FrameColor = gocui.ColorGreen
case toolkit.Checkbox:
w.v.BgColor = gocui.GetColor("#FFAA55") // Dark Purple
w.v.FrameColor = gocui.GetColor("#FFEE11")
case toolkit.Dropdown:
w.v.BgColor = gocui.ColorCyan
w.v.FrameColor = gocui.ColorGreen
case toolkit.Textbox:
w.v.BgColor = gocui.ColorYellow
w.v.FrameColor = gocui.ColorGreen
case toolkit.Slider:
w.v.BgColor = gocui.GetColor("#FFAA55") // Dark Purple
w.v.FrameColor = gocui.ColorRed
case toolkit.Label:
w.v.FrameColor = gocui.ColorRed
default:
w.v.BgColor = gocui.ColorYellow
}
}
// SetColor("#FFAA55") // purple
func (w *cuiWidget) SetColor(c string) {
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorCyan
w.v.SelFgColor = gocui.ColorBlack
switch c {
case "Green":
w.v.BgColor = gocui.ColorGreen
case "Purple":
w.v.BgColor = gocui.GetColor("#FFAA55")
case "Yellow":
w.v.BgColor = gocui.ColorYellow
case "Blue":
w.v.BgColor = gocui.ColorBlue
case "Red":
w.v.BgColor = gocui.ColorRed
default:
w.v.BgColor = gocui.GetColor(c)
}
}
func (w *cuiWidget) SetDefaultHighlight() {
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorGreen
w.v.SelFgColor = gocui.ColorBlack
}

View File

@ -1,111 +0,0 @@
package main
import (
"fmt"
"strconv"
"git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
)
// 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) {
me.defaultBehavior = s
if (me.defaultBehavior) {
log(logInfo, "Setting this toolkit to use the default behavior.")
log(logInfo, "This is the 'guessing' part as defined by the wit/gui 'Principles'. Refer to the docs.")
me.stretchy = false
me.padded = true
me.menubar = true
me.margin = true
me.canvas = false
me.bookshelf = true // 99% of the time, things make a vertical stack of objects
} else {
log(logInfo, "This toolkit is set to ignore the default behavior.")
}
}
func actionDump(b bool, a *toolkit.Action) {
if (a == nil) {
log(b, "action = nil")
return
}
log(b, "a.Name =", a.Name)
log(b, "a.Text =", a.Text)
log(b, "a.WidgetId =", a.WidgetId)
log(b, "a.ParentId =", a.ParentId)
log(b, "a.B =", a.B)
log(b, "a.S =", a.S)
widgetDump(b, a.Widget)
}
func widgetDump(b bool, w *toolkit.Widget) {
if (w == nil) {
log(b, "widget = nil")
return
}
/*
log(b, "widget.Name =", w.Name)
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)
log(b, "widget.I =", w.I)
log(b, "widget.Width =", w.Width)
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
*/
}
func dumpWidgets(g *gocui.Gui, v *gocui.View) {
for _, view := range g.Views() {
i, _ := strconv.Atoi(view.Name())
if (me.widgets[i] != nil) {
continue
}
log(logNow, "dump() not a widget. view.Name =", view.Name())
}
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
w.showWidgetPlacement(logNow, "")
if (w.v == nil) {
log(logError, "dump() ERROR w.v == nil")
} else {
if (strconv.Itoa(i) != w.v.Name()) {
log(logError, "dump() ERROR unequal str.Itoa(i) =", strconv.Itoa(i))
log(logError, "dump() ERROR unequal w.v.Name() =", w.v.Name())
}
}
}
}
func (w *cuiWidget) showWidgetPlacement(b bool, s string) {
log(b, "dump()", s,
fmt.Sprintf("(wId,pId)=(%3d,%3d)", w.id, w.parentId),
fmt.Sprintf("real()=(%3d,%3d,%3d,%3d)", w.realSize.w0, w.realSize.h0, w.realSize.w1, w.realSize.h1),
"next()=(", w.nextX, ",", w.nextY, ")",
"logical()=(", w.logicalSize.w0, ",", w.logicalSize.h0, ",", w.logicalSize.w1, ",", w.logicalSize.h1, ")",
w.widgetType, ",", w.name, "text=", w.text)
if (w.realWidth != (w.realSize.w1 - w.realSize.w0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
if (w.realHeight != (w.realSize.h1 - w.realSize.h0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
}

View File

@ -1,62 +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 (
"github.com/awesome-gocui/gocui"
)
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
}
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
}
// dump out the widgets
func addDebugKeys(g *gocui.Gui) {
// dump all widget info to the log
g.SetKeybinding("", 'd', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
dumpWidgets(g, v)
return nil
})
// hide all widgets
g.SetKeybinding("", 'h', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
hideWidgets()
return nil
})
// show all widgets
g.SetKeybinding("", 's', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
showWidgets()
return nil
})
// try to adjust all the widget positions
g.SetKeybinding("", 'r', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
adjustWidgets()
return nil
})
}

View File

@ -1,30 +0,0 @@
package main
import (
"os"
witlog "git.wit.org/wit/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
func log(a ...any) {
witlog.Where = "wit/democui"
witlog.Log(a...)
}
func sleep(a ...any) {
witlog.Sleep(a...)
}
func exit(a ...any) {
witlog.Exit(a...)
}
func setOutput(f *os.File) {
witlog.SetOutput(f)
}

View File

@ -1,18 +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)
"git.wit.org/wit/gui/toolkit"
)
func Quit() {
me.baseGui.Close()
}
func Action(a *toolkit.Action) {
log(logNow, "Action()", a)
w := setupWidgetT(a)
place(w, a)
log(logInfo, "Action() END")
}

View File

@ -1,52 +0,0 @@
package main
// implements widgets 'Window' and 'Tab'
import (
// "fmt"
"strconv"
// "git.wit.org/wit/gui/toolkit"
// "github.com/awesome-gocui/gocui"
)
func adjustWidgets() {
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
p := me.widgets[w.parentId]
if (p != nil) {
w.setParentLogical(p)
}
}
}
func hideWidgets() {
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
if (w.visable) {
if (w.v != nil) {
cuiName := strconv.Itoa(i)
log(logNow, "about to delete", cuiName, w.name)
me.baseGui.DeleteView(cuiName)
}
}
}
}
func showWidgets() {
for i := 0; i <= me.highest; i++ {
w := me.widgets[i]
if (w == nil) {
continue
}
if (w.visable) {
w.drawView()
}
}
}

View File

@ -1,349 +0,0 @@
package main
import (
"fmt"
"errors"
"strconv"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
var adjusted bool = false
// expands the logical size of the parents
func (w *cuiWidget) setParentLogical(p *cuiWidget) {
if (w.visable) {
// expand the parent logicalsize to include the widget realSize
if (p.logicalSize.w0 > w.realSize.w0) {
p.logicalSize.w0 = w.realSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.realSize.h0) {
p.logicalSize.h0 = w.realSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.realSize.w1) {
p.logicalSize.w1 = w.realSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.realSize.h1) {
p.logicalSize.h1 = w.realSize.h1
adjusted = true
}
} else {
// expand the parent logicalsize to include the widget logicalsize
if (p.logicalSize.w0 > w.logicalSize.w0) {
p.logicalSize.w0 = w.logicalSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.logicalSize.h0) {
p.logicalSize.h0 = w.logicalSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.logicalSize.w1) {
p.logicalSize.w1 = w.logicalSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.logicalSize.h1) {
p.logicalSize.h1 = w.logicalSize.h1
adjusted = true
}
}
if (w.visable) {
// adjust the widget realSize to the top left corner of the logicalsize
if (w.logicalSize.w0 > w.realSize.w0) {
w.realSize.w0 = w.logicalSize.w0
w.realSize.w1 = w.realSize.w0 + w.realWidth
adjusted = true
}
if (w.logicalSize.h0 > w.realSize.h0) {
w.realSize.h0 = w.logicalSize.h0
w.realSize.h1 = w.realSize.h0 + w.realHeight
adjusted = true
}
}
w.showWidgetPlacement(logNow, "setParentLogical() widget")
p.showWidgetPlacement(logNow, "setParentLogical() parent")
if (w.id == 0) || (p.id == 0) {
// stop resizing when you hit the root widget
return
}
// pass the logical resizing up
pP := me.widgets[p.parentId]
if (pP != nil) {
p.setParentLogical(pP)
}
}
var fakeStartWidth int = 80
var fakeStartHeight int = 0
func (w *cuiWidget) setFake() {
if (w.visable) {
return
}
// setup fake labels for non-visable things off screen
w.realWidth = me.defaultWidth
w.realHeight = me.defaultHeight
w.realSize.w0 = fakeStartWidth
w.realSize.h0 = fakeStartHeight
w.realSize.w1 = w.realSize.w0 + me.defaultWidth
w.realSize.h1 = w.realSize.h0 + me.defaultHeight
fakeStartHeight += 2
w.showWidgetPlacement(logNow, "setFake()")
}
func drawView(w *cuiWidget) *gocui.View {
var newName string = ""
newName = strconv.Itoa(w.id)
if (me.baseGui == nil) {
log(logError, "drawView() me.baseGui == nil")
return nil
}
a := w.realSize.w0
b := w.realSize.h0
c := w.realSize.w1
d := w.realSize.h1
v, err := me.baseGui.SetView(newName, a, b, c, d, 0)
if err == nil {
log(logError, "drawView() internal plugin error err = nil")
return nil
}
if !errors.Is(err, gocui.ErrUnknownView) {
log(logError, "drawView() internal plugin error error.IS()", err)
return nil
}
w.v = v
return v
}
func boxedPlace(w *cuiWidget) {
t := len(w.name)
if (w.id == 0) {
w.realWidth = 0
w.realHeight = 0
return
}
p := me.widgets[w.parentId]
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
switch p.widgetType {
case toolkit.Box:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = p.nextX + w.realWidth
w.realSize.h1 = p.nextY + w.realHeight
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX + w.realWidth
w.logicalSize.h1 = p.nextY + w.realHeight
w.nextX = p.nextX
w.nextY = p.nextY
if (w.horizontal) {
log(logNow, "PARENT BOX IS HORIZONTAL")
p.nextX += w.realWidth
} else {
log(logNow, "PARENT BOX IS VERTICAL")
p.nextY += w.realHeight
}
case toolkit.Group:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = p.nextX + w.realWidth
w.realSize.h1 = p.nextY + w.realHeight
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX + w.realWidth
w.logicalSize.h1 = p.nextY + w.realHeight
w.nextX = w.logicalSize.w0 + 3 // default group padding
w.nextY = w.logicalSize.h1
// increment parent
p.nextY += w.realHeight
default:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextX
w.realSize.h0 = p.nextY
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realSize.h0 + w.realHeight
// increment parent
p.nextY += w.realHeight
}
p.showWidgetPlacement(logNow, "bP parent")
w.showWidgetPlacement(logNow, "bP widget")
}
func findPlace(w *cuiWidget, a *toolkit.Action) {
t := len(w.name)
w.visable = true
switch w.widgetType {
case toolkit.Root:
w.visable = false
w.setFake()
w.showWidgetPlacement(logNow, "Root:")
case toolkit.Flag:
w.visable = false
w.setFake()
w.showWidgetPlacement(logNow, "Flag:")
case toolkit.Window:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = me.nextW
w.realSize.h0 = 0
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = me.nextW
w.logicalSize.h0 = 0
w.logicalSize.w1 = w.logicalSize.w0 + w.realWidth
w.logicalSize.h1 = w.realHeight
w.nextX = w.logicalSize.w0 + t // default group padding
w.nextY = w.logicalSize.h1
me.nextW += w.realWidth
w.showWidgetPlacement(logNow, "window:")
case toolkit.Tab:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = me.nextW
w.realSize.h0 = 0
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = me.nextW
w.logicalSize.h0 = 0
w.logicalSize.w1 = w.logicalSize.w0 + w.realWidth
w.logicalSize.h1 = w.realHeight
w.nextX = w.logicalSize.w0 + t // default group padding
w.nextY = w.logicalSize.h1
me.nextW += w.realWidth
w.showWidgetPlacement(logNow, "tab:")
case toolkit.Grid:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "grid:")
case toolkit.Box:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "box:")
case toolkit.Group:
p := me.widgets[w.parentId]
w.horizontal = a.B
w.visable = false
w.setFake()
if (p == nil) {
log(logError, "ERRRRRRRRRRRORRRRRRRRRRRRR: parentId widget == nil")
return
}
w.logicalSize.w0 = p.nextX
w.logicalSize.h0 = p.nextY
w.logicalSize.w1 = p.nextX
w.logicalSize.h1 = p.nextY
w.nextX = p.nextX
w.nextY = p.nextY
w.showWidgetPlacement(logNow, "group:")
default:
boxedPlace(w)
}
}
func place(w *cuiWidget, a *toolkit.Action) {
log(logInfo, "place() START")
findPlace(w, a)
v := drawView(w)
if (v == nil) {
log(logError, "place() drawView(w) returned nil")
return
}
me.baseGui.SetKeybinding(v.Name(), gocui.MouseLeft, gocui.ModNone, click)
v.Wrap = true
fmt.Fprintln(v, " " + w.name)
w.SetDefaultWidgetColor()
log(logInfo, "place() END")
return
}
func (w *cuiWidget) drawView() {
var err error
if (me.baseGui == nil) {
log(logError, "drawView() me.baseGui == nil")
return
}
a := w.realSize.w0
b := w.realSize.h0
c := w.realSize.w1
d := w.realSize.h1
var newName string = ""
newName = strconv.Itoa(w.id)
w.v, err = me.baseGui.SetView(newName, a, b, c, d, 0)
if err == nil {
log(logError, "drawView() internal plugin error err = nil")
return
}
if !errors.Is(err, gocui.ErrUnknownView) {
log(logError, "drawView() internal plugin error error.IS()", err)
return
}
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
w.v.Wrap = true
fmt.Fprintln(w.v, " " + w.text)
w.SetDefaultWidgetColor()
}

View File

@ -9,3 +9,7 @@ plugin:
objdump: objdump:
objdump -t ../gocui.so |less objdump -t ../gocui.so |less
log:
reset
tail -f /tmp/witgui.* /tmp/guilogfile

View File

@ -1,53 +0,0 @@
package main
import (
"errors"
"fmt"
"strings"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func newButton(parentW *toolkit.Widget, w *toolkit.Widget) {
log(true, "AddButton()", w.Name)
addButton(w.Name)
stringWidget[w.Name] = w
listMap()
}
func addButton(name string) *gocui.View {
t := len(name)
if (baseGui == nil) {
panic("WTF")
}
v, err := baseGui.SetView(name, currentX, currentY, currentX+t+3, currentY+2, 0)
if err == nil {
log("wit/gui internal plugin error", err)
return nil
}
if !errors.Is(err, gocui.ErrUnknownView) {
log("wit/gui internal plugin error", err)
return nil
}
v.Wrap = true
fmt.Fprintln(v, " " + name)
fmt.Fprintln(v, strings.Repeat("foo\n", 2))
currentView, err := baseGui.SetCurrentView(name)
if err != nil {
log("wit/gui internal plugin error", err)
return nil
}
log("wit/gui addbutton() current view name =", currentView.Name())
views = append(views, name)
curView = len(views) - 1
idxView += 1
currentY += 3
if (groupSize < len(name)) {
groupSize = len(name)
}
return currentView
}

165
toolkit/gocui/click.go Normal file
View File

@ -0,0 +1,165 @@
package main
import (
"fmt"
"errors"
"strconv"
"strings"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
func (w *cuiWidget) doWidgetClick() {
switch w.widgetType {
case toolkit.Root:
me.rootNode.redoTabs(true)
// me.rootNode.redoFake(true)
case toolkit.Flag:
me.rootNode.redoColor(true)
case toolkit.Window:
me.rootNode.redoTabs(true)
w.redoBox(true)
w.toggleTree()
me.rootNode.redoColor(true)
case toolkit.Tab:
me.rootNode.redoTabs(true)
w.redoBox(true)
w.toggleTree()
me.rootNode.redoColor(true)
case toolkit.Box:
w.showWidgetPlacement(logNow, "drawTree()")
if (w.horizontal) {
log("BOX IS HORIZONTAL", w.nextW, w.nextH, w.name)
} else {
log("BOX IS VERTICAL", w.nextW, w.nextH, w.name)
}
// w.redoBox(true)
default:
// w.textResize()
// something
}
}
var toggle bool = true
func (w *cuiWidget) toggleTree() {
if (toggle) {
w.drawTree(toggle)
toggle = false
} else {
w.hideWidgets()
toggle = true
}
}
// display the widgets in the binary tree
func (w *cuiWidget) drawTree(draw bool) {
if (w == nil) {
return
}
w.showWidgetPlacement(logNow, "drawTree()")
if (draw) {
w.textResize()
w.drawView()
} else {
me.baseGui.DeleteView(w.cuiName)
w.v = nil
}
for _, child := range w.children {
child.drawTree(draw)
}
}
func click(g *gocui.Gui, v *gocui.View) error {
var l string
var err error
log(logNow, "click() START", v.Name())
i, err := strconv.Atoi(v.Name())
if (err != nil) {
log(logNow, "click() Can't find widget. error =", err)
} else {
log(logNow, "click() ok v.Name() =", v.Name())
w := findWidget(i, me.rootNode)
if (w == nil) {
log(logError, "click() CANT FIND VIEW in binary tree. v.Name =", v.Name())
return nil
}
log(logNow, "click() Found widget =", w.id, w.name, ",", w.text)
w.doWidgetClick()
return nil
}
if _, err := g.SetCurrentView(v.Name()); err != nil {
return err
}
_, cy := v.Cursor()
if l, err = v.Line(cy); err != nil {
l = ""
}
maxX, maxY := g.Size()
if v, err := g.SetView("msg", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0); err == nil || errors.Is(err, gocui.ErrUnknownView) {
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
}
// this seems to delete the button(?)
// g.SetViewOnBottom(v.Name())
log(logNow, "click() END")
return nil
}
// display the widgets in the binary tree
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
var widgets []*cuiWidget
var f func (widget *cuiWidget)
w, h := g.MousePosition()
f = func(widget *cuiWidget) {
if ((widget.logicalSize.w0 < w) && (w < widget.logicalSize.w1)) {
widgets = append(widgets, widget)
}
for _, child := range widget.children {
f(child)
}
}
f(me.rootNode)
var t string
for i, widget := range widgets {
log(logNow, "ctrlDown() FOUND widget", i, widget.name)
t += widget.cuiName + " " + widget.name + "\n"
// widget.showWidgetPlacement(logNow, "drawTree()")
}
t = strings.TrimSpace(t)
if (me.ctrlDown == nil) {
setupCtrlDownWidget()
}
me.ctrlDown.text = t
me.ctrlDown.realSize.w0 = w
me.ctrlDown.realSize.h0 = h
me.ctrlDown.textResize()
me.ctrlDown.drawView()
/*
v, err := g.SetView("ctrlDown", maxX/2-10, maxY/2, maxX/2+10, maxY/2+2, 0)
if (err != nil) {
log(logError, "ctrlDown() g.SetView() error:", err)
return
}
v.Clear()
v.SelBgColor = gocui.ColorCyan
v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, l)
*/
log(logNow, "ctrlDown()", w, h)
return nil
}

113
toolkit/gocui/color.go Normal file
View File

@ -0,0 +1,113 @@
package main
import (
"math/rand"
"github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
// gocui.GetColor("#FFAA55") // Dark Purple
func (w *cuiWidget) SetDefaultWidgetColor() {
log(logInfo, "SetDefaultWidgetColor() on", w.widgetType, w.name)
v, _ := me.baseGui.View(w.cuiName)
if (v == nil) {
log(logError, "SetDefaultWidgetColor() failed on view == nil")
return
}
// v.BgColor = gocui.GetColor("#FFAA55") // Dark Purple
// v.BgColor = gocui.GetColor("#88AA55") // heavy purple
// 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
switch w.widgetType {
case toolkit.Root:
v.FrameColor = gocui.ColorRed
v.BgColor = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
case toolkit.Flag:
v.FrameColor = gocui.ColorRed
v.BgColor = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
case toolkit.Window:
v.FgColor = gocui.ColorCyan
v.SelBgColor = gocui.ColorBlue
v.FrameColor = gocui.ColorBlue
case toolkit.Tab:
v.SelBgColor = gocui.ColorBlue
v.FrameColor = gocui.ColorBlue
case toolkit.Button:
v.BgColor = gocui.ColorWhite
v.FrameColor = gocui.ColorGreen
v.SelBgColor = gocui.ColorBlack
v.SelFgColor = gocui.ColorGreen
case toolkit.Label:
v.BgColor = gocui.GetColor("#55AAFF") // super light grey
v.SelBgColor = gocui.GetColor("#55AAFF") // super light grey
case toolkit.Box:
v.FrameColor = gocui.ColorRed
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
v.BgColor = gocui.GetColor("#DDDDDD") // light purple
case toolkit.Grid:
// v.FgColor = gocui.ColorCyan
// v.SelBgColor = gocui.ColorBlue
// v.FrameColor = gocui.ColorBlue
case toolkit.Group:
v.BgColor = gocui.GetColor("#55AAFF") // super light grey
default:
}
}
// SetColor("#FFAA55") // purple
func (w *cuiWidget) SetColor(c string) {
if (w.v == nil) {
log(logError, "SetColor() failed on view == nil")
return
}
w.v.SelBgColor = gocui.ColorCyan
w.v.SelFgColor = gocui.ColorBlack
switch c {
case "Green":
w.v.BgColor = gocui.ColorGreen
case "Purple":
w.v.BgColor = gocui.GetColor("#FFAA55")
case "Yellow":
w.v.BgColor = gocui.ColorYellow
case "Blue":
w.v.BgColor = gocui.ColorBlue
case "Red":
w.v.BgColor = gocui.ColorRed
default:
w.v.BgColor = gocui.GetColor(c)
}
}
func (w *cuiWidget) SetDefaultHighlight() {
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 (w *cuiWidget) redoColor(draw bool) {
if (w == nil) {
return
}
sleep(.05)
w.SetDefaultWidgetColor()
for _, child := range w.children {
child.redoColor(draw)
}
}

100
toolkit/gocui/common.go Normal file
View File

@ -0,0 +1,100 @@
package main
import (
"strconv"
"git.wit.org/wit/gui/toolkit"
// "github.com/awesome-gocui/gocui"
)
func setupWidget(a *toolkit.Action) *cuiWidget {
var w *cuiWidget
w = new(cuiWidget)
w.name = a.Name
w.text = a.Text
w.b = a.B
w.i = a.I
w.s = a.S
w.x = a.X
w.y = a.Y
w.width = a.Width
w.height = a.Height
w.widgetType = a.WidgetType
w.id = a.WidgetId
// set the name used by gocui to the id
w.cuiName = strconv.Itoa(w.id)
w.parent = findWidget(a.ParentId, me.rootNode)
log(logInfo, "setupWidget() w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
if (w.id == 0) {
me.rootNode = w
// this is the rootNode
return w
}
if (w.parent == nil) {
log(logError, "setupWidget() ERROR: PARENT = NIL w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
// just use the rootNode (hopefully it's not nil)
w.parent = me.rootNode
// return w
}
if (w.parent == nil) {
log(logError, "setupWidget() ERROR: PARENT = NIL w.id =", w.id, "w.parent", w.parent, "ParentId =", a.ParentId)
me.rootNode = w
return w
}
// add this widget as a child for the parent
w.parent.Append(w)
if (a.WidgetType == toolkit.Box) {
if (a.B) {
w.horizontal = true
} else {
w.horizontal = false
}
}
// w.showWidgetPlacement(logNow)
return w
}
func setupCtrlDownWidget() {
var w *cuiWidget
w = new(cuiWidget)
w.name = "ctrlDown"
w.widgetType = toolkit.Flag
w.id = -1
me.ctrlDown = w
// me.rootNode.Append(w)
}
func (n *cuiWidget) Append(child *cuiWidget) {
n.children = append(n.children, child)
// child.parent = n
}
// find widget by number
func findWidget(i int, w *cuiWidget) (*cuiWidget) {
if (w == nil) {
log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against w.id = nil")
return nil
}
log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against w.id =", w.id)
if (w.id == i) {
log(logInfo, "findWidget() FOUND w.id ==", i, w.widgetType, w.name)
return w
}
for _, child := range w.children {
newW := findWidget(i, child)
log(logVerbose, "findWidget() Trying to find i =", i, "currently checking against child.id =", child.id)
if (newW != nil) {
return newW
}
}
return nil
}

View File

@ -1,109 +1,70 @@
package main package main
import "git.wit.org/wit/gui/toolkit" import (
"fmt"
var defaultBehavior bool = true "git.wit.org/wit/gui/toolkit"
// "github.com/awesome-gocui/gocui"
)
var bookshelf bool // do you want things arranged in the box like a bookshelf or a stack? func actionDump(b bool, a *toolkit.Action) {
var canvas bool // if set to true, the windows are a raw canvas if (a == nil) {
var menubar bool // for windows log(b, "action = nil")
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
var debugChange bool
var debugPlugin bool
var debugFlags bool
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, "debugPlugin =", debugPlugin)
log(true, "debugFlags =", debugFlags)
log(true, "debugError =", debugError)
}
/*
func (t *gocuiT) Dump(b bool) {
if ! b {
return return
} }
log(b, "Name = ", t.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)
}
widgetDump(b, t.tw)
}
*/
func widgetDump(b bool, w *toolkit.Widget) { log(b, "a.Name =", a.Name)
log(b, "a.Text =", a.Text)
log(b, "a.WidgetId =", a.WidgetId)
log(b, "a.ParentId =", a.ParentId)
log(b, "a.B =", a.B)
log(b, "a.S =", a.S)
}
func (w *cuiWidget) dumpTree(draw bool) {
log(logNow, "dumpTree() START", w)
if (w == nil) { if (w == nil) {
log(b, "widget = nil")
return return
} }
w.showWidgetPlacement(logNow, "Tree:")
/* for _, child := range w.children {
log(b, "widget.Name =", w.Name) child.dumpTree(draw)
// log(b, "widget.Action =", w.Action) }
log(b, "widget.Type =", w.Type)
log(b, "widget.Custom =", w.Custom)
log(b, "widget.B =", w.B)
log(b, "widget.I =", w.I)
log(b, "widget.Width =", w.Width)
log(b, "widget.Height =", w.Height)
log(b, "widget.X =", w.X)
log(b, "widget.Y =", w.Y)
*/
} }
/* func (w *cuiWidget) showWidgetPlacement(b bool, s string) {
func GetDebugToolkit () bool { if (w == nil) {
return debugToolkit log(logError, "WTF w == nil")
return
}
if (w.id == 0) {
log(logVerbose, "showWidgetPlacement() parent == nil ok. This is the rootNode", w.id, w.cuiName)
return
}
if (w.parent == nil) {
log(logError, "showWidgetPlacement() WTF parent == nil", w.id, w.cuiName)
log(logError, "showWidgetPlacement() WTF parent == nil", w.id, w.cuiName)
log(logError, "showWidgetPlacement() WTF parent == nil", w.id, w.cuiName)
return
}
log(b, "dump()", s,
fmt.Sprintf("(wId,pId)=(%3d,%3d)", w.id, w.parent.id),
fmt.Sprintf("real()=(%3d,%3d,%3d,%3d)", w.realSize.w0, w.realSize.h0, w.realSize.w1, w.realSize.h1),
"next()=(", w.nextW, ",", w.nextH, ")",
"logical()=(", w.logicalSize.w0, ",", w.logicalSize.h0, ",", w.logicalSize.w1, ",", w.logicalSize.h1, ")",
w.widgetType, ",", w.name, "text=", w.text)
if (w.realWidth != (w.realSize.w1 - w.realSize.w0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
if (w.realHeight != (w.realSize.h1 - w.realSize.h0)) {
log(b, "dump()", s,
"badsize()=(", w.realWidth, ",", w.realHeight, ")",
"badreal()=(", w.realSize.w0, ",", w.realSize.h0, ",", w.realSize.w1, ",", w.realSize.h1, ")",
w.widgetType, ",", w.name)
}
} }
*/

View File

@ -1,112 +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"
"os"
"git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
)
const delta = 1
var (
views = []string{}
curView = -1
idxView = 0
currentX = 5
currentY = 2
groupSize = 0
baseGui *gocui.Gui
helpLabel *gocui.View
err error
ch chan(func ())
outf *os.File
)
func Init() {
baseGui, err = gocui.NewGui(gocui.OutputNormal, true)
if err != nil {
exit(err)
}
baseGui.Highlight = true
baseGui.SelFgColor = gocui.ColorRed
baseGui.SelFrameColor = gocui.ColorRed
baseGui.Cursor = true
baseGui.Mouse = true
baseGui.SetManagerFunc(layout)
if err := initKeybindings(baseGui); err != nil {
exit(err)
}
viewWidget = make(map[*gocui.View]*toolkit.Widget)
stringWidget = make(map[string]*toolkit.Widget)
ch = make(chan func())
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)
}
// hmm. where to put this?
// defer outf.Close()
setOutput(outf)
log("This is a test log entry")
}
func Queue(f func()) {
log("QUEUEEEEE")
f()
}
func Main(f func()) {
// close the STDOUT log file
defer outf.Close()
if (baseGui == nil) {
panic("WTF Main()")
}
defer baseGui.Close()
// log.Println("ADDDDDDDD BUTTTTTTTTTON")
// addButton("test 3")
f()
if err := baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
exit(err)
}
baseGui.Close()
os.Exit(0)
}
func layout(g *gocui.Gui) error {
var err error
maxX, _ := g.Size()
helpLabel, err = g.SetView("help", maxX-32, 0, maxX-1, 12, 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, "STDOUT: /tmp/witgui.log")
fmt.Fprintln(helpLabel, "Ctrl-C or Q: Exit")
}
return nil
}

View File

@ -1,36 +0,0 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
func newGroup(parentW *toolkit.Widget, w *toolkit.Widget) {
if (parentW == nil) {
log(debugError, "plugin error. parent widget == nil")
return
}
if (w == nil) {
log(debugPlugin, "plugin error. widget == nil")
return
}
if (w.Name == "") {
w.Name = parentW.Name
}
if (w.Name == "") {
w.Name = "nil newGroup"
}
log("AddGroup", w.Name)
addGroup(w.Name)
stringWidget[w.Name] = w
}
func addGroup(name string) {
log("addGroup() START name =", name)
log("addGroup() START groupSize =", groupSize, "currentY =", currentY, "currentX =", currentX)
currentY = 2
currentX += groupSize + 5
groupSize = 0
log("addGroup() START, RESET Y = 3, RESET X = ", currentX)
}

View File

@ -19,7 +19,7 @@ func helplayout(g *gocui.Gui) error {
var err error var err error
maxX, _ := g.Size() maxX, _ := g.Size()
help, err := g.SetView("help", maxX-32, 0, maxX-1, 12, 0) help, err := g.SetView("help", maxX-32, 0, maxX-1, 17, 0)
if err != nil { if err != nil {
if !errors.Is(err, gocui.ErrUnknownView) { if !errors.Is(err, gocui.ErrUnknownView) {
return err return err
@ -35,6 +35,9 @@ func helplayout(g *gocui.Gui) error {
fmt.Fprintln(help, "Arrow keys: Move Button") fmt.Fprintln(help, "Arrow keys: Move Button")
fmt.Fprintln(help, "t: Move Button to the top") fmt.Fprintln(help, "t: Move Button to the top")
fmt.Fprintln(help, "b: Move Button to the button") fmt.Fprintln(help, "b: Move Button to the button")
fmt.Fprintln(help, "h: hide buttons")
fmt.Fprintln(help, "s: show buttons")
fmt.Fprintln(help, "p: panic()")
fmt.Fprintln(help, "STDOUT: /tmp/witgui.log") fmt.Fprintln(help, "STDOUT: /tmp/witgui.log")
fmt.Fprintln(help, "Ctrl-C or Q: Exit") fmt.Fprintln(help, "Ctrl-C or Q: Exit")
if _, err := g.SetCurrentView("help"); err != nil { if _, err := g.SetCurrentView("help"); err != nil {

View File

@ -6,130 +6,66 @@ package main
import ( import (
"github.com/awesome-gocui/gocui" "github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
) )
func initKeybindings(g *gocui.Gui) error { func defaultKeybindings(g *gocui.Gui) error {
log("got to initKeybindings") if err := g.SetKeybinding("", gocui.KeyCtrlC, gocui.ModNone, quit); err != nil {
if err := g.SetKeybinding("", 'q', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
return gocui.ErrQuit
}); err != nil {
return err return err
} }
if err := g.SetKeybinding("", 'Q', gocui.ModNone, for _, n := range []string{"but1", "but2", "help", "but3"} {
func(g *gocui.Gui, v *gocui.View) error { if err := g.SetKeybinding(n, gocui.MouseLeft, gocui.ModNone, showMsg); err != nil {
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("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("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("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("enter", v.Name())
var w *toolkit.Widget
w = stringWidget[v.Name()]
if (w == nil) {
log("COULD NOT FIND WIDGET", v.Name())
} else {
log("FOUND WIDGET!", w)
if (w.Custom != nil) {
w.Custom()
return nil
}
// if (w.Event != nil) {
// w.Event(w)
// return nil
// }
}
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 return err
}); err != nil { }
}
if err := g.SetKeybinding("", gocui.MouseRelease, gocui.ModNone, mouseUp); err != nil {
return err return err
} }
if err := g.SetKeybinding("", 'b', gocui.ModNone, if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, globalDown); err != nil {
func(g *gocui.Gui, v *gocui.View) error {
_, err := g.SetViewOnBottom(views[curView])
return err
}); err != nil {
return err return err
} }
if err := g.SetKeybinding("", 'h', gocui.ModNone, if err := g.SetKeybinding("", gocui.MouseLeft, gocui.ModMouseCtrl, ctrlDown); err != nil {
func(g *gocui.Gui, v *gocui.View) error {
log("help", v.Name())
tmp, _ := g.SetViewOnTop("help")
log("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 {
exit("gocui SetKeybinding()", err)
}
return nil
}); err != nil {
return err 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 return nil
} }
// dump out the widgets
func addDebugKeys(g *gocui.Gui) {
// dump all widget info to the log
g.SetKeybinding("", 'd', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
log(logNow, "gocui.SetKeyBinding() dumpTree() START")
me.rootNode.dumpTree(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
})
// panic
g.SetKeybinding("", 'p', gocui.ModNone,
func(g *gocui.Gui, v *gocui.View) error {
panic("forced panic in gocui")
return nil
})
}

View File

@ -5,7 +5,15 @@ import (
witlog "git.wit.org/wit/gui/log" witlog "git.wit.org/wit/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
func log(a ...any) { func log(a ...any) {
witlog.Where = "wit/gocui"
witlog.Log(a...) witlog.Log(a...)
} }

72
toolkit/gocui/logical.go Normal file
View File

@ -0,0 +1,72 @@
package main
import (
// "git.wit.org/wit/gui/toolkit"
)
var adjusted bool = false
// expands the logical size of the parents
func (w *cuiWidget) setParentLogical(p *cuiWidget) {
if (w.visable) {
// expand the parent logicalsize to include the widget realSize
if (p.logicalSize.w0 > w.realSize.w0) {
p.logicalSize.w0 = w.realSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.realSize.h0) {
p.logicalSize.h0 = w.realSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.realSize.w1) {
p.logicalSize.w1 = w.realSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.realSize.h1) {
p.logicalSize.h1 = w.realSize.h1
adjusted = true
}
} else {
// expand the parent logicalsize to include the widget logicalsize
if (p.logicalSize.w0 > w.logicalSize.w0) {
p.logicalSize.w0 = w.logicalSize.w0
adjusted = true
}
if (p.logicalSize.h0 > w.logicalSize.h0) {
p.logicalSize.h0 = w.logicalSize.h0
adjusted = true
}
if (p.logicalSize.w1 < w.logicalSize.w1) {
p.logicalSize.w1 = w.logicalSize.w1
adjusted = true
}
if (p.logicalSize.h1 < w.logicalSize.h1) {
p.logicalSize.h1 = w.logicalSize.h1
adjusted = true
}
}
if (w.visable) {
// adjust the widget realSize to the top left corner of the logicalsize
if (w.logicalSize.w0 > w.realSize.w0) {
w.realSize.w0 = w.logicalSize.w0
w.realSize.w1 = w.realSize.w0 + w.realWidth
adjusted = true
}
if (w.logicalSize.h0 > w.realSize.h0) {
w.realSize.h0 = w.logicalSize.h0
w.realSize.h1 = w.realSize.h0 + w.realHeight
adjusted = true
}
}
w.showWidgetPlacement(logNow, "setParentLogical() widget")
p.showWidgetPlacement(logNow, "setParentLogical() parent")
if (w.id == 0) || (p.id == 0) {
// stop resizing when you hit the root widget
return
}
// pass the logical resizing up
pP := w.parent
if (pP != nil) {
p.setParentLogical(pP)
}
}

View File

@ -8,18 +8,15 @@ import (
"os" "os"
) )
/*
func OnExit(f func(string)) {
Custom = f
}
*/
func Init() { func Init() {
log(logInfo, "Init() of democui") log(logInfo, "Init() of awesome-gocui")
me.widgets = make(map[int]*cuiWidget)
me.defaultWidth = 10 me.defaultWidth = 10
me.defaultHeight = 2 me.defaultHeight = 2
me.defaultBehavior = true me.defaultBehavior = true
me.horizontalPadding = 20
me.groupPadding = 2
me.buttonPadding = 2
} }
func Exit() { func Exit() {
@ -27,18 +24,6 @@ func Exit() {
me.baseGui.Close() me.baseGui.Close()
} }
/*
func mouseClick(name string) {
// output screws up the console. Need to fix this by redirecting all console output to a file from log.Println()
// log.Println("g.Close()")
// g.Close()
log("Found andlabs Running custom function for the mouse click")
Custom(name)
// panic("got andlabs")
}
*/
func Main(f func()) { func Main(f func()) {
log("start Init()") log("start Init()")
@ -53,15 +38,3 @@ func Main(f func()) {
MouseMain() MouseMain()
} }
/*
func StartConsoleMouse() {
defer g.Close()
log("start Main()")
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
exit(err)
}
log("exit Main()")
}
*/

View File

@ -45,6 +45,7 @@ func layout(g *gocui.Gui) error {
} }
v.Frame = false v.Frame = false
} }
/*
if v, err := g.SetView("but1", 2, 2, 22, 7, 0); err != nil { if v, err := g.SetView("but1", 2, 2, 22, 7, 0); err != nil {
if !errors.Is(err, gocui.ErrUnknownView) { if !errors.Is(err, gocui.ErrUnknownView) {
return err return err
@ -67,6 +68,7 @@ func layout(g *gocui.Gui) error {
v.SelFgColor = gocui.ColorBlack v.SelFgColor = gocui.ColorBlack
fmt.Fprintln(v, "Button 2 - line 1") fmt.Fprintln(v, "Button 2 - line 1")
} }
*/
helplayout(g) helplayout(g)
updateHighlightedView(g) updateHighlightedView(g)
return nil return nil

221
toolkit/gocui/place.go Normal file
View File

@ -0,0 +1,221 @@
package main
import (
// "github.com/awesome-gocui/gocui"
"git.wit.org/wit/gui/toolkit"
)
var fakeStartWidth int = 80
var fakeStartHeight int = 0
func (w *cuiWidget) setFake() {
if (w.visable) {
return
}
t := len(w.name)
// setup fake labels for non-visable things off screen
w.realWidth = t + 2
w.realHeight = me.defaultHeight
w.realSize.w0 = fakeStartWidth
w.realSize.h0 = fakeStartHeight
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realSize.h0 + w.realHeight
fakeStartHeight += 3
if (fakeStartHeight > 24) {
fakeStartHeight = 0
fakeStartWidth += 20
}
w.showWidgetPlacement(logNow, "setFake()")
}
func findPlace(w *cuiWidget) {
w.visable = true
switch w.widgetType {
case toolkit.Root:
w.visable = false
w.setFake()
case toolkit.Flag:
w.visable = false
w.setFake()
case toolkit.Grid:
w.visable = false
w.setFake()
case toolkit.Box:
w.visable = false
w.setFake()
default:
w.redoBox(true)
}
}
func (w *cuiWidget) redoBox(draw bool) {
if (w == nil) {
return
}
if (me.rootNode == nil) {
return
}
p := w.parent
if (p == nil) {
log(logInfo, "redoBox()", w.id, "parent == nil")
return
}
t := len(w.text)
w.visable = true
switch w.widgetType {
case toolkit.Window:
for _, child := range w.children {
child.redoBox(draw)
}
case toolkit.Tab:
for _, child := range w.children {
child.redoBox(draw)
}
case toolkit.Grid:
// hmm
w.logicalSize.w0 = p.nextW
w.logicalSize.h0 = p.nextH
w.logicalSize.w1 = p.nextW
w.logicalSize.h1 = p.nextH
w.nextW = p.nextW
w.nextH = p.nextH
var wCount, hCount int
var b bool = true
for _, child := range w.children {
child.redoBox(draw)
if (b) {
wCount += 1
b = false
} else {
wCount = 0
w.nextH += 1
b = true
}
w.nextW = p.nextW + wCount * 20
w.nextH = p.nextH + hCount * 4
log(logInfo, "redoBox(GRID) (w,h count)", wCount, hCount, "(X,Y)", w.x, w.y, w.name)
}
w.showWidgetPlacement(logNow, "grid:")
case toolkit.Box:
w.logicalSize.w0 = p.nextW
w.logicalSize.h0 = p.nextH
w.logicalSize.w1 = p.nextW
w.logicalSize.h1 = p.nextH
w.nextW = p.nextW
w.nextH = p.nextH
for _, child := range w.children {
child.redoBox(draw)
if (w.horizontal) {
log("BOX IS HORIZONTAL", p.nextW, p.nextW, p.name)
log("BOX IS HORIZONTAL", w.nextW, w.nextH, w.name)
log("BOX IS HORIZONTAL")
// expand based on the child width
w.nextW = child.nextW + me.horizontalPadding
// reset height to parent
w.nextH = p.nextH
} else {
log("BOX IS VERTICAL", p.nextW, p.nextW, p.name)
log("BOX IS VERTICAL", w.nextW, w.nextH, w.name)
log("BOX IS VERTICAL")
// go straight down
w.nextW = p.nextW
// expand based on the child height
w.nextH = child.nextH
}
}
w.showWidgetPlacement(logNow, "box:")
case toolkit.Group:
w.realWidth = t + me.buttonPadding
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextW
w.realSize.h0 = p.nextH
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = w.realSize.w0
w.logicalSize.h0 = w.realSize.h0
w.logicalSize.w1 = w.realSize.w1
w.logicalSize.h1 = w.realSize.h1
w.nextW = p.nextW + me.groupPadding
w.nextH = p.nextH + me.buttonPadding
for _, child := range w.children {
child.redoBox(draw)
// reset nextW to straight down
w.nextW = p.nextW + 4
w.nextH = child.nextH
}
// expand the height of the parent now that the group is done
// p.nextW = w.nextW
// p.nextH = w.nextH
w.showWidgetPlacement(logNow, "group:")
default:
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextW
w.realSize.h0 = p.nextH
w.realSize.w1 = p.nextW + w.realWidth
w.realSize.h1 = p.nextH + w.realHeight
w.logicalSize.w0 = p.nextW
w.logicalSize.h0 = p.nextH
w.logicalSize.w1 = p.nextW + w.realWidth
w.logicalSize.h1 = p.nextH + w.realHeight
w.nextW = w.realSize.w1
w.nextH = w.realSize.h1
}
}
func (w *cuiWidget) boxedPlace() {
t := len(w.name)
if (w.id == 0) {
w.realWidth = 0
w.realHeight = 0
return
}
p := w.parent
if (p == nil) {
log(logError, "boxedPlace() parentId widget == nil")
return
}
w.realWidth = t + 3
w.realHeight = me.defaultHeight
w.realSize.w0 = p.nextW
w.realSize.h0 = p.nextH
w.realSize.w1 = p.nextW + w.realWidth
w.realSize.h1 = p.nextH + w.realHeight
w.logicalSize.w0 = p.nextW
w.logicalSize.h0 = p.nextH
w.logicalSize.w1 = p.nextW + w.realWidth
w.logicalSize.h1 = p.nextH + w.realHeight
w.nextW = w.realSize.w1
w.nextH = w.realSize.h1
w.showWidgetPlacement(logNow, "bP widget")
}
func (w *cuiWidget) updateLogicalSizes() {
for _, child := range w.children {
child.updateLogicalSizes()
if (w.logicalSize.w0 > child.logicalSize.w0) {
w.logicalSize.w0 = child.logicalSize.w0
}
if (w.logicalSize.w1 < child.logicalSize.w1) {
w.logicalSize.w1 = child.logicalSize.w1
}
if (w.logicalSize.h0 > child.logicalSize.h0) {
w.logicalSize.h0 = child.logicalSize.h0
}
if (w.logicalSize.h1 < child.logicalSize.h1) {
w.logicalSize.h1 = child.logicalSize.h1
}
}
}

View File

@ -4,114 +4,77 @@ import (
// if you include more than just this 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) // then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
"git.wit.org/wit/gui/toolkit" "git.wit.org/wit/gui/toolkit"
"github.com/awesome-gocui/gocui"
) )
// This is a map between the widgets in wit/gui and the internal structures of gocui
var viewWidget map[*gocui.View]*toolkit.Widget
var stringWidget map[string]*toolkit.Widget
func Quit() { func Quit() {
baseGui.Close() me.baseGui.Close()
} }
// This lists out the know mappings func Action(a *toolkit.Action) {
func listMap() { log(logInfo, "Action() START", a.WidgetId, a.ActionType, a.WidgetType, a.Name)
for v, w := range viewWidget { w := findWidget(a.WidgetId, me.rootNode)
log("view =", v.Name, "widget name =", w.Name) switch a.ActionType {
} case toolkit.Add:
for s, w := range stringWidget { w = setupWidget(a)
log("string =", s, "widget =", w) findPlace(w)
w.drawView()
case toolkit.Show:
if (a.B) {
w.drawView()
} else {
w.hideWidgets()
}
case toolkit.Set:
w.Set(a.A)
case toolkit.SetText:
w.SetText(a.S)
case toolkit.AddText:
w.AddText(a.S)
case toolkit.Move:
log(logNow, "attempt to move() =", a.ActionType, a.WidgetType, a.Name)
default:
log(logError, "Action() Unknown =", a.ActionType, a.WidgetType, a.Name)
} }
log(logInfo, "Action() END")
} }
func (w *cuiWidget) AddText(text string) {
// if (w == nil) {
// This should be called ? log(logNow, "widget is nil")
// Pass() ?
// This handles all interaction between the wit/gui package (what golang knows about)
// and this plugin that talks to the OS and does scary and crazy things to make
// a GUI on whatever OS or whatever GUI toolkit you might have (GTK, QT, WASM, libcurses)
//
// Once you are here, you should be in a protected goroutine created by the golang wit/gui package
//
// TODO: make sure you can't escape this goroutine
//
func Send(p *toolkit.Widget, c *toolkit.Widget) {
if (p == nil) {
log(debugPlugin, "Send() parent = nil")
} else {
log(debugPlugin, "Send() parent =", p.Name, ",", p.Type)
}
log(debugPlugin, "Send() child =", c.Name, ",", c.Type)
/*
if (c.Action == "SetMargin") {
log(debugError, "need to implement SetMargin here")
setMargin(c, c.B)
return return
} }
*/ w.vals = append(w.vals, text)
for i, s := range w.vals {
log(logNow, "AddText()", w.name, i, s)
}
w.SetText(text)
}
switch c.Type { func (w *cuiWidget) SetText(text string) {
/* if (w == nil) {
case toolkit.Window: log(logNow, "widget is nil")
// doWindow(c) return
case toolkit.Tab: }
// doTab(p, c) w.text = text
*/ w.s = text
case toolkit.Group: w.textResize()
newGroup(p, c) me.baseGui.DeleteView(w.cuiName)
case toolkit.Button: w.drawView()
newButton(p, c) }
/*
case toolkit.Checkbox: func (w *cuiWidget) Set(val any) {
// doCheckbox(p, c) log(logInfo, "Set() value =", val)
case toolkit.Label: var a toolkit.Action
// doLabel(p, c) a.ActionType = toolkit.Set
case toolkit.Textbox:
// doTextbox(p, c) switch v := val.(type) {
case toolkit.Slider: case bool:
// doSlider(p, c) w.b = val.(bool)
case toolkit.Spinner: case string:
// doSpinner(p, c) w.SetText(val.(string))
case toolkit.Dropdown: case int:
// doDropdown(p, c) w.i = val.(int)
case toolkit.Combobox:
// doCombobox(p, c)
case toolkit.Grid:
// doGrid(p, c)
*/
/*
case toolkit.Flag:
// log(debugFlags, "plugin Send() flag parent =", p.Name, p.Type)
// log(debugFlags, "plugin Send() flag child =", c.Name, c.Type)
// log(debugFlags, "plugin Send() flag child.Action =", c.Action)
// log(debugFlags, "plugin Send() flag child.S =", c.S)
// log(debugFlags, "plugin Send() flag child.B =", c.B)
// log(debugFlags, "plugin Send() what to flag?")
// should set the checkbox to this value
switch c.S {
case "Toolkit":
debugToolkit = c.B
case "Change":
debugChange = c.B
case "Plugin":
debugPlugin = c.B
case "Flags":
debugFlags = c.B
case "Error":
debugError = c.B
case "Show":
ShowDebug()
default:
log(debugError, "Can't set unknown flag", c.S)
}
*/
default: default:
log(debugError, "plugin Send() unknown parent =", p.Name, p.Type) log(logError, "Set() unknown type =", v, "a =", a)
log(debugError, "plugin Send() unknown child =", c.Name, c.Type)
log(debugError, "plugin Send() Don't know how to do", c.Type, "yet")
} }
} }

View File

@ -21,9 +21,10 @@ import (
var me config var me config
type config struct { type config struct {
highest int // highest widgetId
baseGui *gocui.Gui // the main gocui handle baseGui *gocui.Gui // the main gocui handle
widgets map[int]*cuiWidget rootNode *cuiWidget // the base of the binary tree. it should have id == 0
ctrlDown *cuiWidget // shown if you click the mouse when the ctrl key is pressed
callback func(int) callback func(int)
helpLabel *gocui.View helpLabel *gocui.View
@ -38,6 +39,10 @@ type config struct {
stretchy bool // expand things like buttons to the maximum size stretchy bool // expand things like buttons to the maximum size
padded bool // add space between things like buttons padded bool // add space between things like buttons
margin bool // add space around the frames of windows margin bool // add space around the frames of windows
horizontalPadding int
groupPadding int
buttonPadding int
} }
/* /*
@ -73,11 +78,14 @@ type realSizeT struct {
type cuiWidget struct { type cuiWidget struct {
id int // widget ID id int // widget ID
parentId int // parentId int
widgetType toolkit.WidgetType widgetType toolkit.WidgetType
name string // a descriptive name of the widget name string // a descriptive name of the widget
text string // the current text being displayed text string // the current text being displayed
cuiName string // what gocui uses to reference the widget
vals []string // dropdown menu options
visable bool // widget types like 'box' are 'false' visable bool // widget types like 'box' are 'false'
realWidth int // the real width realWidth int // the real width
@ -85,8 +93,21 @@ type cuiWidget struct {
realSize rectType // the display size of this widget realSize rectType // the display size of this widget
logicalSize rectType // the logical size. Includes all the child widgets logicalSize rectType // the logical size. Includes all the child widgets
nextX int nextW int
nextY int nextH int
// things from toolkit/action
b bool
i int
s string
x int
y int
width int
height int
//deprecate
// nextX int
// nextY int
// horizontal=true means layout widgets like books on a bookshelf // horizontal=true means layout widgets like books on a bookshelf
// horizontal=false means layout widgets like books in a stack // horizontal=false means layout widgets like books in a stack
@ -94,18 +115,12 @@ type cuiWidget struct {
tainted bool tainted bool
v *gocui.View v *gocui.View
baseGui *gocui.Gui // use gogui.Manager ? as 'workspaces?'
// writeMutex protects locks the write process // writeMutex protects locks the write process
writeMutex sync.Mutex writeMutex sync.Mutex
// deprecate parent *cuiWidget
// logicalWidth int `default:8` children []*cuiWidget
// logicalHeight int `default:2`
// rect rectType
// current rectType // the logical size. Includes all the child widgets
// width int
// height int
} }
// from the gocui devs: // from the gocui devs:

88
toolkit/gocui/tab.go Normal file
View File

@ -0,0 +1,88 @@
package main
// implements widgets 'Window' and 'Tab'
import (
"git.wit.org/wit/gui/toolkit"
// "github.com/awesome-gocui/gocui"
)
func (w *cuiWidget) hideWidgets() {
switch w.widgetType {
case toolkit.Root:
case toolkit.Flag:
case toolkit.Window:
case toolkit.Tab:
case toolkit.Box:
case toolkit.Grid:
default:
if (w.v != nil) {
me.baseGui.DeleteView(w.cuiName)
w.v = nil
}
}
for _, child := range w.children {
child.hideWidgets()
}
}
func (w *cuiWidget) showWidgets() {
w.drawView()
for _, child := range w.children {
child.showWidgets()
}
}
func (w *cuiWidget) redoTabs(draw bool) {
log(logNow, "redoTabs() START", w.name)
if (w == nil) {
return
}
if (w.widgetType == toolkit.Root) {
w.logicalSize.w0 = 0
w.logicalSize.h0 = 0
w.logicalSize.w1 = 0
w.logicalSize.h1 = 0
w.nextW = 2
w.nextH = 2
}
log(logNow, "redoTabs() about to check for window and tab ", w.name)
w.text = w.name
t := len(w.text)
if ((w.widgetType == toolkit.Window) || (w.widgetType == toolkit.Tab)) {
log(logNow, "redoTabs() in Window and Tab", w.name)
w.realWidth = t + 2
w.realHeight = me.defaultHeight
w.realSize.w0 = me.rootNode.logicalSize.w1
w.realSize.h0 = 0
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realHeight
w.logicalSize.w0 = 0
w.logicalSize.h0 = 0
w.logicalSize.w1 = 0
w.logicalSize.h1 = w.realHeight
// spaces right 1 space to next tab widget
// spaces down 1 line to the next widget
w.nextW = 2
w.nextH = w.realHeight + 1
me.rootNode.logicalSize.w1 = w.realSize.w1 + 1
me.rootNode.logicalSize.h1 = 0
me.baseGui.DeleteView(w.cuiName)
w.v = nil
w.drawView()
w.showWidgetPlacement(logNow, "redoTabs()")
}
log(logNow, "redoTabs() about to for loop children", w.name)
for _, child := range w.children {
log(logNow, "redoTabs() got to child", child.name)
child.redoTabs(draw)
}
}

86
toolkit/gocui/view.go Normal file
View File

@ -0,0 +1,86 @@
package main
import (
"fmt"
"errors"
"strconv"
"bufio"
"strings"
"github.com/awesome-gocui/gocui"
// "git.wit.org/wit/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 (w *cuiWidget) textResize() {
var width, height int
for i, s := range splitLines(w.text) {
log(logNow, "textResize() len =", len(s), i, s)
if (width < len(s)) {
width = len(s)
}
height = i
}
w.realWidth = width + 3
w.realHeight = me.defaultHeight + height
w.realSize.w1 = w.realSize.w0 + w.realWidth
w.realSize.h1 = w.realSize.h0 + w.realHeight
w.showWidgetPlacement(logNow, "textResize()")
}
func (w *cuiWidget) drawView() {
var err error
if (w.cuiName == "") {
log(logError, "drawView() w.cuiName was not set for widget", w)
w.cuiName = strconv.Itoa(w.id)
}
if (w.v != nil) {
log(logInfo, "drawView() w.v already defined for widget", w)
v, _ := me.baseGui.View(w.cuiName)
if (v == nil) {
log(logError, "drawView() ERROR view does not really exist", w)
w.v = nil
} else {
return
}
}
v, _ := me.baseGui.View(w.cuiName)
if (v != nil) {
log(logError, "drawView() already defined for name", w.cuiName)
w.v = v
return
}
a := w.realSize.w0
b := w.realSize.h0
c := w.realSize.w1
d := w.realSize.h1
w.v, err = me.baseGui.SetView(w.cuiName, a, b, c, d, 0)
if err == nil {
log(logError, "drawView() internal plugin error err = nil")
return
}
if !errors.Is(err, gocui.ErrUnknownView) {
log(logError, "drawView() internal plugin error error.IS()", err)
return
}
me.baseGui.SetKeybinding(w.v.Name(), gocui.MouseLeft, gocui.ModNone, click)
w.v.Wrap = true
fmt.Fprintln(w.v, " " + w.text)
// w.SetDefaultWidgetColor()
}

View File

@ -1,80 +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"
// "git.wit.org/wit/gui/toolkit"
)
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(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(x0, y0, x1, y1)
return nil
}

View File

@ -1,16 +0,0 @@
package main
import (
"git.wit.org/wit/gui/toolkit"
)
func NewWindow(w *toolkit.Widget) {
if (w == nil) {
log("wit/gui plugin error. widget == nil")
return
}
if (w.Name == "") {
w.Name = "nil newWindow"
}
log("gui.gocui.AddWindow", w.Name)
}

View File

@ -19,7 +19,7 @@ type ActionType int
// "Interaction" as per wikipedia [[User interface]] // "Interaction" as per wikipedia [[User interface]]
// Could a protobuf be used here? (Can functions be passed?) // Could a protobuf be used here? (Can functions be passed?)
type Widget struct { type Widget struct {
Name string // Name string
Type WidgetType Type WidgetType
// This function is how you interact with the toolkit // This function is how you interact with the toolkit
@ -27,7 +27,6 @@ type Widget struct {
// Hopefully this will be the barrier between the goroutines // Hopefully this will be the barrier between the goroutines
// TODO: move this interaction to channels // TODO: move this interaction to channels
Custom func() Custom func()
Callback func()
// re-adding an id to test channels // re-adding an id to test channels
Id int Id int
@ -55,7 +54,7 @@ type Action struct {
// this should be the widget // this should be the widget
// if the action is New, Hide, Enable, etc // if the action is New, Hide, Enable, etc
Widget *Widget Widget *Widget
Callback func(int) Callback func(int) bool
// This is how the values are passed back and forth // This is how the values are passed back and forth
// values from things like checkboxes & dropdown's // values from things like checkboxes & dropdown's
@ -66,6 +65,8 @@ type Action struct {
// (still probably not, almost certainly not. not possible. layer violation?) // (still probably not, almost certainly not. not possible. layer violation?)
S string // not safe to have 'S' S string // not safe to have 'S'
A any
// This GUI is intended for simple things // This GUI is intended for simple things
// We are not laying out PDF's here // We are not laying out PDF's here
// This is used for things like a slider(0,100) // This is used for things like a slider(0,100)

View File

@ -42,6 +42,8 @@ func NewWindow() *Node {
a.ActionType = toolkit.Add a.ActionType = toolkit.Add
a.Width = Config.Width a.Width = Config.Width
a.Height = Config.Height a.Height = Config.Height
a.Name = Config.Title
a.Text = Config.Title
newaction(&a, newNode, Config.rootNode) newaction(&a, newNode, Config.rootNode)
return newNode return newNode