Compare commits
50 Commits
Author | SHA1 | Date |
---|---|---|
|
86aa5fb001 | |
|
262426fb44 | |
|
ec0807ce2b | |
|
ce1d9457f9 | |
|
664ce4dfae | |
|
7b6af30194 | |
|
e0c55e73d2 | |
|
4efbfa7a1d | |
|
9669a63c5d | |
|
bf250b5ac6 | |
|
aaebb4c5d9 | |
|
36514cbb68 | |
|
1552eedc18 | |
|
4523eda0fa | |
|
3acf473792 | |
|
6c3149c0fe | |
|
784eac740f | |
|
a88937c508 | |
|
96eac58cf5 | |
|
b8781b1b64 | |
|
126b9a30a2 | |
|
994449b1c2 | |
|
5ebb13a454 | |
|
6127fa1cbb | |
|
54bbe72aa8 | |
|
b373eab346 | |
|
e73cfaf490 | |
|
046e6b4d6c | |
|
efb5ede4b9 | |
|
5e6d7cffdf | |
|
76e15fa1df | |
|
75014f4b28 | |
|
9ef16c1bf2 | |
|
da54c0f039 | |
|
6d1dfed3db | |
|
65cf744a86 | |
|
caf7428ba3 | |
|
948d2af071 | |
|
ddd7709182 | |
|
9912c3eb82 | |
|
660d9e7e3a | |
|
0124d25c34 | |
|
ed3789c23f | |
|
6f739933b7 | |
|
4b79e862a7 | |
|
dc329ed18c | |
|
3e7287baea | |
|
04406b3561 | |
|
0638183356 | |
|
f24c509859 |
|
@ -5,3 +5,4 @@
|
||||||
go.mod
|
go.mod
|
||||||
go.sum
|
go.sum
|
||||||
gocui
|
gocui
|
||||||
|
resources/*.so
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -23,9 +23,9 @@ custom:
|
||||||
GO111MODULE=off go build -v -work -buildmode=blah
|
GO111MODULE=off go build -v -work -buildmode=blah
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f gocui gocui.so go.*
|
rm -f gocui *.so go.*
|
||||||
rm -f *.pb.go *.patch
|
rm -f *.pb.go *.patch
|
||||||
go-mod-clean --purge
|
go-mod-clean purge
|
||||||
|
|
||||||
# Test the README.md & doc.go file
|
# Test the README.md & doc.go file
|
||||||
# this runs pkgsite, the binary that does dev.go.dev
|
# this runs pkgsite, the binary that does dev.go.dev
|
||||||
|
|
34
color.go
34
color.go
|
@ -186,6 +186,27 @@ func (tk *guiWidget) setColorLabel() {
|
||||||
tk.updateColor()
|
tk.updateColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) setColorLabelTable() {
|
||||||
|
if tk.color == nil {
|
||||||
|
tk.color = new(colorT)
|
||||||
|
}
|
||||||
|
if me.dark {
|
||||||
|
tk.color.frame = gocui.AttrNone
|
||||||
|
tk.color.fg = gocui.ColorWhite
|
||||||
|
tk.color.bg = gocui.ColorBlack
|
||||||
|
tk.color.selFg = gocui.ColorWhite
|
||||||
|
tk.color.selBg = gocui.AttrNone
|
||||||
|
} else {
|
||||||
|
tk.color.frame = gocui.AttrNone
|
||||||
|
tk.color.fg = gocui.ColorBlack
|
||||||
|
tk.color.bg = gocui.AttrNone
|
||||||
|
tk.color.selFg = gocui.AttrNone
|
||||||
|
tk.color.selBg = gocui.ColorGreen
|
||||||
|
}
|
||||||
|
|
||||||
|
tk.updateColor()
|
||||||
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) setColorButtonDense() {
|
func (tk *guiWidget) setColorButtonDense() {
|
||||||
if tk.color == nil {
|
if tk.color == nil {
|
||||||
tk.color = new(colorT)
|
tk.color = new(colorT)
|
||||||
|
@ -207,6 +228,19 @@ func (tk *guiWidget) setColorButtonDense() {
|
||||||
tk.updateColor()
|
tk.updateColor()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) setColorNotifyIcon() {
|
||||||
|
if tk.color == nil {
|
||||||
|
tk.color = new(colorT)
|
||||||
|
}
|
||||||
|
tk.color.frame = gocui.AttrNone
|
||||||
|
tk.color.fg = gocui.ColorWhite
|
||||||
|
tk.color.bg = gocui.ColorBlue
|
||||||
|
tk.color.selFg = gocui.ColorBlue
|
||||||
|
tk.color.selBg = gocui.AttrNone
|
||||||
|
|
||||||
|
tk.updateColor()
|
||||||
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) setColorButton() {
|
func (tk *guiWidget) setColorButton() {
|
||||||
if tk.color == nil {
|
if tk.color == nil {
|
||||||
tk.color = new(colorT)
|
tk.color = new(colorT)
|
||||||
|
|
4
debug.go
4
debug.go
|
@ -86,6 +86,10 @@ func (tk *guiWidget) dumpWidget(s string) {
|
||||||
} else {
|
} else {
|
||||||
end = fmt.Sprintf("%-8s %-8s %s", tk.WidgetType(), tk.cuiName, tk.String())
|
end = fmt.Sprintf("%-8s %-8s %s", tk.WidgetType(), tk.cuiName, tk.String())
|
||||||
}
|
}
|
||||||
|
if tk.node.InTable() {
|
||||||
|
// log.Log(GOCUI, "findParentTAble()", tk.labelN, tk.cuiName, tk.node.WidgetId)
|
||||||
|
end += " (table)"
|
||||||
|
}
|
||||||
log.Log(GOCUI, s1, s, end)
|
log.Log(GOCUI, s1, s, end)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
|
@ -18,7 +17,7 @@ import (
|
||||||
func registerHandlers(g *gocui.Gui) {
|
func registerHandlers(g *gocui.Gui) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Fprintln(outf, "EVENT BINDINGS recovered in r", r)
|
log.Info("EVENT BINDINGS recovered in r", r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
@ -59,6 +58,7 @@ func registerHandlers(g *gocui.Gui) {
|
||||||
g.SetKeybinding("", 'L', gocui.ModNone, printWidgetTree) // 'L' list all widgets in tree view
|
g.SetKeybinding("", 'L', gocui.ModNone, printWidgetTree) // 'L' list all widgets in tree view
|
||||||
g.SetKeybinding("", 'f', gocui.ModNone, theFind) // 'f' shows what is under your mouse
|
g.SetKeybinding("", 'f', gocui.ModNone, theFind) // 'f' shows what is under your mouse
|
||||||
g.SetKeybinding("", 'd', gocui.ModNone, theLetterD) // 'd' toggles on and off debugging buttons
|
g.SetKeybinding("", 'd', gocui.ModNone, theLetterD) // 'd' toggles on and off debugging buttons
|
||||||
|
g.SetKeybinding("", 'r', gocui.ModNone, reverseStdout) // 'r' turns scrolling of STDOUT upside down
|
||||||
g.SetKeybinding("", 'q', gocui.ModNone, quit) // 'q' only exits gocui. plugin stays alive (?)
|
g.SetKeybinding("", 'q', gocui.ModNone, quit) // 'q' only exits gocui. plugin stays alive (?)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +78,10 @@ func theSuperMouse(g *gocui.Gui, v *gocui.View) error {
|
||||||
// use this to test code ideas // put whatever you want here and hit '2' to activate it
|
// use this to test code ideas // put whatever you want here and hit '2' to activate it
|
||||||
func theNotsure(g *gocui.Gui, v *gocui.View) error {
|
func theNotsure(g *gocui.Gui, v *gocui.View) error {
|
||||||
log.Info("got to theNotsure(). now what? dark =", me.dark)
|
log.Info("got to theNotsure(). now what? dark =", me.dark)
|
||||||
|
me.refresh = true
|
||||||
|
log.Info("running VerifyParentId()")
|
||||||
|
me.treeRoot.VerifyParentId()
|
||||||
|
/*
|
||||||
if me.debug {
|
if me.debug {
|
||||||
log.Info("debugging off")
|
log.Info("debugging off")
|
||||||
me.debug = false
|
me.debug = false
|
||||||
|
@ -90,7 +94,7 @@ func theNotsure(g *gocui.Gui, v *gocui.View) error {
|
||||||
win.dumpWidget("found() win. redrawing window:")
|
win.dumpWidget("found() win. redrawing window:")
|
||||||
win.makeWindowActive()
|
win.makeWindowActive()
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,28 +104,20 @@ func theDarkness(g *gocui.Gui, v *gocui.View) error {
|
||||||
log.Info("you have seen the light")
|
log.Info("you have seen the light")
|
||||||
} else {
|
} else {
|
||||||
me.dark = true
|
me.dark = true
|
||||||
log.Info("you have entered into darkness")
|
log.Info("you have entered into darkness (you may need to trigger SIGWINCH)")
|
||||||
|
log.Info("or maybe open a new window. notsure. This obviously isn't finished.")
|
||||||
|
log.Info("submit patches to this and you will definitely get free cloud credits at WIT")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func wheelsUp(g *gocui.Gui, v *gocui.View) error {
|
func wheelsUp(g *gocui.Gui, v *gocui.View) error {
|
||||||
// log.Info("private wheels up")
|
stdoutWheelsUp()
|
||||||
me.stdout.pager -= 2
|
|
||||||
if me.stdout.pager < 0 {
|
|
||||||
me.stdout.pager = 0
|
|
||||||
}
|
|
||||||
me.stdout.tk.refreshStdout()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func wheelsDown(g *gocui.Gui, v *gocui.View) error {
|
func wheelsDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
// log.Info("you've landed")
|
stdoutWheelsDown()
|
||||||
me.stdout.pager += 2
|
|
||||||
if me.stdout.pager > len(me.stdout.outputS) {
|
|
||||||
me.stdout.pager = len(me.stdout.outputS)
|
|
||||||
}
|
|
||||||
me.stdout.tk.refreshStdout()
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,11 +141,13 @@ func doEsc(g *gocui.Gui, v *gocui.View) error {
|
||||||
me.dropdown.tk.Hide()
|
me.dropdown.tk.Hide()
|
||||||
me.dropdown.active = false
|
me.dropdown.active = false
|
||||||
log.Info("escaped from dropdown")
|
log.Info("escaped from dropdown")
|
||||||
|
me.baseGui.SetCurrentView(me.notify.clock.tk.cuiName)
|
||||||
}
|
}
|
||||||
if me.textbox.active {
|
if me.textbox.active {
|
||||||
me.textbox.tk.Hide()
|
me.textbox.tk.Hide()
|
||||||
me.textbox.active = false
|
me.textbox.active = false
|
||||||
log.Info("escaped from textbox")
|
log.Info("escaped from textbox")
|
||||||
|
me.baseGui.SetCurrentView(me.notify.clock.tk.cuiName)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -187,6 +185,19 @@ func theFind(g *gocui.Gui, v *gocui.View) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reverseStdout(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
if me.stdout.reverse {
|
||||||
|
me.stdout.reverse = false
|
||||||
|
log.Info("stdout scrolling normal")
|
||||||
|
} else {
|
||||||
|
me.stdout.reverse = true
|
||||||
|
log.Info("stdout scrolling is reversed. this is sometimes useful when you")
|
||||||
|
log.Info("only need to see a few most recent lines and have the STDOUT window")
|
||||||
|
log.Info("take up minimal realestate at the bottom of your window")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// is run whenever anyone hits 'd' (in an open space)
|
// is run whenever anyone hits 'd' (in an open space)
|
||||||
func theLetterD(g *gocui.Gui, v *gocui.View) error {
|
func theLetterD(g *gocui.Gui, v *gocui.View) error {
|
||||||
// widgets that don't have physical existance in
|
// widgets that don't have physical existance in
|
||||||
|
|
|
@ -8,12 +8,14 @@ import (
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
func theStdout(g *gocui.Gui, v *gocui.View) error {
|
func theStdout(g *gocui.Gui, v *gocui.View) error {
|
||||||
// me.stdout.pager = 0
|
// me.stdout.pager = 0
|
||||||
infos := fmt.Sprintf("pager=%d len(%d) ", me.stdout.pager, len(me.stdout.outputS))
|
infos := fmt.Sprintf("pager=%d len(%d) ", me.stdout.pager, len(me.stdout.outputS))
|
||||||
infos += fmt.Sprintf("last(%d,%d)", me.stdout.lastW, me.stdout.lastH)
|
infos += fmt.Sprintf("last(%d,%d)", me.stdout.lastW, me.stdout.lastH)
|
||||||
|
me.stdout.changed = true
|
||||||
|
|
||||||
if me.stdout.outputOnTop {
|
if me.stdout.outputOnTop {
|
||||||
if me.stdout.outputOffscreen {
|
if me.stdout.outputOffscreen {
|
||||||
|
@ -22,18 +24,38 @@ func theStdout(g *gocui.Gui, v *gocui.View) error {
|
||||||
me.stdout.lastW = me.stdout.tk.gocuiSize.w0
|
me.stdout.lastW = me.stdout.tk.gocuiSize.w0
|
||||||
me.stdout.lastH = me.stdout.tk.gocuiSize.h0
|
me.stdout.lastH = me.stdout.tk.gocuiSize.h0
|
||||||
relocateStdoutOffscreen()
|
relocateStdoutOffscreen()
|
||||||
|
new1 := new(tree.ToolkitConfig)
|
||||||
|
new1.Plugin = "gocui"
|
||||||
|
new1.Name = "stdoutoffscreen"
|
||||||
|
new1.Value = "true"
|
||||||
|
me.myTree.ConfigSave(new1)
|
||||||
return nil
|
return nil
|
||||||
} else {
|
} else {
|
||||||
me.stdout.outputOffscreen = true
|
me.stdout.outputOffscreen = true
|
||||||
log.Info("stdout moved on screen", infos)
|
log.Info("stdout moved on screen", infos)
|
||||||
|
new1 := new(tree.ToolkitConfig)
|
||||||
|
new1.Plugin = "gocui"
|
||||||
|
new1.Name = "stdoutoffscreen"
|
||||||
|
new1.Value = "false"
|
||||||
|
me.myTree.ConfigSave(new1)
|
||||||
}
|
}
|
||||||
// move the stdout window back onscreen
|
// move the stdout window back onscreen
|
||||||
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
||||||
me.stdout.outputOnTop = false
|
me.stdout.outputOnTop = false
|
||||||
setThingsOnTop()
|
setThingsOnTop()
|
||||||
|
new1 := new(tree.ToolkitConfig)
|
||||||
|
new1.Plugin = "gocui"
|
||||||
|
new1.Name = "stdoutlevel"
|
||||||
|
new1.Value = "bottom"
|
||||||
|
me.myTree.ConfigSave(new1)
|
||||||
} else {
|
} else {
|
||||||
me.stdout.outputOnTop = true
|
me.stdout.outputOnTop = true
|
||||||
setThingsOnTop()
|
setThingsOnTop()
|
||||||
|
new1 := new(tree.ToolkitConfig)
|
||||||
|
new1.Plugin = "gocui"
|
||||||
|
new1.Name = "stdoutlevel"
|
||||||
|
new1.Value = "top"
|
||||||
|
me.myTree.ConfigSave(new1)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -55,14 +77,20 @@ func stdoutHome(g *gocui.Gui, v *gocui.View) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func stdoutArrowUp(g *gocui.Gui, v *gocui.View) error {
|
func stdoutArrowUp(g *gocui.Gui, v *gocui.View) error {
|
||||||
me.stdout.pager += 1
|
if me.stdout.reverse {
|
||||||
me.stdout.tk.refreshStdout()
|
stdoutWheelsDown()
|
||||||
|
} else {
|
||||||
|
stdoutWheelsUp()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func stdoutArrowDown(g *gocui.Gui, v *gocui.View) error {
|
func stdoutArrowDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
me.stdout.pager -= 1
|
if me.stdout.reverse {
|
||||||
me.stdout.tk.refreshStdout()
|
stdoutWheelsUp()
|
||||||
|
} else {
|
||||||
|
stdoutWheelsDown()
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,3 +109,23 @@ func stdoutPgdn(g *gocui.Gui, v *gocui.View) error {
|
||||||
tk.refreshStdout()
|
tk.refreshStdout()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scrolling up with the mouse wheel (or trackpad)
|
||||||
|
func stdoutWheelsUp() {
|
||||||
|
// log.Info("private wheels up")
|
||||||
|
me.stdout.pager -= 2
|
||||||
|
if me.stdout.pager < 0 {
|
||||||
|
me.stdout.pager = 0
|
||||||
|
}
|
||||||
|
me.stdout.tk.refreshStdout()
|
||||||
|
}
|
||||||
|
|
||||||
|
// scrolling down with the mouse wheel (or trackpad)
|
||||||
|
func stdoutWheelsDown() {
|
||||||
|
// log.Info("you've landed")
|
||||||
|
me.stdout.pager += 2
|
||||||
|
if me.stdout.pager > len(me.stdout.outputS) {
|
||||||
|
me.stdout.pager = len(me.stdout.outputS)
|
||||||
|
}
|
||||||
|
me.stdout.tk.refreshStdout()
|
||||||
|
}
|
||||||
|
|
|
@ -5,9 +5,9 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -40,6 +40,36 @@ func quit(g *gocui.Gui, v *gocui.View) error {
|
||||||
return gocui.ErrQuit
|
return gocui.ErrQuit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) SetView() error {
|
||||||
|
if me.baseGui == nil {
|
||||||
|
return fmt.Errorf("me.baseGui == nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
r := new(rectType)
|
||||||
|
r.w0 = tk.gocuiSize.w0
|
||||||
|
r.h0 = tk.gocuiSize.h0
|
||||||
|
r.w1 = tk.gocuiSize.w1
|
||||||
|
r.h1 = tk.gocuiSize.h1
|
||||||
|
|
||||||
|
return tk.SetViewRect(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) SetViewRect(r *rectType) error {
|
||||||
|
if me.baseGui == nil {
|
||||||
|
return fmt.Errorf("me.baseGui == nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
var err error
|
||||||
|
tk.v, err = me.baseGui.SetView(tk.cuiName, r.w0, r.h0, r.w1, r.h1, 0)
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||||
|
log.Log(ERROR, "SetView() global failed on name =", tk.cuiName)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func SetView(name string, x0, y0, x1, y1 int, overlaps byte) *gocui.View {
|
func SetView(name string, x0, y0, x1, y1 int, overlaps byte) *gocui.View {
|
||||||
if me.baseGui == nil {
|
if me.baseGui == nil {
|
||||||
log.Log(ERROR, "SetView() ERROR: me.baseGui == nil")
|
log.Log(ERROR, "SetView() ERROR: me.baseGui == nil")
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/awesome-gocui/gocui"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/widget"
|
"go.wit.com/widget"
|
||||||
)
|
)
|
||||||
|
@ -26,7 +27,7 @@ func doMouseClick(w int, h int) {
|
||||||
// can't drag or do anything when dropdown or textbox are visible
|
// can't drag or do anything when dropdown or textbox are visible
|
||||||
for _, tk := range findByXY(w, h) {
|
for _, tk := range findByXY(w, h) {
|
||||||
if tk.WidgetId() == me.dropdown.wId {
|
if tk.WidgetId() == me.dropdown.wId {
|
||||||
log.Info("got dropdwon click", w, h, tk.cuiName)
|
log.Info("got dropdown click", w, h, tk.cuiName)
|
||||||
tk.dropdownClicked(w, h)
|
tk.dropdownClicked(w, h)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -42,7 +43,32 @@ func doMouseClick(w int, h int) {
|
||||||
|
|
||||||
win := findWindowUnderMouse()
|
win := findWindowUnderMouse()
|
||||||
if win == nil {
|
if win == nil {
|
||||||
log.Log(GOCUI, "click() nothing was at:", w, h)
|
log.Log(INFO, "click() nothing was at:", w, h)
|
||||||
|
log.Log(INFO, "click() check if", w, h, "is the libnotify icon")
|
||||||
|
if me.notify.icon.tk != nil && me.notify.icon.tk.gocuiSize.inRect(w, h) {
|
||||||
|
log.Log(GOCUI, "click() is libnotify.icon!")
|
||||||
|
if me.notify.icon.active {
|
||||||
|
log.Info("show notify.icon here")
|
||||||
|
setNotifyIconText("[X]")
|
||||||
|
me.notify.icon.active = false
|
||||||
|
} else {
|
||||||
|
log.Info("hide notify.icon here")
|
||||||
|
setNotifyIconText("[ ]")
|
||||||
|
me.notify.icon.active = true
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if me.notify.clock.tk != nil && me.notify.clock.tk.gocuiSize.inRect(w, h) {
|
||||||
|
log.Log(GOCUI, "click() is the clock!")
|
||||||
|
if me.showHelp {
|
||||||
|
log.Info("show help")
|
||||||
|
showHelp()
|
||||||
|
} else {
|
||||||
|
log.Info("hide help")
|
||||||
|
hideHelp()
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if !win.isWindowActive() {
|
if !win.isWindowActive() {
|
||||||
|
@ -81,8 +107,17 @@ func doMouseClick(w int, h int) {
|
||||||
tk.showDropdown()
|
tk.showDropdown()
|
||||||
return
|
return
|
||||||
case widget.Textbox:
|
case widget.Textbox:
|
||||||
|
log.Log(WARN, "TODO: textbox click")
|
||||||
tk.prepTextbox()
|
tk.prepTextbox()
|
||||||
return
|
return
|
||||||
|
case widget.Label:
|
||||||
|
if tk.node.InTable() {
|
||||||
|
if tk.node.State.AtH == 0 {
|
||||||
|
log.Log(NOW, "todo: sort by column here")
|
||||||
|
tk.dumpWidget("sort")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
// TODO: enable the GUI debugger in gocui
|
// TODO: enable the GUI debugger in gocui
|
||||||
// tk.dumpWidget("undef click()") // enable this to debug widget clicks
|
// tk.dumpWidget("undef click()") // enable this to debug widget clicks
|
||||||
|
@ -90,6 +125,12 @@ func doMouseClick(w int, h int) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// todo: use this?
|
||||||
|
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
log.Info("todo: clicked with ctrlDown")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func doMouseDoubleClick(w int, h int) {
|
func doMouseDoubleClick(w int, h int) {
|
||||||
me.mouse.double = false
|
me.mouse.double = false
|
||||||
// log.Printf("actually a double click (%d,%d)", w, h)
|
// log.Printf("actually a double click (%d,%d)", w, h)
|
||||||
|
|
|
@ -48,6 +48,7 @@ func mouseMove(g *gocui.Gui) {
|
||||||
// old hack. create the 'msg' view if it does not yet exist
|
// old hack. create the 'msg' view if it does not yet exist
|
||||||
// TODO: put this somewhere more correct
|
// TODO: put this somewhere more correct
|
||||||
if widgetView, _ := g.View("msg"); widgetView == nil {
|
if widgetView, _ := g.View("msg"); widgetView == nil {
|
||||||
|
me.stdout.changed = true
|
||||||
if createStdout(g) {
|
if createStdout(g) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -110,15 +111,7 @@ func (tk *guiWidget) moveNew() {
|
||||||
tk.makeWindowActive()
|
tk.makeWindowActive()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if tk.WidgetType() == widget.Flag {
|
|
||||||
me.baseGui.SetView(tk.cuiName, w-3, h-3, w+20, h+20, 0)
|
|
||||||
// tk.verifyRect()
|
|
||||||
s := fmt.Sprintf("move(%dx%d) %s ###", w, h, tk.cuiName)
|
|
||||||
tk.dumpWidget(s)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
if tk.WidgetType() == widget.Stdout {
|
if tk.WidgetType() == widget.Stdout {
|
||||||
if me.mouse.resize {
|
if me.mouse.resize {
|
||||||
newW := w - me.stdout.lastW
|
newW := w - me.stdout.lastW
|
||||||
|
@ -138,5 +131,6 @@ func (tk *guiWidget) moveNew() {
|
||||||
// log.Info("Resize false", w, h, newW, newH)
|
// log.Info("Resize false", w, h, newW, newH)
|
||||||
}
|
}
|
||||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||||
|
me.stdout.changed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
82
find.go
82
find.go
|
@ -94,25 +94,6 @@ func (tk *guiWidget) findWindows() []*guiWidget {
|
||||||
return found
|
return found
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the BG widget.
|
|
||||||
// This widget is always in the background and covers the whole screen.
|
|
||||||
// gocui seems to not return mouse events unless there is something there
|
|
||||||
func (tk *guiWidget) findBG() *guiWidget {
|
|
||||||
if tk.WidgetType() == widget.Stdout {
|
|
||||||
if tk.WidgetId() != me.stdout.wId {
|
|
||||||
tk.isBG = true
|
|
||||||
return tk
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, child := range tk.children {
|
|
||||||
if found := child.findBG(); found != nil {
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// used by gocui.TabKey to rotate through the windows
|
// used by gocui.TabKey to rotate through the windows
|
||||||
func findNextWindow() *guiWidget {
|
func findNextWindow() *guiWidget {
|
||||||
var found bool
|
var found bool
|
||||||
|
@ -148,13 +129,6 @@ func findWindowUnderMouse() *guiWidget {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// print out the window list
|
|
||||||
for _, tk := range me.allwin {
|
|
||||||
log.Info("findWindowUnderMouse() print:", tk.labelN, tk.window.active, tk.window.order)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// now check if the active window is below the mouse
|
// now check if the active window is below the mouse
|
||||||
for _, tk := range me.allwin {
|
for _, tk := range me.allwin {
|
||||||
if tk.window.active {
|
if tk.window.active {
|
||||||
|
@ -171,12 +145,6 @@ func findWindowUnderMouse() *guiWidget {
|
||||||
return a.window.order - b.window.order
|
return a.window.order - b.window.order
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// print out the window list
|
|
||||||
for _, tk := range me.allwin {
|
|
||||||
log.Info("findWindowUnderMouse() print:", tk.labelN, tk.window.active, tk.window.order)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
for _, win := range me.allwin {
|
for _, win := range me.allwin {
|
||||||
if win.full.inRect(w, h) {
|
if win.full.inRect(w, h) {
|
||||||
// log.Info(fmt.Sprintf("findWindowUnderMouse() found %s window (%dx%d)", win.cuiName, w, h))
|
// log.Info(fmt.Sprintf("findWindowUnderMouse() found %s window (%dx%d)", win.cuiName, w, h))
|
||||||
|
@ -195,12 +163,6 @@ func findWindowUnderMouse() *guiWidget {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: use this?
|
|
||||||
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
|
|
||||||
log.Info("todo: clicked with ctrlDown")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tk *guiWidget) findParentWindow() *guiWidget {
|
func (tk *guiWidget) findParentWindow() *guiWidget {
|
||||||
if tk.WidgetType() == widget.Window {
|
if tk.WidgetType() == widget.Window {
|
||||||
return tk
|
return tk
|
||||||
|
@ -210,3 +172,47 @@ func (tk *guiWidget) findParentWindow() *guiWidget {
|
||||||
}
|
}
|
||||||
return tk.parent.findParentWindow()
|
return tk.parent.findParentWindow()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) findWidgetByName(name string) *guiWidget {
|
||||||
|
if tk.cuiName == name {
|
||||||
|
return tk
|
||||||
|
}
|
||||||
|
for _, child := range tk.children {
|
||||||
|
found := child.findWidgetByName(name)
|
||||||
|
if found != nil {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) findWidgetByView(v *gocui.View) *guiWidget {
|
||||||
|
if tk.v == v {
|
||||||
|
return tk
|
||||||
|
}
|
||||||
|
if tk.cuiName == v.Name() {
|
||||||
|
log.Log(NOW, "findWidget() error. names are mismatched or out of sync", tk.cuiName)
|
||||||
|
log.Log(NOW, "findWidget() or maybe the view has been deleted")
|
||||||
|
// return tk
|
||||||
|
}
|
||||||
|
for _, child := range tk.children {
|
||||||
|
found := child.findWidgetByView(v)
|
||||||
|
if found != nil {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) findWidgetById(id int) *guiWidget {
|
||||||
|
if tk.WidgetId() == id {
|
||||||
|
return tk
|
||||||
|
}
|
||||||
|
for _, child := range tk.children {
|
||||||
|
found := child.findWidgetById(id)
|
||||||
|
if found != nil {
|
||||||
|
return found
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
125
help.go
125
help.go
|
@ -1,7 +1,7 @@
|
||||||
// Copyright 2014 The gocui Authors. All rights reserved.
|
|
||||||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||||
// Use of this source code is governed by the GPL 3.0
|
// Use of this source code is governed by the GPL 3.0
|
||||||
|
|
||||||
|
// Prior Copyright 2014 The gocui Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
log "go.wit.com/log"
|
log "go.wit.com/log"
|
||||||
|
@ -26,16 +25,20 @@ import (
|
||||||
|
|
||||||
var helpText []string = []string{"Help Menu",
|
var helpText []string = []string{"Help Menu",
|
||||||
"",
|
"",
|
||||||
"Tab: toggle through windows",
|
"Tab toggle through windows",
|
||||||
"O: toggle STDOUT",
|
"'O' toggle STDOUT",
|
||||||
"H: toggle this gocui menu",
|
"'H' toggle this gocui menu",
|
||||||
"L: toggle light/dark mode",
|
"'D' toggle light/dark mode",
|
||||||
"CTRL-c: quit()",
|
"CTRL-z background to shell",
|
||||||
|
"CTRL-c quit()",
|
||||||
"",
|
"",
|
||||||
"Debugging:",
|
"Debugging:",
|
||||||
"S: Supermouse mode",
|
"'S' Supermouse mode",
|
||||||
"M: list all widget positions",
|
"'M' list all widget positions",
|
||||||
"L: list all widgets in tree",
|
"'L' list all widgets in tree",
|
||||||
|
"<Pgup> scroll up the STDOUT window",
|
||||||
|
"<Pgdn> scroll down the STDOUT window",
|
||||||
|
"'r' reverse STDOUT scrolling",
|
||||||
}
|
}
|
||||||
|
|
||||||
func hideHelp() {
|
func hideHelp() {
|
||||||
|
@ -66,17 +69,18 @@ func showHelp() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
help, err := g.SetView("help", maxX-(newW+me.FramePadW), 0, maxX-1, len(helpText)+me.FramePadH, 0)
|
a := maxX - (newW + me.FramePadW)
|
||||||
|
b := me.notify.help.offsetH
|
||||||
|
c := maxX - 1
|
||||||
|
d := me.notify.help.offsetH + len(helpText) + me.FramePadH
|
||||||
|
|
||||||
|
help, err := g.SetView("help", a, b, c, d, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
help.SelBgColor = gocui.ColorGreen
|
help.SelBgColor = gocui.ColorGreen
|
||||||
help.SelFgColor = gocui.ColorBlack
|
help.SelFgColor = gocui.ColorBlack
|
||||||
// fmt.Fprintln(help, "Enter: Click Button")
|
|
||||||
// fmt.Fprintln(help, "Tab/Space: Switch Buttons")
|
|
||||||
// fmt.Fprintln(help, "Backspace: Delete Button")
|
|
||||||
// fmt.Fprintln(help, "Arrow keys: Move Button")
|
|
||||||
|
|
||||||
fmt.Fprintln(help, strings.Join(helpText, "\n"))
|
fmt.Fprintln(help, strings.Join(helpText, "\n"))
|
||||||
|
|
||||||
|
@ -86,94 +90,19 @@ func showHelp() error {
|
||||||
}
|
}
|
||||||
g.SetViewOnTop("help")
|
g.SetViewOnTop("help")
|
||||||
me.helpLabel = help
|
me.helpLabel = help
|
||||||
if me.clock.tk == nil {
|
|
||||||
makeClock()
|
/*
|
||||||
me.clock.tk.MoveToOffset(maxX-10, 1)
|
if me.treeRoot == nil {
|
||||||
me.clock.tk.Hide()
|
log.Info("gogui makeClock() error. treeRoot == nil")
|
||||||
me.clock.tk.Show()
|
return nil
|
||||||
}
|
} else {
|
||||||
if me.clock.tk != nil {
|
|
||||||
me.clock.tk.MoveToOffset(maxX-10, 1)
|
|
||||||
me.clock.tk.Hide()
|
|
||||||
me.clock.tk.Show()
|
|
||||||
}
|
|
||||||
if me.stdout.tk == nil {
|
if me.stdout.tk == nil {
|
||||||
makeOutputWidget(me.baseGui, "made this in showHelp()")
|
makeOutputWidget(me.baseGui, "made this in showHelp()")
|
||||||
msg := fmt.Sprintf("test to stdout from in showHelp() %d\n", me.ecount)
|
msg := fmt.Sprintf("test to stdout from in showHelp() %d\n", me.ecount)
|
||||||
me.stdout.Write([]byte(msg))
|
me.stdout.Write([]byte(msg))
|
||||||
log.Log(NOW, "log.log(NOW) test")
|
log.Log(NOW, "log.log(NOW) test")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeClock() {
|
|
||||||
me.clock.tk = makeNewFlagWidget(me.clock.wId)
|
|
||||||
me.clock.tk.dumpWidget("init() clock")
|
|
||||||
w, h := me.baseGui.MousePosition()
|
|
||||||
me.clock.tk.MoveToOffset(w, h)
|
|
||||||
me.clock.tk.labelN = time.Now().Format("15:04:05")
|
|
||||||
me.clock.tk.frame = false
|
|
||||||
me.clock.tk.setColorLabel()
|
|
||||||
me.clock.tk.Show()
|
|
||||||
me.clock.active = true
|
|
||||||
me.clock.tk.dumpWidget("showClock()")
|
|
||||||
}
|
|
||||||
|
|
||||||
// in the very end of redrawing things, this will place the help and stdout on the top or botton
|
|
||||||
// depending on the state the user has chosen
|
|
||||||
func setThingsOnTop() {
|
|
||||||
if me.showHelp { // terrible variable name. FIXME
|
|
||||||
// log.Info("help does not exist")
|
|
||||||
} else {
|
|
||||||
me.baseGui.SetViewOnTop("help")
|
|
||||||
}
|
|
||||||
if me.clock.tk != nil {
|
|
||||||
me.baseGui.SetViewOnTop(me.clock.tk.v.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
if me.stdout.tk == nil {
|
|
||||||
makeOutputWidget(me.baseGui, "from setThingsOnTop()")
|
|
||||||
}
|
|
||||||
if me.stdout.tk == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if me.stdout.tk.v == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if me.dark {
|
|
||||||
me.stdout.tk.v.FgColor = gocui.ColorWhite
|
|
||||||
me.stdout.tk.v.BgColor = gocui.ColorBlack
|
|
||||||
} else {
|
|
||||||
me.stdout.tk.v.FgColor = gocui.ColorBlack
|
|
||||||
me.stdout.tk.v.BgColor = gocui.AttrNone
|
|
||||||
}
|
|
||||||
|
|
||||||
if me.stdout.outputOnTop {
|
|
||||||
me.baseGui.SetViewOnTop("msg")
|
|
||||||
} else {
|
|
||||||
me.baseGui.SetViewOnBottom("msg")
|
|
||||||
}
|
|
||||||
if me.stdout.startOnscreen {
|
|
||||||
// log.Info("THIS TRIGGERS STDOUT") // todo: make a proper init() & move this there
|
|
||||||
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
|
||||||
me.stdout.startOnscreen = false
|
|
||||||
}
|
|
||||||
setBottomBG()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setBottomBG() {
|
|
||||||
// this attempts to find the "BG" widget and set it to the background on the very very bottom
|
|
||||||
rootTK := me.treeRoot.TK.(*guiWidget)
|
|
||||||
if tk := rootTK.findBG(); tk != nil {
|
|
||||||
// log.Info("found BG. setting to bottom", tk.cuiName)
|
|
||||||
if me.dark {
|
|
||||||
tk.v.BgColor = gocui.ColorBlack
|
|
||||||
} else {
|
|
||||||
tk.v.BgColor = gocui.ColorWhite
|
|
||||||
}
|
|
||||||
tk.v.Clear()
|
|
||||||
me.baseGui.SetViewOnBottom(tk.cuiName)
|
|
||||||
w, h := me.baseGui.Size()
|
|
||||||
me.baseGui.SetView(tk.cuiName, -1, -1, w+1, h+1, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
329
init.go
329
init.go
|
@ -14,10 +14,13 @@ import (
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/debug"
|
"runtime/debug"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
|
"go.wit.com/toolkits/tree"
|
||||||
)
|
)
|
||||||
|
|
||||||
// sent via -ldflags
|
// sent via -ldflags
|
||||||
|
@ -26,69 +29,128 @@ var BUILDTIME string
|
||||||
|
|
||||||
var PLUGIN string = "gocui"
|
var PLUGIN string = "gocui"
|
||||||
|
|
||||||
|
// this is called at the very initial connection
|
||||||
|
// between the app and this gocui plugin
|
||||||
|
// this is a good place to initialize gocui's default behavior
|
||||||
|
func toolkitInit() {
|
||||||
|
log.Log(INFO, "gocui toolkitInit() me.ok =", me.ok)
|
||||||
|
if me.baseGui == nil {
|
||||||
|
log.Info("gocui baseGui is still nil")
|
||||||
|
standardExit()
|
||||||
|
}
|
||||||
|
if me.treeRoot == nil {
|
||||||
|
log.Info("gocui treeRoot is still nil")
|
||||||
|
standardExit()
|
||||||
|
}
|
||||||
|
// w := me.treeRoot.TK.(*guiWidget)
|
||||||
|
// w.dumpTree("MM")
|
||||||
|
// w.dumpWindows("WW")
|
||||||
|
|
||||||
|
// SETUP HELP START
|
||||||
|
me.baseGui.Update(testRefresh)
|
||||||
|
log.Log(INFO, "gocui toolkitInit() trying showHelp() me.ok =", me.ok)
|
||||||
|
showHelp()
|
||||||
|
hideHelp()
|
||||||
|
// SETUP HELP END
|
||||||
|
|
||||||
|
// SETUP STDOUT START
|
||||||
|
if me.stdout.tk == nil {
|
||||||
|
makeOutputWidget(me.baseGui, "from setThingsOnTop()")
|
||||||
|
}
|
||||||
|
|
||||||
|
// time.Sleep(300 * time.Millisecond)
|
||||||
|
log.Log(INFO, "gocui toolkitInit() me.ok =", me.ok)
|
||||||
|
me.baseGui.Update(testRefresh)
|
||||||
|
if !me.stdout.init {
|
||||||
|
log.Log(INFO, "gocui toolkitInit() stdout.Init me.ok =", me.ok)
|
||||||
|
me.stdout.init = true
|
||||||
|
relocateStdoutOffscreen()
|
||||||
|
}
|
||||||
|
// time.Sleep(1 * time.Second)
|
||||||
|
me.stdout.outputOnTop = false
|
||||||
|
setThingsOnTop()
|
||||||
|
// SETUP STDOUT END
|
||||||
|
|
||||||
|
// SETUP BG
|
||||||
|
if me.BG.tk == nil {
|
||||||
|
me.BG.tk = makeNewInternalWidget(me.BG.wId)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SETUP libnotify clock and menu
|
||||||
|
me.notify.clock.once.Do(makeNotifyClock)
|
||||||
|
me.notify.icon.once.Do(makeNotifyIcon)
|
||||||
|
|
||||||
|
// TODO: for some reason, this makes the background doesn't display
|
||||||
|
// PUT INIT DEBUG COOE HERE
|
||||||
|
var toggle bool
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
// enable this to show early debugging
|
||||||
|
// w := me.treeRoot.TK.(*guiWidget)
|
||||||
|
// w.dumpTree("MM")
|
||||||
|
// w.dumpWindows("WW")
|
||||||
|
|
||||||
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
if toggle {
|
||||||
|
toggle = false
|
||||||
|
// log.Info("gocui toolkitInit() put testing true stuff here")
|
||||||
|
} else {
|
||||||
|
toggle = true
|
||||||
|
// log.Info("gocui toolkitInit() put testing false stuff here")
|
||||||
|
}
|
||||||
|
setBottomBG()
|
||||||
|
}
|
||||||
|
// PUT INIT DEBUG COOE HERE END
|
||||||
|
|
||||||
|
// TEST TEXTBOX START
|
||||||
|
// time.Sleep(1 * time.Second)
|
||||||
|
log.Log(INFO, "gocui toolkitInit() me.ok =", me.ok)
|
||||||
|
me.baseGui.Update(testRefresh)
|
||||||
|
if me.textbox.tk == nil {
|
||||||
|
log.Log(INFO, "gocui toolkitInit() initTextbox me.ok =", me.ok)
|
||||||
|
initTextbox()
|
||||||
|
}
|
||||||
|
// TEST TEXTBOX END
|
||||||
|
}
|
||||||
|
|
||||||
func toolkitClose() {
|
func toolkitClose() {
|
||||||
me.baseGui.Close()
|
me.baseGui.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// a GO GUI plugin should initTree in init()
|
||||||
|
// this should be done before the application
|
||||||
|
// starts trying to open up a channel
|
||||||
|
func init() {
|
||||||
|
me.myTree = initTree()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// sets defaults and establishes communication
|
// sets defaults and establishes communication
|
||||||
// to this toolkit from the wit/gui golang package
|
// to this toolkit from the wit/gui golang package
|
||||||
func initPlugin() {
|
func initPlugin() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Fprintf(outf, "PANIC: initPlugin() recovered %v\n", r)
|
fmt.Fprintf(me.outf, "PANIC: initPlugin() recovered %v\n", r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
// todo: make this a tmp file that goes away
|
|
||||||
outf, err = os.OpenFile("/tmp/captureMode.log", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("error opening file:", err)
|
|
||||||
os.Exit(0)
|
|
||||||
}
|
|
||||||
me.starttime = time.Now()
|
|
||||||
log.Log(INFO, "Init() of awesome-gocui")
|
|
||||||
|
|
||||||
// init the config struct default values
|
|
||||||
Set(&me, "default")
|
|
||||||
// todo: some early output still goes to the /tmp/ file
|
|
||||||
//time.Sleep(200 * time.Millisecond)
|
|
||||||
log.CaptureMode(me.stdout)
|
|
||||||
|
|
||||||
// initial stdout window settings
|
|
||||||
me.stdout.w = 180
|
|
||||||
me.stdout.h = 40
|
|
||||||
me.stdout.lastW = 4
|
|
||||||
me.stdout.lastH = 20
|
|
||||||
|
|
||||||
// just make up unique values for these
|
|
||||||
me.dropdown.wId = -77
|
|
||||||
me.textbox.wId = -55
|
|
||||||
me.stdout.wId = -4
|
|
||||||
me.clock.wId = -5
|
|
||||||
|
|
||||||
Set(&me.dropdown, "default")
|
|
||||||
// s := fmt.Sprintln("fake default check =", me.FakeW, "dropdown.Id", me.dropdown.Id)
|
|
||||||
// me.stdout.Write([]byte(s))
|
|
||||||
|
|
||||||
me.mouse.mouseUp = true
|
|
||||||
me.mouse.clicktime = time.Millisecond * 200
|
|
||||||
me.mouse.doubletime = time.Millisecond * 400
|
|
||||||
|
|
||||||
me.myTree = initTree()
|
|
||||||
|
|
||||||
me.newWindowTrigger = make(chan *guiWidget, 1)
|
|
||||||
go newWindowTrigger()
|
|
||||||
go refreshGocui()
|
|
||||||
|
|
||||||
// read in defaults from config protobuf
|
// read in defaults from config protobuf
|
||||||
if val, err := me.myTree.ConfigFind("stdout"); err == nil {
|
if val, err := me.myTree.ConfigFind("stdout"); err == nil {
|
||||||
if val == "true" {
|
if val == "true" {
|
||||||
me.stdout.startOnscreen = true
|
me.stdout.startOnscreen = true
|
||||||
// me.stdout.Write([]byte("starting with stdout onscreen\n"))
|
// me.stdout.Write([]byte("starting with stdout onscreen\n"))
|
||||||
} else {
|
}
|
||||||
// me.stdout.Write([]byte("starting with stdout offscreen\n"))
|
if val == "disable" {
|
||||||
|
log.Log(INFO, "gocui: attempt to COMPLETELY DISABLE STDOUT LOG")
|
||||||
|
me.stdout.disable = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if val, err := me.myTree.ConfigFind("stdoutoffscreen"); err == nil {
|
||||||
|
if val == "false" {
|
||||||
|
// log.Log(NOW, "gocui: START ON SCREEN TRUE")
|
||||||
|
me.stdout.startOnscreen = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if val, err := me.myTree.ConfigFind("dark"); err == nil {
|
if val, err := me.myTree.ConfigFind("dark"); err == nil {
|
||||||
|
@ -101,16 +163,92 @@ func initPlugin() {
|
||||||
me.dark = true
|
me.dark = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// todo: make this a tmp file that goes away
|
||||||
|
if !me.stdout.disable {
|
||||||
|
tmpFile, err := os.CreateTemp("", "gocui-*.log")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error creating temp file:", err)
|
||||||
|
standardExit()
|
||||||
|
}
|
||||||
|
// defer os.Remove(tmpFile.Name())
|
||||||
|
|
||||||
|
log.Log(INFO, "stdout.disable == true. writing to", tmpFile.Name())
|
||||||
|
me.outf = tmpFile
|
||||||
|
// todo: some early output still goes to the /tmp/ file
|
||||||
|
//time.Sleep(200 * time.Millisecond)
|
||||||
|
log.CaptureMode(me.stdout)
|
||||||
|
}
|
||||||
|
me.starttime = time.Now()
|
||||||
|
log.Log(INFO, "Init() of awesome-gocui")
|
||||||
|
|
||||||
|
// init the config struct default values
|
||||||
|
Set(&me, "default")
|
||||||
|
|
||||||
|
// initial app window settings
|
||||||
|
|
||||||
|
// initial stdout window settings
|
||||||
|
me.stdout.w = 180
|
||||||
|
me.stdout.h = 40
|
||||||
|
me.stdout.lastW = 4
|
||||||
|
me.stdout.lastH = 20
|
||||||
|
|
||||||
|
if val, err := me.myTree.ConfigFind("stdoutsize"); err == nil {
|
||||||
|
parts := strings.Fields(val)
|
||||||
|
if len(parts) == 4 {
|
||||||
|
log.Info("initial stdout settings:", parts, "setting startOnscreen = true")
|
||||||
|
me.stdout.w, _ = strconv.Atoi(parts[0])
|
||||||
|
me.stdout.h, _ = strconv.Atoi(parts[1])
|
||||||
|
me.stdout.lastW, _ = strconv.Atoi(parts[2])
|
||||||
|
me.stdout.lastH, _ = strconv.Atoi(parts[3])
|
||||||
|
me.stdout.startOnscreen = true
|
||||||
|
} else {
|
||||||
|
log.Info("initial stdout settings parse error:", parts)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// just make up unique values for these
|
||||||
|
me.dropdown.wId = -77
|
||||||
|
me.textbox.wId = -55
|
||||||
|
me.stdout.wId = -4
|
||||||
|
me.BG.wId = -22
|
||||||
|
|
||||||
|
// the clock widget id and offset
|
||||||
|
me.notify.clock.wId = -5
|
||||||
|
me.notify.clock.offsetW = 13
|
||||||
|
me.notify.clock.offsetH = 1
|
||||||
|
|
||||||
|
me.notify.icon.wId = -6
|
||||||
|
me.notify.icon.offsetW = 4
|
||||||
|
me.notify.icon.offsetH = 1
|
||||||
|
|
||||||
|
me.notify.help.wId = -7
|
||||||
|
me.notify.help.offsetH = 3
|
||||||
|
|
||||||
|
Set(&me.dropdown, "default")
|
||||||
|
// s := fmt.Sprintln("fake default check =", me.FakeW, "dropdown.Id", me.dropdown.Id)
|
||||||
|
// me.stdout.Write([]byte(s))
|
||||||
|
|
||||||
|
me.mouse.mouseUp = true
|
||||||
|
me.mouse.clicktime = time.Millisecond * 200
|
||||||
|
me.mouse.doubletime = time.Millisecond * 400
|
||||||
|
|
||||||
|
me.newWindowTrigger = make(chan *guiWidget, 1)
|
||||||
|
go newWindowTrigger()
|
||||||
|
go refreshGocui()
|
||||||
|
|
||||||
log.Log(NOW, "Init() start pluginChan")
|
log.Log(NOW, "Init() start pluginChan")
|
||||||
|
if me.stdout.disable {
|
||||||
os.Stdout = outf
|
log.Info("Using STDOUT")
|
||||||
|
} else {
|
||||||
log.CaptureMode(outf)
|
log.Info("Using gocui STDOUT")
|
||||||
|
os.Stdout = me.outf
|
||||||
|
log.CaptureMode(me.outf)
|
||||||
|
}
|
||||||
|
|
||||||
// init gocui
|
// init gocui
|
||||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
os.Exit(-1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
me.baseGui = g
|
me.baseGui = g
|
||||||
|
@ -129,7 +267,9 @@ func initPlugin() {
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
|
|
||||||
fmt.Fprintln(outf, "hello world", time.Since(me.starttime))
|
if me.outf != nil {
|
||||||
|
fmt.Fprintln(me.outf, "hello world", time.Since(me.starttime))
|
||||||
|
}
|
||||||
|
|
||||||
// coreStdout()
|
// coreStdout()
|
||||||
// createStdout(g)
|
// createStdout(g)
|
||||||
|
@ -145,12 +285,18 @@ func gocuiMain() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
log.Warn("PANIC ecovered in gocuiMain()", r)
|
log.Warn("PANIC ecovered in gocuiMain()", r)
|
||||||
fmt.Fprintf(outf, "PANIC recovered in r = %v", r)
|
if me.outf == nil {
|
||||||
os.Stderr = outf
|
|
||||||
os.Stdout = outf
|
|
||||||
debug.PrintStack()
|
debug.PrintStack()
|
||||||
pprof.Lookup("goroutine").WriteTo(outf, 1)
|
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
||||||
panic(outf)
|
panic(os.Stdout)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintf(me.outf, "PANIC recovered in r = %v", r)
|
||||||
|
os.Stderr = me.outf
|
||||||
|
os.Stdout = me.outf
|
||||||
|
debug.PrintStack()
|
||||||
|
pprof.Lookup("goroutine").WriteTo(me.outf, 1)
|
||||||
|
panic(me.outf)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
@ -165,8 +311,11 @@ func gocuiMain() {
|
||||||
func standardExit() {
|
func standardExit() {
|
||||||
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
||||||
me.baseGui.Close()
|
me.baseGui.Close()
|
||||||
|
if me.outf != nil {
|
||||||
log.Log(NOW, "standardExit() doing outf.Close()")
|
log.Log(NOW, "standardExit() doing outf.Close()")
|
||||||
outf.Close()
|
me.outf.Close()
|
||||||
|
os.Remove(me.outf.Name())
|
||||||
|
}
|
||||||
// log(true, "standardExit() setOutput(os.Stdout)")
|
// log(true, "standardExit() setOutput(os.Stdout)")
|
||||||
// setOutput(os.Stdout)
|
// setOutput(os.Stdout)
|
||||||
log.Log(NOW, "standardExit() send back Quit()")
|
log.Log(NOW, "standardExit() send back Quit()")
|
||||||
|
@ -181,7 +330,8 @@ func standardClose() {
|
||||||
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
||||||
me.baseGui.Close()
|
me.baseGui.Close()
|
||||||
log.Log(NOW, "standardExit() doing outf.Close()")
|
log.Log(NOW, "standardExit() doing outf.Close()")
|
||||||
outf.Close()
|
me.outf.Close()
|
||||||
|
os.Remove(me.outf.Name())
|
||||||
// os.Stdin = os.Stdin
|
// os.Stdin = os.Stdin
|
||||||
// os.Stdout = os.Stdout
|
// os.Stdout = os.Stdout
|
||||||
// os.Stderr = os.Stderr
|
// os.Stderr = os.Stderr
|
||||||
|
@ -194,12 +344,6 @@ func main() {
|
||||||
// this hack is to wait for the application to send something
|
// this hack is to wait for the application to send something
|
||||||
// before trying to do anything. todo: rethink this someday
|
// before trying to do anything. todo: rethink this someday
|
||||||
func waitOK() {
|
func waitOK() {
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
fmt.Fprintln(outf, "INIT PLUGIN recovered in r", r)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
for {
|
for {
|
||||||
if me.ok {
|
if me.ok {
|
||||||
return
|
return
|
||||||
|
@ -229,50 +373,64 @@ func testRefresh(*gocui.Gui) error {
|
||||||
func refreshGocui() {
|
func refreshGocui() {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
fmt.Fprintln(outf, "INIT PLUGIN recovered in r", r)
|
if me.outf == nil {
|
||||||
|
log.Info("INIT PLUGIN recovered in r", r)
|
||||||
|
} else {
|
||||||
|
fmt.Fprintln(me.outf, "INIT PLUGIN recovered in r", r)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
var lastRefresh time.Time
|
var lastRefresh time.Time
|
||||||
lastRefresh = time.Now()
|
lastRefresh = time.Now()
|
||||||
|
me.refresh = false
|
||||||
for {
|
for {
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
// log.Info("refresh checking ok")
|
// log.Info("refresh checking ok")
|
||||||
if !me.ok {
|
if !me.ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redraw the windows if something has changed
|
||||||
|
if time.Since(lastRefresh) > 1000*time.Millisecond {
|
||||||
|
if me.refresh {
|
||||||
|
log.Log(NOW, "newWindowTrigger() sending refresh to channel")
|
||||||
|
me.newWindowTrigger <- me.treeRoot.TK.(*guiWidget)
|
||||||
|
me.refresh = false
|
||||||
|
}
|
||||||
|
if me.stdout.changed {
|
||||||
|
me.stdout.changed = false
|
||||||
|
lastRefresh = time.Now()
|
||||||
|
new1 := new(tree.ToolkitConfig)
|
||||||
|
new1.Plugin = "gocui"
|
||||||
|
new1.Name = "stdoutsize"
|
||||||
|
width := me.stdout.tk.gocuiSize.w1 - me.stdout.tk.gocuiSize.w0
|
||||||
|
height := me.stdout.tk.gocuiSize.h1 - me.stdout.tk.gocuiSize.h0
|
||||||
|
new1.Value = fmt.Sprintf("%d %d %d %d", width, height, me.stdout.tk.gocuiSize.w0, me.stdout.tk.gocuiSize.h0)
|
||||||
|
me.myTree.ConfigSave(new1)
|
||||||
|
// log.Log(NOW, "newWindowTrigger() gocui setting stdout size =", new1.Value)
|
||||||
|
// me.stdout.tk.dumpWidget("save")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this code updates the clock
|
||||||
if time.Since(lastRefresh) > 1000*time.Millisecond {
|
if time.Since(lastRefresh) > 1000*time.Millisecond {
|
||||||
// artificially pause clock while dragging.
|
// artificially pause clock while dragging.
|
||||||
// this is a reminder to make this refresh code smarter
|
// this is a reminder to make this refresh code smarter
|
||||||
// after the switch to protocol buffers
|
// after the switch to protocol buffers
|
||||||
|
me.myTree.Lock()
|
||||||
if me.mouse.mouseUp {
|
if me.mouse.mouseUp {
|
||||||
// log.Info("refresh now on mouseUp")
|
// log.Info("refresh now on mouseUp")
|
||||||
// todo: add logic here to see if the application has changed anything
|
// todo: add logic here to see if the application has changed anything
|
||||||
// me.baseGui.UpdateAsync(testRefresh) // probably don't need this
|
libNotifyUpdate()
|
||||||
me.baseGui.Update(testRefresh)
|
|
||||||
if me.clock.tk != nil && !me.showHelp {
|
|
||||||
// also double check the gocui view exists
|
|
||||||
if me.clock.tk.v != nil {
|
|
||||||
me.clock.tk.v.Clear()
|
|
||||||
me.clock.tk.labelN = time.Now().Format("15:04:05")
|
|
||||||
me.clock.tk.v.WriteString(me.clock.tk.labelN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastRefresh = time.Now()
|
lastRefresh = time.Now()
|
||||||
} else {
|
} else {
|
||||||
me.baseGui.Update(testRefresh)
|
|
||||||
if time.Since(lastRefresh) > 3*time.Second {
|
if time.Since(lastRefresh) > 3*time.Second {
|
||||||
if me.clock.tk != nil && !me.showHelp {
|
libNotifyUpdate()
|
||||||
// also double check the gocui view exists
|
|
||||||
if me.clock.tk.v != nil {
|
|
||||||
me.clock.tk.v.Clear()
|
|
||||||
me.clock.tk.labelN = time.Now().Format("15:04:05")
|
|
||||||
me.clock.tk.v.WriteString(me.clock.tk.labelN)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastRefresh = time.Now()
|
lastRefresh = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
me.myTree.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,10 +444,11 @@ func newWindowTrigger() {
|
||||||
select {
|
select {
|
||||||
case tk := <-me.newWindowTrigger:
|
case tk := <-me.newWindowTrigger:
|
||||||
// log.Log(NOW, "newWindowTrigger() got new window", tk.cuiName)
|
// log.Log(NOW, "newWindowTrigger() got new window", tk.cuiName)
|
||||||
time.Sleep(200 * time.Millisecond)
|
// time.Sleep(200 * time.Millisecond)
|
||||||
waitOK()
|
waitOK()
|
||||||
time.Sleep(200 * time.Millisecond)
|
me.myTree.Lock()
|
||||||
redoWindows(3, 3)
|
// time.Sleep(200 * time.Millisecond)
|
||||||
|
redoWindows(me.FirstWindowW, me.FirstWindowH)
|
||||||
me.firstWindowOk = true
|
me.firstWindowOk = true
|
||||||
if !me.stdout.init {
|
if !me.stdout.init {
|
||||||
me.stdout.init = true
|
me.stdout.init = true
|
||||||
|
@ -297,9 +456,9 @@ func newWindowTrigger() {
|
||||||
}
|
}
|
||||||
if me.textbox.tk == nil {
|
if me.textbox.tk == nil {
|
||||||
initTextbox()
|
initTextbox()
|
||||||
me.textbox.tk.prepTextbox()
|
|
||||||
}
|
}
|
||||||
tk.makeWindowActive()
|
tk.makeWindowActive()
|
||||||
|
me.myTree.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,295 @@
|
||||||
|
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||||
|
// Use of this source code is governed by the GPL 3.0
|
||||||
|
|
||||||
|
// this file implements a libnotify-like menu
|
||||||
|
// also there is SIGWINCH resizing
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/awesome-gocui/gocui"
|
||||||
|
log "go.wit.com/log"
|
||||||
|
"go.wit.com/toolkits/tree"
|
||||||
|
"go.wit.com/widget"
|
||||||
|
)
|
||||||
|
|
||||||
|
// create a new widget in the binary tree
|
||||||
|
func makeNewInternalWidget(wId int) *guiWidget {
|
||||||
|
if me.treeRoot == nil {
|
||||||
|
log.Info("GOGUI Init ERROR. treeRoot == nil")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
n := new(tree.Node)
|
||||||
|
n.WidgetType = widget.Flag
|
||||||
|
n.WidgetId = wId
|
||||||
|
n.ParentId = 0
|
||||||
|
|
||||||
|
// store the internal toolkit information
|
||||||
|
tk := new(guiWidget)
|
||||||
|
tk.frame = true
|
||||||
|
|
||||||
|
tk.node = n
|
||||||
|
tk.node.Parent = me.treeRoot
|
||||||
|
|
||||||
|
// set the name used by gocui to the id
|
||||||
|
tk.cuiName = fmt.Sprintf("%d DR", wId)
|
||||||
|
|
||||||
|
tk.setColorInput()
|
||||||
|
|
||||||
|
// add this new widget on the binary tree
|
||||||
|
tk.parent = me.treeRoot.TK.(*guiWidget)
|
||||||
|
if tk.parent == nil {
|
||||||
|
panic("makeNewFlagWidget() didn't get treeRoot guiWidget")
|
||||||
|
} else {
|
||||||
|
tk.parent.children = append(tk.parent.children, tk)
|
||||||
|
}
|
||||||
|
|
||||||
|
n.TK = tk
|
||||||
|
return tk
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeNotifyClock() {
|
||||||
|
if me.treeRoot == nil {
|
||||||
|
log.Info("gogui makeClock() error. treeRoot == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
me.notify.clock.tk = makeNewInternalWidget(me.notify.clock.wId)
|
||||||
|
// me.notify.clock.tk.dumpWidget("init() clock")
|
||||||
|
me.notify.clock.tk.MoveToOffset(0, 0)
|
||||||
|
me.notify.clock.tk.labelN = time.Now().Format("15:04:05")
|
||||||
|
me.notify.clock.tk.frame = false
|
||||||
|
me.notify.clock.tk.setColorLabel()
|
||||||
|
me.notify.clock.tk.Show()
|
||||||
|
me.notify.clock.active = true
|
||||||
|
// me.notify.clock.tk.dumpWidget("notifyClock()")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeNotifyIcon() {
|
||||||
|
if me.treeRoot == nil {
|
||||||
|
log.Info("gogui makeClock() error. treeRoot == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
me.notify.icon.tk = makeNewInternalWidget(me.notify.icon.wId)
|
||||||
|
// me.notify.icon.tk.dumpWidget("init() menu")
|
||||||
|
w, _ := me.baseGui.Size()
|
||||||
|
me.notify.icon.tk.MoveToOffset(w-5, me.notify.icon.offsetH)
|
||||||
|
me.notify.icon.tk.labelN = "[ ]"
|
||||||
|
me.notify.icon.tk.frame = false
|
||||||
|
me.notify.icon.tk.setColorNotifyIcon()
|
||||||
|
me.notify.icon.tk.Show()
|
||||||
|
me.notify.icon.active = true
|
||||||
|
// me.notify.icon.tk.dumpWidget("notifyIcon()")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func libNotifyUpdate() {
|
||||||
|
if me.baseGui == nil {
|
||||||
|
log.Info("libNotifyUpdate error baseGui == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// refresh GOCUI
|
||||||
|
me.baseGui.Update(testRefresh)
|
||||||
|
// me.baseGui.UpdateAsync(testRefresh) // Async option. probably don't need this?
|
||||||
|
|
||||||
|
if me.notify.clock.tk == nil {
|
||||||
|
log.Info("libNotifyUpdate error clock.tk == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for SIGWINCH. If so, move the libnotify clock
|
||||||
|
w, h := me.baseGui.Size()
|
||||||
|
if me.winchW != w || me.winchH != h {
|
||||||
|
if me.winchW == 0 && me.winchH == 0 {
|
||||||
|
// this isn't really SIGWINCH. This is the app starting
|
||||||
|
} else {
|
||||||
|
log.Printf("gocui: long live SIGWINCH! (w,h) is now (%d,%d)\n", w, h)
|
||||||
|
}
|
||||||
|
me.winchW = w
|
||||||
|
me.winchH = h
|
||||||
|
me.notify.clock.tk.MoveToOffset(w-me.notify.clock.offsetW, me.notify.clock.offsetH)
|
||||||
|
me.notify.clock.tk.Hide()
|
||||||
|
me.notify.clock.tk.Show()
|
||||||
|
|
||||||
|
sigWinchBG()
|
||||||
|
sigWinchIcon()
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the time
|
||||||
|
me.notify.clock.tk.v.Clear()
|
||||||
|
me.notify.clock.tk.labelN = time.Now().Format("15:04:05")
|
||||||
|
me.notify.clock.tk.v.WriteString(me.notify.clock.tk.labelN)
|
||||||
|
hardDrawAtgocuiSize(me.notify.clock.tk)
|
||||||
|
// hardDrawUnderMouse(me.notify.clock.tk, "clock")
|
||||||
|
// log.Info("libNotifyUpdate updated clock", me.notify.clock.tk.labelN)
|
||||||
|
|
||||||
|
if me.notify.icon.tk == nil {
|
||||||
|
log.Info("libNotifyUpdate error menu.tk == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if me.notify.icon.tk.v == nil {
|
||||||
|
log.Info("libNotifyUpdate error menu.tk.v == nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// update the menu
|
||||||
|
hardDrawAtgocuiSize(me.notify.icon.tk)
|
||||||
|
me.notify.icon.tk.setColorNotifyIcon()
|
||||||
|
me.baseGui.SetViewOnTop(me.notify.icon.tk.v.Name())
|
||||||
|
me.baseGui.SetViewOnTop(me.notify.clock.tk.v.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func setNotifyIconText(s string) {
|
||||||
|
me.notify.icon.tk.v.Clear()
|
||||||
|
me.notify.icon.tk.labelN = s
|
||||||
|
me.notify.icon.tk.v.WriteString(me.notify.icon.tk.labelN)
|
||||||
|
hardDrawAtgocuiSize(me.notify.icon.tk)
|
||||||
|
me.notify.icon.tk.setColorNotifyIcon()
|
||||||
|
me.baseGui.SetViewOnTop(me.notify.icon.tk.v.Name())
|
||||||
|
log.Info("setNotifyIconText() updated menu to:", me.notify.icon.tk.labelN)
|
||||||
|
// print out the window list // TODO: put this in libnotify
|
||||||
|
for _, tk := range me.allwin {
|
||||||
|
log.Info("known window Window", tk.labelN, tk.window.active, tk.window.order)
|
||||||
|
}
|
||||||
|
if s == "[X]" {
|
||||||
|
log.Warn("should turn on help window here")
|
||||||
|
showHelp()
|
||||||
|
} else {
|
||||||
|
log.Warn("should turn off help window here")
|
||||||
|
hideHelp()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// in the very end of redrawing things, this will place the help and stdout on the top or botton
|
||||||
|
// depending on the state the user has chosen
|
||||||
|
func setThingsOnTop() {
|
||||||
|
if me.showHelp { // terrible variable name. FIXME
|
||||||
|
// log.Info("help does not exist")
|
||||||
|
} else {
|
||||||
|
me.baseGui.SetViewOnTop("help")
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.notify.clock.tk != nil {
|
||||||
|
me.baseGui.SetViewOnTop(me.notify.clock.tk.v.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.notify.icon.tk != nil {
|
||||||
|
if me.notify.icon.tk.v != nil {
|
||||||
|
me.baseGui.SetViewOnTop(me.notify.icon.tk.v.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.stdout.tk == nil {
|
||||||
|
makeOutputWidget(me.baseGui, "from setThingsOnTop()")
|
||||||
|
}
|
||||||
|
if me.stdout.tk == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if me.stdout.tk.v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if me.dark {
|
||||||
|
me.stdout.tk.v.FgColor = gocui.ColorWhite
|
||||||
|
me.stdout.tk.v.BgColor = gocui.ColorBlack
|
||||||
|
} else {
|
||||||
|
me.stdout.tk.v.FgColor = gocui.ColorBlack
|
||||||
|
me.stdout.tk.v.BgColor = gocui.AttrNone
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.stdout.outputOnTop {
|
||||||
|
me.baseGui.SetViewOnTop("msg")
|
||||||
|
} else {
|
||||||
|
me.baseGui.SetViewOnBottom("msg")
|
||||||
|
}
|
||||||
|
if me.stdout.startOnscreen {
|
||||||
|
// log.Info("THIS TRIGGERS STDOUT") // todo: make a proper init() & move this there
|
||||||
|
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
||||||
|
me.stdout.startOnscreen = false
|
||||||
|
}
|
||||||
|
setBottomBG()
|
||||||
|
}
|
||||||
|
|
||||||
|
// useful for debuggging
|
||||||
|
func hardDrawUnderMouse(tk *guiWidget, name string) {
|
||||||
|
if tk.v != nil {
|
||||||
|
tk.Hide()
|
||||||
|
}
|
||||||
|
w, h := me.baseGui.MousePosition()
|
||||||
|
r := new(rectType)
|
||||||
|
r.w0 = w
|
||||||
|
r.h0 = h
|
||||||
|
r.w1 = w + 8
|
||||||
|
r.h1 = h + 4
|
||||||
|
if err := tk.SetViewRect(r); err != nil {
|
||||||
|
log.Info("hardDrawUnderMouse() err", tk.cuiName, err)
|
||||||
|
tk.dumpWidget("hardDrawERR")
|
||||||
|
}
|
||||||
|
tk.v.Frame = false
|
||||||
|
tk.v.Clear()
|
||||||
|
tk.v.WriteString(tk.labelN + "\n" + name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func hardDrawAtgocuiSize(tk *guiWidget) {
|
||||||
|
if tk.v != nil {
|
||||||
|
tk.Hide()
|
||||||
|
}
|
||||||
|
if err := tk.SetView(); err != nil {
|
||||||
|
log.Info("hardDrawAtgocuiSize() err ok widget", tk.cuiName)
|
||||||
|
tk.dumpWidget("hardDrawERR")
|
||||||
|
}
|
||||||
|
tk.v.Frame = false
|
||||||
|
tk.v.Clear()
|
||||||
|
tk.v.WriteString(tk.labelN)
|
||||||
|
// log.Verbose("hardDrawAtgocuiSize() err ok widget", tk.cuiName, a, b, c, d, tk.v.Name())
|
||||||
|
}
|
||||||
|
|
||||||
|
func sigWinchIcon() {
|
||||||
|
w, _ := me.baseGui.Size()
|
||||||
|
me.notify.icon.tk.MoveToOffset(w-me.notify.icon.offsetW, me.notify.icon.offsetH)
|
||||||
|
me.notify.icon.tk.Hide()
|
||||||
|
me.notify.icon.tk.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func sigWinchBG() {
|
||||||
|
tk := me.BG.tk
|
||||||
|
w, h := me.baseGui.Size()
|
||||||
|
tk.gocuiSize.w0 = -1
|
||||||
|
tk.gocuiSize.h0 = -1
|
||||||
|
tk.gocuiSize.w1 = w + 1
|
||||||
|
tk.gocuiSize.h1 = h + 1
|
||||||
|
if err := tk.SetView(); err != nil {
|
||||||
|
tk.dumpWidget("sigWinchBGerr()")
|
||||||
|
log.Log(ERROR, "sigWinchBG()", err)
|
||||||
|
}
|
||||||
|
log.Log(INFO, "background resized to", tk.gocuiSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the "BG" widget and set it to the background on the very very bottom
|
||||||
|
func setBottomBG() {
|
||||||
|
if me.BG.tk == nil {
|
||||||
|
log.Info("background tk widget not initialized")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
tk := me.BG.tk
|
||||||
|
// log.Info("found BG. setting to bottom", tk.cuiName)
|
||||||
|
if tk.v == nil {
|
||||||
|
sigWinchBG()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if me.dark {
|
||||||
|
tk.v.BgColor = gocui.ColorBlack
|
||||||
|
} else {
|
||||||
|
tk.v.BgColor = gocui.ColorWhite
|
||||||
|
}
|
||||||
|
tk.v.Clear()
|
||||||
|
me.baseGui.SetViewOnBottom(tk.cuiName)
|
||||||
|
w, h := me.baseGui.Size()
|
||||||
|
tk.gocuiSize.w0 = -1
|
||||||
|
tk.gocuiSize.h0 = -1
|
||||||
|
tk.gocuiSize.w1 = w + 1
|
||||||
|
tk.gocuiSize.h1 = h + 1
|
||||||
|
tk.SetView()
|
||||||
|
}
|
14
place.go
14
place.go
|
@ -143,7 +143,7 @@ func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
||||||
// tk.dumpWidget(fmt.Sprintf("PlaceGroup(%d,%d)", maxW, newH))
|
// tk.dumpWidget(fmt.Sprintf("PlaceGroup(%d,%d)", maxW, newH))
|
||||||
return maxW, newH
|
return maxW, newH
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
if tk.isWindowDense() && tk.isInGrid() {
|
if tk.isDense() && tk.isInGrid() {
|
||||||
tk.frame = false
|
tk.frame = false
|
||||||
// tk.color = nil
|
// tk.color = nil
|
||||||
// tk.defaultColor = nil
|
// tk.defaultColor = nil
|
||||||
|
@ -167,6 +167,14 @@ func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) isDense() bool {
|
||||||
|
if tk.node.InTable() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return tk.isWindowDense()
|
||||||
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) isWindowDense() bool {
|
func (tk *guiWidget) isWindowDense() bool {
|
||||||
if tk.WidgetType() == widget.Window {
|
if tk.WidgetType() == widget.Window {
|
||||||
return tk.window.dense
|
return tk.window.dense
|
||||||
|
@ -193,8 +201,6 @@ func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
||||||
return 0, 0
|
return 0, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
dense := w.isWindowDense()
|
|
||||||
|
|
||||||
w.full.w0 = startW
|
w.full.w0 = startW
|
||||||
w.full.h0 = startH
|
w.full.h0 = startH
|
||||||
|
|
||||||
|
@ -209,7 +215,7 @@ func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
||||||
if w.heights[child.GridH()] < childH {
|
if w.heights[child.GridH()] < childH {
|
||||||
w.heights[child.GridH()] = childH
|
w.heights[child.GridH()] = childH
|
||||||
}
|
}
|
||||||
if dense {
|
if child.isDense() {
|
||||||
if w.heights[child.GridH()] > 0 {
|
if w.heights[child.GridH()] > 0 {
|
||||||
w.heights[child.GridH()] = 1
|
w.heights[child.GridH()] = 1
|
||||||
} else {
|
} else {
|
||||||
|
|
14
plugin.go
14
plugin.go
|
@ -16,7 +16,7 @@ func newAdd(n *tree.Node) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n.TK != nil {
|
if n.TK != nil {
|
||||||
log.Warn("Tree Add() sent a widget we aleady seem to have")
|
log.Log(INFO, "Tree Add() sent a widget we aleady seem to have")
|
||||||
// this is done to protect the plugin being 'refreshed' with the
|
// this is done to protect the plugin being 'refreshed' with the
|
||||||
// widget binary tree. TODO: find a way to keep them in sync
|
// widget binary tree. TODO: find a way to keep them in sync
|
||||||
return
|
return
|
||||||
|
@ -36,15 +36,18 @@ func newAdd(n *tree.Node) {
|
||||||
*/
|
*/
|
||||||
w := n.TK.(*guiWidget)
|
w := n.TK.(*guiWidget)
|
||||||
w.Show()
|
w.Show()
|
||||||
|
me.refresh = true // testing code to see if refresh can work
|
||||||
}
|
}
|
||||||
|
|
||||||
// for gocui as a GUI plugin, SetTitle & SetLabel are identical to SetText
|
// for gocui as a GUI plugin, SetTitle & SetLabel are identical to SetText
|
||||||
func setTitle(n *tree.Node, s string) {
|
func setTitle(n *tree.Node, s string) {
|
||||||
setText(n, s)
|
setText(n, s)
|
||||||
|
me.refresh = true // testing code to see if refresh can work
|
||||||
}
|
}
|
||||||
|
|
||||||
func setLabel(n *tree.Node, s string) {
|
func setLabel(n *tree.Node, s string) {
|
||||||
setText(n, s)
|
setText(n, s)
|
||||||
|
me.refresh = true // testing code to see if refresh can work
|
||||||
}
|
}
|
||||||
|
|
||||||
// setText() and addText() are simple. They take the event sent
|
// setText() and addText() are simple. They take the event sent
|
||||||
|
@ -61,6 +64,7 @@ func setText(n *tree.Node, s string) {
|
||||||
}
|
}
|
||||||
w := n.TK.(*guiWidget)
|
w := n.TK.(*guiWidget)
|
||||||
w.SetText(s)
|
w.SetText(s)
|
||||||
|
me.refresh = true // testing code to see if refresh can work
|
||||||
}
|
}
|
||||||
|
|
||||||
func addText(n *tree.Node, s string) {
|
func addText(n *tree.Node, s string) {
|
||||||
|
@ -74,6 +78,7 @@ func addText(n *tree.Node, s string) {
|
||||||
}
|
}
|
||||||
w := n.TK.(*guiWidget)
|
w := n.TK.(*guiWidget)
|
||||||
w.AddText(s)
|
w.AddText(s)
|
||||||
|
me.refresh = true // testing code to see if refresh can work
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *guiWidget) deleteGocuiViews() {
|
func (w *guiWidget) deleteGocuiViews() {
|
||||||
|
@ -111,7 +116,7 @@ func (w *guiWidget) AddText(text string) {
|
||||||
}
|
}
|
||||||
w.vals = append(w.vals, text)
|
w.vals = append(w.vals, text)
|
||||||
for i, s := range w.vals {
|
for i, s := range w.vals {
|
||||||
log.Log(NOW, "AddText()", w.String(), i, s)
|
log.Log(INFO, "AddText()", w.String(), i, s)
|
||||||
}
|
}
|
||||||
w.SetText(text)
|
w.SetText(text)
|
||||||
}
|
}
|
||||||
|
@ -157,10 +162,10 @@ func (tk *guiWidget) GetText() string {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hack. use "textbox widget" to "disable" user events
|
||||||
func hideDisable() {
|
func hideDisable() {
|
||||||
if me.textbox.tk == nil {
|
if me.textbox.tk == nil {
|
||||||
initTextbox()
|
initTextbox()
|
||||||
me.textbox.tk.prepTextbox()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
me.textbox.tk.Hide()
|
me.textbox.tk.Hide()
|
||||||
|
@ -172,6 +177,7 @@ func hideDisable() {
|
||||||
// me.baseGui.DeleteView(me.textbox.tk.v.Name())
|
// me.baseGui.DeleteView(me.textbox.tk.v.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// hack. use "textbox widget" to "disable" user events
|
||||||
func showDisable() {
|
func showDisable() {
|
||||||
if me.textbox.tk == nil {
|
if me.textbox.tk == nil {
|
||||||
initTextbox()
|
initTextbox()
|
||||||
|
@ -195,7 +201,7 @@ func showDisable() {
|
||||||
me.textbox.tk.v.Editable = true
|
me.textbox.tk.v.Editable = true
|
||||||
me.textbox.tk.v.Wrap = true
|
me.textbox.tk.v.Wrap = true
|
||||||
|
|
||||||
me.baseGui.SetView(me.textbox.tk.cuiName, r.w0, r.h0, r.w1, r.h1, 0)
|
me.textbox.tk.SetViewRect(r)
|
||||||
me.baseGui.SetCurrentView(me.textbox.tk.v.Name())
|
me.baseGui.SetCurrentView(me.textbox.tk.v.Name())
|
||||||
|
|
||||||
// bind the enter key to a function so we can close the textbox
|
// bind the enter key to a function so we can close the textbox
|
||||||
|
|
10
size.go
10
size.go
|
@ -67,7 +67,7 @@ func (tk *guiWidget) Size() (int, int) {
|
||||||
case widget.Checkbox:
|
case widget.Checkbox:
|
||||||
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
if tk.isWindowDense() {
|
if tk.isDense() {
|
||||||
return len(tk.String()) + 2, 0
|
return len(tk.String()) + 2, 0
|
||||||
}
|
}
|
||||||
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
||||||
|
@ -244,7 +244,7 @@ func (tk *guiWidget) setFullSize() bool {
|
||||||
if tk.WidgetType() == widget.Button {
|
if tk.WidgetType() == widget.Button {
|
||||||
tk.full.h1 = tk.full.h0 + 1
|
tk.full.h1 = tk.full.h0 + 1
|
||||||
}
|
}
|
||||||
if tk.isWindowDense() && tk.isInGrid() {
|
if tk.isDense() && tk.isInGrid() {
|
||||||
tk.full.h1 = tk.full.h0
|
tk.full.h1 = tk.full.h0
|
||||||
}
|
}
|
||||||
if changed {
|
if changed {
|
||||||
|
@ -309,7 +309,7 @@ func (tk *guiWidget) buttonFullSize() rectType {
|
||||||
tk.full.h1 = r.h1
|
tk.full.h1 = r.h1
|
||||||
|
|
||||||
// total hack. fix this somewhere eventually correctly
|
// total hack. fix this somewhere eventually correctly
|
||||||
if tk.isWindowDense() { // total hack. fix this somewhere eventually correctly
|
if tk.isDense() { // total hack. fix this somewhere eventually correctly
|
||||||
tk.full.h0 += 1 // total hack. fix this somewhere eventually correctly
|
tk.full.h0 += 1 // total hack. fix this somewhere eventually correctly
|
||||||
tk.full.h1 = tk.full.h0 // total hack. fix this somewhere eventually correctly
|
tk.full.h1 = tk.full.h0 // total hack. fix this somewhere eventually correctly
|
||||||
}
|
}
|
||||||
|
@ -355,7 +355,9 @@ func (tk *guiWidget) getFullSize() rectType {
|
||||||
case widget.Checkbox:
|
case widget.Checkbox:
|
||||||
return tk.buttonFullSize()
|
return tk.buttonFullSize()
|
||||||
case widget.Dropdown:
|
case widget.Dropdown:
|
||||||
return tk.buttonFullSize()
|
r := tk.buttonFullSize()
|
||||||
|
r.w1 += 7 // TODO: fix this to be real
|
||||||
|
return r
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -46,6 +45,7 @@ func coreStdout() {
|
||||||
me.stdout.tk = initWidget(n)
|
me.stdout.tk = initWidget(n)
|
||||||
|
|
||||||
tk := me.stdout.tk
|
tk := me.stdout.tk
|
||||||
|
tk.cuiName = "msg"
|
||||||
tk.gocuiSize.w0 = me.stdout.lastW
|
tk.gocuiSize.w0 = me.stdout.lastW
|
||||||
tk.gocuiSize.h0 = me.stdout.lastH
|
tk.gocuiSize.h0 = me.stdout.lastH
|
||||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + me.stdout.w
|
tk.gocuiSize.w1 = tk.gocuiSize.w0 + me.stdout.w
|
||||||
|
@ -64,32 +64,18 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
me.stdout.tk.cuiName = "msg"
|
||||||
|
me.stdout.tk.SetView()
|
||||||
|
|
||||||
v, err := g.View("msg")
|
v, err := g.View("msg")
|
||||||
if v == nil {
|
if v == nil {
|
||||||
log.Log(NOW, "makeoutputwindow() this is supposed to happen. v == nil", err)
|
// log.Log(NOW, "makeoutputwindow() this is supposed to happen. v == nil", err)
|
||||||
} else {
|
} else {
|
||||||
log.Log(NOW, "makeoutputwindow() msg != nil. WTF now? err =", err)
|
log.Log(NOW, "makeoutputwindow() msg != nil. WTF now? err =", err)
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
rect := me.stdout.tk.gocuiSize
|
v = me.stdout.tk.v
|
||||||
v, err = g.SetView("msg", rect.w0, rect.h0, rect.w1, rect.h1, 0)
|
|
||||||
|
|
||||||
if errors.Is(err, gocui.ErrUnknownView) {
|
|
||||||
log.Log(NOW, "makeoutputwindow() this is supposed to happen?", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Log(NOW, "makeoutputwindow() create output window failed", err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if v == nil {
|
|
||||||
log.Log(NOW, "makeoutputwindow() msg == nil. WTF now? err =", err)
|
|
||||||
return nil
|
|
||||||
} else {
|
|
||||||
me.stdout.tk.v = v
|
|
||||||
}
|
|
||||||
|
|
||||||
v.Clear()
|
v.Clear()
|
||||||
v.SelBgColor = gocui.ColorCyan
|
v.SelBgColor = gocui.ColorCyan
|
||||||
|
@ -98,16 +84,8 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||||
// g.SetViewOnBottom("msg")
|
// g.SetViewOnBottom("msg")
|
||||||
// setBottomBG()
|
// setBottomBG()
|
||||||
|
|
||||||
me.stdout.tk.v = v
|
|
||||||
me.stdout.tk.DrawAt(me.stdout.lastW, me.stdout.lastH)
|
me.stdout.tk.DrawAt(me.stdout.lastW, me.stdout.lastH)
|
||||||
relocateStdoutOffscreen()
|
relocateStdoutOffscreen()
|
||||||
/*
|
|
||||||
if me.stdout.outputOffscreen {
|
|
||||||
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
|
||||||
} else {
|
|
||||||
relocateStdoutOffscreen()
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,14 +93,32 @@ func relocateStdoutOffscreen() {
|
||||||
if me.stdout.tk == nil {
|
if me.stdout.tk == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !me.stdout.disable {
|
||||||
|
log.Info("Using gocui STDOUT")
|
||||||
log.CaptureMode(me.stdout.tk)
|
log.CaptureMode(me.stdout.tk)
|
||||||
// log.Log(ERROR, "setting log.CaptureMode(tk.v) in relocateStdoutOffscreen()")
|
}
|
||||||
newW := 10
|
newW := 10
|
||||||
newH := 0 - me.stdout.h - 4
|
newH := 0 - me.stdout.h - 4
|
||||||
me.stdout.tk.relocateStdout(newW, newH)
|
me.stdout.tk.relocateStdout(newW, newH)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) relocateStdout(w int, h int) {
|
func (tk *guiWidget) relocateStdout(w int, h int) {
|
||||||
|
if me.stdout.w < 8 {
|
||||||
|
me.stdout.w = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
if me.stdout.h < 4 {
|
||||||
|
me.stdout.h = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
if w+me.stdout.w < 2 {
|
||||||
|
w = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
if h+me.stdout.h < 2 {
|
||||||
|
h = 2
|
||||||
|
}
|
||||||
|
|
||||||
w0 := w
|
w0 := w
|
||||||
h0 := h
|
h0 := h
|
||||||
w1 := w + me.stdout.w
|
w1 := w + me.stdout.w
|
||||||
|
@ -138,8 +134,7 @@ func (tk *guiWidget) relocateStdout(w int, h int) {
|
||||||
tk.full.h0 = h0
|
tk.full.h0 = h0
|
||||||
tk.full.h1 = h1
|
tk.full.h1 = h1
|
||||||
|
|
||||||
me.baseGui.SetView("msg", w0, h0, w1, h1, 0)
|
tk.SetView()
|
||||||
// me.baseGui.SetViewOnBottom("msg")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// from the gocui devs:
|
// from the gocui devs:
|
||||||
|
@ -161,13 +156,20 @@ func (w stdout) Write(p []byte) (n int, err error) {
|
||||||
|
|
||||||
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
||||||
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
||||||
|
if me.outf != nil {
|
||||||
|
fmt.Fprint(me.outf, string(p))
|
||||||
|
}
|
||||||
|
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *guiWidget) Write(p []byte) (n int, err error) {
|
func (w *guiWidget) Write(p []byte) (n int, err error) {
|
||||||
if w == nil {
|
|
||||||
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
||||||
|
if me.outf != nil {
|
||||||
|
fmt.Fprint(me.outf, string(p))
|
||||||
|
}
|
||||||
|
|
||||||
|
if w == nil {
|
||||||
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
}
|
}
|
||||||
|
@ -175,7 +177,6 @@ func (w *guiWidget) Write(p []byte) (n int, err error) {
|
||||||
me.writeMutex.Lock()
|
me.writeMutex.Lock()
|
||||||
defer me.writeMutex.Unlock()
|
defer me.writeMutex.Unlock()
|
||||||
|
|
||||||
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
|
||||||
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
||||||
|
|
||||||
tk := me.stdout.tk
|
tk := me.stdout.tk
|
||||||
|
@ -186,7 +187,6 @@ func (w *guiWidget) Write(p []byte) (n int, err error) {
|
||||||
// redo this old code
|
// redo this old code
|
||||||
v, _ := me.baseGui.View("msg")
|
v, _ := me.baseGui.View("msg")
|
||||||
if v != nil {
|
if v != nil {
|
||||||
// fmt.Fprintln(outf, "found msg")
|
|
||||||
tk.v = v
|
tk.v = v
|
||||||
}
|
}
|
||||||
return len(p), nil
|
return len(p), nil
|
||||||
|
@ -211,7 +211,9 @@ func (tk *guiWidget) refreshStdout() {
|
||||||
// chop off the last lines in the buffer
|
// chop off the last lines in the buffer
|
||||||
chop := len(me.stdout.outputS) - (me.stdout.pager + me.stdout.h)
|
chop := len(me.stdout.outputS) - (me.stdout.pager + me.stdout.h)
|
||||||
cur = append(cur, me.stdout.outputS[chop:chop+me.stdout.h]...)
|
cur = append(cur, me.stdout.outputS[chop:chop+me.stdout.h]...)
|
||||||
|
if me.stdout.reverse {
|
||||||
slices.Reverse(cur)
|
slices.Reverse(cur)
|
||||||
|
}
|
||||||
tk.v.Clear()
|
tk.v.Clear()
|
||||||
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
||||||
}
|
}
|
||||||
|
|
39
structs.go
39
structs.go
|
@ -25,7 +25,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var initOnce sync.Once // run initPlugin() only once
|
var initOnce sync.Once // run initPlugin() only once
|
||||||
var outf *os.File // hacks for capturing stdout
|
|
||||||
|
|
||||||
// It's probably a terrible idea to call this 'me'
|
// It's probably a terrible idea to call this 'me'
|
||||||
// 2025 note: doesn't seem terrible to call this 'me' anymore. notsure.
|
// 2025 note: doesn't seem terrible to call this 'me' anymore. notsure.
|
||||||
|
@ -41,9 +40,12 @@ type config struct {
|
||||||
currentWindow *guiWidget // this is the current tab or window to show
|
currentWindow *guiWidget // this is the current tab or window to show
|
||||||
ok bool // if the user doesn't hit a key or move the mouse, gocui doesn't really start
|
ok bool // if the user doesn't hit a key or move the mouse, gocui doesn't really start
|
||||||
firstWindowOk bool // allows the init to wait for the first window from the application
|
firstWindowOk bool // allows the init to wait for the first window from the application
|
||||||
|
refresh bool // redraw everything?
|
||||||
ctrlDown *tree.Node // shown if you click the mouse when the ctrl key is pressed
|
ctrlDown *tree.Node // shown if you click the mouse when the ctrl key is pressed
|
||||||
helpLabel *gocui.View // ?
|
helpLabel *gocui.View // ?
|
||||||
showHelp bool // toggle boolean for the help menu (deprecate?)
|
showHelp bool // toggle boolean for the help menu (deprecate?)
|
||||||
|
FirstWindowW int `default:"2"` // how far over to start window #1
|
||||||
|
FirstWindowH int `default:"0"` // how far down to start window #1
|
||||||
FramePadW int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
|
FramePadW int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
|
||||||
FramePadH int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
|
FramePadH int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
|
||||||
PadW int `default:"1" dense:"0"` // pad spacing
|
PadW int `default:"1" dense:"0"` // pad spacing
|
||||||
|
@ -75,13 +77,17 @@ type config struct {
|
||||||
stdout stdout // information for the STDOUT window
|
stdout stdout // information for the STDOUT window
|
||||||
dropdown dropdown // the dropdown menu
|
dropdown dropdown // the dropdown menu
|
||||||
textbox dropdown // the textbox popup window
|
textbox dropdown // the textbox popup window
|
||||||
clock dropdown // the textbox popup window
|
BG dropdown // the background widget
|
||||||
|
notify libnotify // emulates the desktop libnotify menu
|
||||||
allwin []*guiWidget // for tracking which window is next
|
allwin []*guiWidget // for tracking which window is next
|
||||||
dark bool // use a 'dark' color palette
|
dark bool // use a 'dark' color palette
|
||||||
mouse mouse // mouse settings
|
mouse mouse // mouse settings
|
||||||
showDebug bool // todo: move this into config struct
|
showDebug bool // todo: move this into config struct
|
||||||
debug bool // todo: move this into config struct
|
debug bool // todo: move this into config struct
|
||||||
starttime time.Time // checks how long it takes on startup
|
starttime time.Time // checks how long it takes on startup
|
||||||
|
winchW int // used to detect SIGWINCH
|
||||||
|
winchH int // used to detect SIGWINCH
|
||||||
|
outf *os.File // hacks for capturing stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
// stuff controlling how the mouse works
|
// stuff controlling how the mouse works
|
||||||
|
@ -107,13 +113,14 @@ type stdout struct {
|
||||||
outputOnTop bool // is the STDOUT window on top?
|
outputOnTop bool // is the STDOUT window on top?
|
||||||
outputOffscreen bool // is the STDOUT window offscreen?
|
outputOffscreen bool // is the STDOUT window offscreen?
|
||||||
startOnscreen bool // start the output window onscreen?
|
startOnscreen bool // start the output window onscreen?
|
||||||
|
disable bool // disable the stdout window. do not change os.Stdout & os.Stderr
|
||||||
lastW int // the last 'w' location (used to move from offscreen to onscreen)
|
lastW int // the last 'w' location (used to move from offscreen to onscreen)
|
||||||
lastH int // the last 'h' location (used to move from offscreen to onscreen)
|
lastH int // the last 'h' location (used to move from offscreen to onscreen)
|
||||||
// mouseOffsetW int // the current 'w' offset
|
|
||||||
// mouseOffsetH int // the current 'h' offset
|
|
||||||
init bool // moves the window offscreen on startup
|
init bool // moves the window offscreen on startup
|
||||||
outputS []string // the buffer of all the output
|
outputS []string // the buffer of all the output
|
||||||
pager int // allows the user to page through the buffer
|
pager int // allows the user to page through the buffer
|
||||||
|
changed bool // indicates the user has changed stdout. gocui should remember the state here
|
||||||
|
reverse bool // flip the STDOUT upside down so new STDOUT lines are at the top
|
||||||
}
|
}
|
||||||
|
|
||||||
// settings for the dropdown window
|
// settings for the dropdown window
|
||||||
|
@ -125,10 +132,29 @@ type dropdown struct {
|
||||||
h int // the height
|
h int // the height
|
||||||
active bool // is the dropdown menu currently in use?
|
active bool // is the dropdown menu currently in use?
|
||||||
init bool // moves the window offscreen on startup
|
init bool // moves the window offscreen on startup
|
||||||
Id int `default:"-78"` // the widget id to use
|
// Id int `default:"-78"` // the widget id to use
|
||||||
wId int `default:"-78"` // the widget id to use
|
wId int `default:"-78"` // the widget id to use
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// settings for the dropdown window
|
||||||
|
type internalTK struct {
|
||||||
|
once sync.Once // for init
|
||||||
|
tk *guiWidget // where to show STDOUT
|
||||||
|
callerTK *guiWidget // which widget called the dropdown menu
|
||||||
|
wId int // the widget id to use
|
||||||
|
active bool // is the internal widget currently in use?
|
||||||
|
offsetW int // width offset
|
||||||
|
offsetH int // height offset
|
||||||
|
}
|
||||||
|
|
||||||
|
// the desktop libnotify menu
|
||||||
|
type libnotify struct {
|
||||||
|
clock internalTK // widget for the clock
|
||||||
|
icon internalTK // libnotify menu icon
|
||||||
|
window internalTK // the libnotify menu
|
||||||
|
help internalTK // the help menu
|
||||||
|
}
|
||||||
|
|
||||||
// this is the gocui way
|
// this is the gocui way
|
||||||
// corner starts at in the upper left corner
|
// corner starts at in the upper left corner
|
||||||
type rectType struct {
|
type rectType struct {
|
||||||
|
@ -164,7 +190,6 @@ type window struct {
|
||||||
currentTab bool // the visible tab
|
currentTab bool // the visible tab
|
||||||
selectedTab *tree.Node // for a window, this is currently selected tab
|
selectedTab *tree.Node // for a window, this is currently selected tab
|
||||||
active bool // means this window is the active one
|
active bool // means this window is the active one
|
||||||
isBG bool // means this is the background widget. There is only one of these
|
|
||||||
order int // what level the window is on
|
order int // what level the window is on
|
||||||
// resize bool // only set the title once
|
// resize bool // only set the title once
|
||||||
collapsed bool // only show the window title bar
|
collapsed bool // only show the window title bar
|
||||||
|
@ -216,7 +241,7 @@ type guiWidget struct {
|
||||||
color *colorT // what color to use
|
color *colorT // what color to use
|
||||||
colorLast colorT // the last color the widget had
|
colorLast colorT // the last color the widget had
|
||||||
defaultColor *colorT // the default colors // TODO: make a function for this instead
|
defaultColor *colorT // the default colors // TODO: make a function for this instead
|
||||||
isBG bool // means this is the background widget. There is only one of these
|
isTable bool // is this a table?
|
||||||
}
|
}
|
||||||
|
|
||||||
// THIS IS GO COMPILER MAGIC
|
// THIS IS GO COMPILER MAGIC
|
||||||
|
|
43
table.go
43
table.go
|
@ -13,18 +13,6 @@ import (
|
||||||
"go.wit.com/widget"
|
"go.wit.com/widget"
|
||||||
)
|
)
|
||||||
|
|
||||||
func initWindowPB(pb *guipb.Widget) *guiWidget {
|
|
||||||
var w *guiWidget
|
|
||||||
w = new(guiWidget)
|
|
||||||
|
|
||||||
w.pb = pb
|
|
||||||
w.parent = me.treeRoot.TK.(*guiWidget)
|
|
||||||
w.wtype = widget.Window
|
|
||||||
w.cuiName = fmt.Sprintf("%d %s", pb.Id, "TK")
|
|
||||||
w.labelN = pb.Name
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
func initGridPB(pb *guipb.Widget) *guiWidget {
|
func initGridPB(pb *guipb.Widget) *guiWidget {
|
||||||
var w *guiWidget
|
var w *guiWidget
|
||||||
w = new(guiWidget)
|
w = new(guiWidget)
|
||||||
|
@ -33,6 +21,7 @@ func initGridPB(pb *guipb.Widget) *guiWidget {
|
||||||
w.wtype = widget.Grid
|
w.wtype = widget.Grid
|
||||||
w.cuiName = fmt.Sprintf("%d %s", pb.Id, "TK")
|
w.cuiName = fmt.Sprintf("%d %s", pb.Id, "TK")
|
||||||
w.labelN = pb.Name
|
w.labelN = pb.Name
|
||||||
|
w.isTable = true
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,19 +31,21 @@ func showTable(t *guipb.Table) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("gocui: table.Title", t.Title)
|
log.Info("gocui: table.Title", t.Title)
|
||||||
if t.Window == nil {
|
// log.Info("gocui: need to add window here id =", t.Window.Id, t.Window.Name)
|
||||||
log.Info("gocui: missing window widget. tree plugin error")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
log.Info("gocui: need to add window here id =", t.Window.Id, t.Window.Name)
|
|
||||||
if t.Grid == nil {
|
if t.Grid == nil {
|
||||||
log.Info("gocui: missing grid widget. tree plugin error")
|
log.Info("gocui: missing grid widget. tree plugin error")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
root := me.treeRoot.TK.(*guiWidget)
|
||||||
|
parent := root.findWidgetById(int(t.Parent.Id))
|
||||||
|
if parent == nil {
|
||||||
|
log.Info("gocui: show table error. parent.Id not found", t.Parent.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
log.Info("gocui: need to add grid here id =", t.Grid.Id)
|
log.Info("gocui: need to add grid here id =", t.Grid.Id)
|
||||||
win := initWindowPB(t.Window)
|
grid := initGridPB(t.Grid)
|
||||||
grid := initWindowPB(t.Window)
|
grid.parent = parent
|
||||||
grid.parent = win
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func enableWidget(n *tree.Node) {
|
func enableWidget(n *tree.Node) {
|
||||||
|
@ -83,12 +74,20 @@ func hideWidget(n *tree.Node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) deleteWidget() {
|
func (tk *guiWidget) deleteWidget() {
|
||||||
log.Info("gocui deleteWidget() looking for child to delete:", tk.cuiName)
|
log.Log(INFO, "gocui deleteWidget() looking for child to delete:", tk.cuiName)
|
||||||
p := tk.parent
|
p := tk.parent
|
||||||
for i, child := range p.children {
|
for i, child := range p.children {
|
||||||
if tk == child {
|
if tk == child {
|
||||||
log.Info("deleteWidget() found parent with child to delete:", i, child.cuiName)
|
log.Log(INFO, "deleteWidget() found parent with child to delete:", i, child.cuiName, child.WidgetId())
|
||||||
p.children = slices.Delete(p.children, i, i+1)
|
p.children = slices.Delete(p.children, i, i+1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
tk.deleteTree()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tk *guiWidget) deleteTree() {
|
||||||
|
for _, child := range tk.children {
|
||||||
|
child.deleteTree()
|
||||||
|
}
|
||||||
|
tk.Hide()
|
||||||
}
|
}
|
||||||
|
|
32
textbox.go
32
textbox.go
|
@ -7,6 +7,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
"github.com/awesome-gocui/gocui"
|
||||||
log "go.wit.com/log"
|
log "go.wit.com/log"
|
||||||
|
@ -40,7 +41,7 @@ func initTextbox() {
|
||||||
func (callertk *guiWidget) prepTextbox() {
|
func (callertk *guiWidget) prepTextbox() {
|
||||||
initTextbox()
|
initTextbox()
|
||||||
if me.textbox.tk == nil {
|
if me.textbox.tk == nil {
|
||||||
log.Log(GOCUI, "prepTextbox() Is Broken")
|
log.Log(WARN, "prepTextbox() Is Broken")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,21 +52,35 @@ func (callertk *guiWidget) prepTextbox() {
|
||||||
r.w1 = r.w0 + 24
|
r.w1 = r.w0 + 24
|
||||||
r.h1 = r.h0 + 2
|
r.h1 = r.h0 + 2
|
||||||
me.textbox.tk.forceSizes(r)
|
me.textbox.tk.forceSizes(r)
|
||||||
// me.textbox.tk.dumpWidget("after sizes")
|
me.textbox.tk.dumpWidget("after sizes")
|
||||||
|
|
||||||
me.textbox.callerTK = callertk
|
me.textbox.callerTK = callertk
|
||||||
|
|
||||||
// showTextbox(callertk.String())
|
if me.textbox.tk.v != nil {
|
||||||
|
log.Log(WARN, "WARNING textbox DeleteView()")
|
||||||
|
log.Log(WARN, "WARNING textbox DeleteView()")
|
||||||
|
log.Log(WARN, "WARNING textbox DeleteView()")
|
||||||
|
me.baseGui.DeleteView(me.textbox.tk.cuiName)
|
||||||
|
time.Sleep(time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := me.textbox.tk.SetViewRect(r); err != nil {
|
||||||
|
log.Log(WARN, "textbox SetViewRect() failed", err, "view name =", me.textbox.tk.cuiName)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// me.textbox.tk.Show() // actually makes the gocui view. TODO: redo this?
|
||||||
|
showTextbox(callertk.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func showTextbox(callers string) {
|
func showTextbox(callers string) {
|
||||||
// tk := me.textbox.tk
|
// tk := me.textbox.tk
|
||||||
// me.textbox.tk.dumpWidget("after sizes")
|
// me.textbox.tk.dumpWidget("after sizes")
|
||||||
|
log.Log(WARN, "showTextbox() caller string =", callers)
|
||||||
|
|
||||||
// me.textbox.tk.Show() // actually makes the gocui view. TODO: redo this
|
// me.textbox.tk.Show() // actually makes the gocui view. TODO: redo this
|
||||||
|
|
||||||
if me.textbox.tk.v == nil {
|
if me.textbox.tk.v == nil {
|
||||||
log.Info("wtf went wrong")
|
log.Log(WARN, "textbox.tk.v == nil showTextbox() is broken")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,8 +93,8 @@ func showTextbox(callers string) {
|
||||||
me.textbox.tk.v.Editable = true
|
me.textbox.tk.v.Editable = true
|
||||||
me.textbox.tk.v.Wrap = true
|
me.textbox.tk.v.Wrap = true
|
||||||
|
|
||||||
r := me.textbox.tk.gocuiSize
|
me.textbox.tk.SetView()
|
||||||
me.baseGui.SetView(me.textbox.tk.cuiName, r.w0, r.h0, r.w1, r.h1, 0)
|
|
||||||
me.baseGui.SetCurrentView(me.textbox.tk.v.Name())
|
me.baseGui.SetCurrentView(me.textbox.tk.v.Name())
|
||||||
|
|
||||||
// bind the enter key to a function so we can close the textbox
|
// bind the enter key to a function so we can close the textbox
|
||||||
|
@ -87,7 +102,8 @@ func showTextbox(callers string) {
|
||||||
|
|
||||||
me.textbox.active = true
|
me.textbox.active = true
|
||||||
|
|
||||||
// me.textbox.dumpWidget("showTextbox()")
|
me.baseGui.SetViewOnTop(me.textbox.tk.v.Name())
|
||||||
|
me.textbox.tk.dumpWidget("showTextbox()")
|
||||||
}
|
}
|
||||||
|
|
||||||
func theCloseTheTextbox(g *gocui.Gui, v *gocui.View) error {
|
func theCloseTheTextbox(g *gocui.Gui, v *gocui.View) error {
|
||||||
|
@ -109,7 +125,7 @@ func textboxClosed() {
|
||||||
me.textbox.tk.Hide()
|
me.textbox.tk.Hide()
|
||||||
// log.Info("textbox closed with text:", newtext, me.textbox.callerTK.cuiName)
|
// log.Info("textbox closed with text:", newtext, me.textbox.callerTK.cuiName)
|
||||||
|
|
||||||
if me.clock.tk.v != nil {
|
if me.notify.clock.tk.v != nil {
|
||||||
me.baseGui.SetCurrentView("help")
|
me.baseGui.SetCurrentView("help")
|
||||||
} else {
|
} else {
|
||||||
me.baseGui.SetCurrentView("msg")
|
me.baseGui.SetCurrentView("msg")
|
||||||
|
|
15
treeInit.go
15
treeInit.go
|
@ -32,6 +32,9 @@ package main
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
log "go.wit.com/log"
|
||||||
"go.wit.com/toolkits/tree"
|
"go.wit.com/toolkits/tree"
|
||||||
"go.wit.com/widget"
|
"go.wit.com/widget"
|
||||||
)
|
)
|
||||||
|
@ -49,9 +52,20 @@ func Callback(guiCallback chan widget.Action) {
|
||||||
|
|
||||||
func PluginChannel() chan widget.Action {
|
func PluginChannel() chan widget.Action {
|
||||||
initOnce.Do(initPlugin)
|
initOnce.Do(initPlugin)
|
||||||
|
for {
|
||||||
|
if me.myTree != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
log.Info("me.myTree == nil")
|
||||||
|
time.Sleep(300 * time.Millisecond)
|
||||||
|
}
|
||||||
return me.myTree.PluginChannel()
|
return me.myTree.PluginChannel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FrozenChannel() chan widget.Action {
|
||||||
|
return me.myTree.FrozenChannel()
|
||||||
|
}
|
||||||
|
|
||||||
func initTree() *tree.TreeInfo {
|
func initTree() *tree.TreeInfo {
|
||||||
t := tree.New()
|
t := tree.New()
|
||||||
t.PluginName = PLUGIN
|
t.PluginName = PLUGIN
|
||||||
|
@ -68,6 +82,7 @@ func initTree() *tree.TreeInfo {
|
||||||
t.Hide = hideWidget
|
t.Hide = hideWidget
|
||||||
|
|
||||||
t.SetChecked = setChecked
|
t.SetChecked = setChecked
|
||||||
|
t.ToolkitInit = toolkitInit
|
||||||
t.ToolkitClose = toolkitClose
|
t.ToolkitClose = toolkitClose
|
||||||
t.ShowTable = showTable
|
t.ShowTable = showTable
|
||||||
|
|
||||||
|
|
|
@ -41,29 +41,24 @@ func addWidget(n *tree.Node) {
|
||||||
switch n.WidgetType {
|
switch n.WidgetType {
|
||||||
case widget.Root:
|
case widget.Root:
|
||||||
log.Log(INFO, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.String())
|
log.Log(INFO, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.String())
|
||||||
// tk.color = &colorRoot
|
|
||||||
setFake(n)
|
setFake(n)
|
||||||
return
|
return
|
||||||
case widget.Flag:
|
case widget.Flag:
|
||||||
// tk.color = &colorFlag
|
|
||||||
setFake(n)
|
setFake(n)
|
||||||
return
|
return
|
||||||
case widget.Window:
|
case widget.Window:
|
||||||
tk.frame = false
|
tk.frame = false
|
||||||
tk.labelN = tk.GetText() + " X"
|
tk.labelN = tk.GetText() + " X"
|
||||||
// tk.setColor(&colorWindow)
|
|
||||||
me.newWindowTrigger <- tk
|
me.newWindowTrigger <- tk
|
||||||
redoWindows(0, 0)
|
redoWindows(0, 0)
|
||||||
hideHelp()
|
|
||||||
showHelp()
|
|
||||||
return
|
return
|
||||||
case widget.Stdout:
|
case widget.Stdout:
|
||||||
tk.labelN = "moreSTDOUT"
|
tk.labelN = "moreSTDOUT"
|
||||||
n.State.ProgName = "moreSTDOUT"
|
n.State.ProgName = "moreSTDOUT"
|
||||||
n.State.Label = "moreSTDOUT"
|
n.State.Label = "moreSTDOUT"
|
||||||
|
tk.isFake = true
|
||||||
return
|
return
|
||||||
case widget.Tab:
|
case widget.Tab:
|
||||||
// tk.color = &colorTab
|
|
||||||
return
|
return
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
tk.setColorButton()
|
tk.setColorButton()
|
||||||
|
@ -82,20 +77,16 @@ func addWidget(n *tree.Node) {
|
||||||
case widget.Textbox:
|
case widget.Textbox:
|
||||||
n.State.Label = ""
|
n.State.Label = ""
|
||||||
tk.labelN = " "
|
tk.labelN = " "
|
||||||
// tk.color = &colorDropdown
|
|
||||||
tk.setColorInput()
|
tk.setColorInput()
|
||||||
return
|
return
|
||||||
case widget.Combobox:
|
case widget.Combobox:
|
||||||
// tk.color = &colorCombobox
|
|
||||||
tk.setColorInput()
|
tk.setColorInput()
|
||||||
return
|
return
|
||||||
case widget.Box:
|
case widget.Box:
|
||||||
// tk.color = &colorBox
|
|
||||||
tk.isFake = true
|
tk.isFake = true
|
||||||
setFake(n)
|
setFake(n)
|
||||||
return
|
return
|
||||||
case widget.Grid:
|
case widget.Grid:
|
||||||
// tk.color = &colorGrid
|
|
||||||
tk.isFake = true
|
tk.isFake = true
|
||||||
setFake(n)
|
setFake(n)
|
||||||
return
|
return
|
||||||
|
@ -104,7 +95,17 @@ func addWidget(n *tree.Node) {
|
||||||
tk.frame = false
|
tk.frame = false
|
||||||
return
|
return
|
||||||
case widget.Label:
|
case widget.Label:
|
||||||
|
if tk.node.InTable() {
|
||||||
|
if tk.node.State.AtH == 0 {
|
||||||
|
// this is the table header
|
||||||
|
tk.setColorLabelTable()
|
||||||
|
} else {
|
||||||
|
// todo: highlight the whole table row
|
||||||
tk.setColorLabel()
|
tk.setColorLabel()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tk.setColorLabel()
|
||||||
|
}
|
||||||
tk.frame = false
|
tk.frame = false
|
||||||
return
|
return
|
||||||
default:
|
default:
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/awesome-gocui/gocui"
|
|
||||||
"go.wit.com/log"
|
"go.wit.com/log"
|
||||||
"go.wit.com/toolkits/tree"
|
"go.wit.com/toolkits/tree"
|
||||||
"go.wit.com/widget"
|
"go.wit.com/widget"
|
||||||
|
@ -43,7 +42,11 @@ func initWidget(n *tree.Node) *guiWidget {
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
if p.TK == nil {
|
if p.TK == nil {
|
||||||
|
if n.WidgetId == 0 {
|
||||||
|
// this is a normal init condition
|
||||||
|
} else {
|
||||||
log.Log(ERROR, "parent.TK == nil", w.String(), n.WidgetId, w.WidgetType())
|
log.Log(ERROR, "parent.TK == nil", w.String(), n.WidgetId, w.WidgetType())
|
||||||
|
}
|
||||||
return w
|
return w
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,34 +124,3 @@ func (tk *guiWidget) SetVisible(b bool) {
|
||||||
tk.Hide()
|
tk.Hide()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) findWidgetByName(name string) *guiWidget {
|
|
||||||
if tk.cuiName == name {
|
|
||||||
return tk
|
|
||||||
}
|
|
||||||
for _, child := range tk.children {
|
|
||||||
found := child.findWidgetByName(name)
|
|
||||||
if found != nil {
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tk *guiWidget) findWidgetByView(v *gocui.View) *guiWidget {
|
|
||||||
if tk.v == v {
|
|
||||||
return tk
|
|
||||||
}
|
|
||||||
if tk.cuiName == v.Name() {
|
|
||||||
log.Log(NOW, "findWidget() error. names are mismatched or out of sync", tk.cuiName)
|
|
||||||
log.Log(NOW, "findWidget() or maybe the view has been deleted")
|
|
||||||
// return tk
|
|
||||||
}
|
|
||||||
for _, child := range tk.children {
|
|
||||||
found := child.findWidgetByView(v)
|
|
||||||
if found != nil {
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -162,12 +162,20 @@ func (tk *guiWidget) drawView() {
|
||||||
log.Log(ERROR, "drawView() internal plugin error err = nil")
|
log.Log(ERROR, "drawView() internal plugin error err = nil")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||||
tk.dumpWidget("drawView() err")
|
tk.dumpWidget("drawView() err")
|
||||||
log.Log(ERROR, "drawView() internal plugin error error.IS()", err)
|
log.Log(ERROR, "drawView() internal plugin error error.IS()", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tk.v == nil {
|
||||||
|
log.Info("MUTEX FAIL. tk.v == nil here in drawView()")
|
||||||
|
log.Info("MUTEX FAIL. tk.v == nil here in drawView()")
|
||||||
|
log.Info("MUTEX FAIL. tk.v == nil here in drawView()")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// this actually sends the text to display to gocui
|
// this actually sends the text to display to gocui
|
||||||
tk.v.Wrap = true
|
tk.v.Wrap = true
|
||||||
tk.v.Frame = tk.frame
|
tk.v.Frame = tk.frame
|
||||||
|
@ -185,7 +193,7 @@ func (tk *guiWidget) drawView() {
|
||||||
switch tk.WidgetType() {
|
switch tk.WidgetType() {
|
||||||
case widget.Button:
|
case widget.Button:
|
||||||
if tk.IsEnabled() {
|
if tk.IsEnabled() {
|
||||||
if tk.isWindowDense() && tk.isInGrid() {
|
if tk.isDense() && tk.isInGrid() {
|
||||||
tk.setColorButtonDense()
|
tk.setColorButtonDense()
|
||||||
} else {
|
} else {
|
||||||
tk.setColorButton()
|
tk.setColorButton()
|
||||||
|
@ -195,6 +203,14 @@ func (tk *guiWidget) drawView() {
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if tk.v == nil {
|
||||||
|
log.Info("MUTEX FAIL 2. tk.v was deleted somehow tk.v == nil here in drawView()")
|
||||||
|
log.Info("MUTEX FAIL 2. tk.v == nil here in drawView()")
|
||||||
|
log.Info("MUTEX FAIL 2. tk.v == nil here in drawView()")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// if you don't do this here, it will be black & white only
|
// if you don't do this here, it will be black & white only
|
||||||
if tk.color != nil {
|
if tk.color != nil {
|
||||||
tk.v.FrameColor = tk.color.frame
|
tk.v.FrameColor = tk.color.frame
|
||||||
|
@ -203,20 +219,16 @@ func (tk *guiWidget) drawView() {
|
||||||
tk.v.SelFgColor = tk.color.selFg
|
tk.v.SelFgColor = tk.color.selFg
|
||||||
tk.v.SelBgColor = tk.color.selBg
|
tk.v.SelBgColor = tk.color.selBg
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Log(INFO, "drawView() END")
|
log.Log(INFO, "drawView() END")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// redraw the widget tree starting at this location
|
||||||
func (w *guiWidget) DrawAt(offsetW, offsetH int) {
|
func (w *guiWidget) DrawAt(offsetW, offsetH int) {
|
||||||
// w.setColor(&colorActiveW)
|
|
||||||
w.placeWidgets(offsetW, offsetH) // compute the sizes & places for each widget
|
w.placeWidgets(offsetW, offsetH) // compute the sizes & places for each widget
|
||||||
// w.dumpWidget(fmt.Sprintf("DrawAt(%d,%d)", offsetW, offsetH))
|
// w.dumpWidget(fmt.Sprintf("DrawAt(%d,%d)", offsetW, offsetH))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *guiWidget) simpleDrawAt(offsetW, offsetH int) {
|
|
||||||
// w.setColor(&colorActiveW)
|
|
||||||
w.dumpWidget("simpleDrawAt()")
|
|
||||||
}
|
|
||||||
|
|
||||||
// display the widgets in the binary tree
|
// display the widgets in the binary tree
|
||||||
func (w *guiWidget) drawTree(draw bool) {
|
func (w *guiWidget) drawTree(draw bool) {
|
||||||
if w == nil {
|
if w == nil {
|
32
window.go
32
window.go
|
@ -71,6 +71,10 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
||||||
|
|
||||||
tk.setFullSize()
|
tk.setFullSize()
|
||||||
tk.Show()
|
tk.Show()
|
||||||
|
if tk.v == nil {
|
||||||
|
log.Info("redrawWindow on tk.v == nil")
|
||||||
|
standardExit()
|
||||||
|
}
|
||||||
tk.v.Clear()
|
tk.v.Clear()
|
||||||
fmt.Fprint(tk.v, "ZZZ"+tk.GetText())
|
fmt.Fprint(tk.v, "ZZZ"+tk.GetText())
|
||||||
tk.showWidgets()
|
tk.showWidgets()
|
||||||
|
@ -96,6 +100,7 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
||||||
|
|
||||||
// set the window frame below the window widget, but this resizes the window widget it seems
|
// set the window frame below the window widget, but this resizes the window widget it seems
|
||||||
me.baseGui.SetViewBeneath(tk.windowFrame.cuiName, tk.cuiName, 1)
|
me.baseGui.SetViewBeneath(tk.windowFrame.cuiName, tk.cuiName, 1)
|
||||||
|
|
||||||
// so now we have to resize the window frame, but this moves it to the top?
|
// so now we have to resize the window frame, but this moves it to the top?
|
||||||
me.baseGui.SetView(tk.windowFrame.cuiName, tk.windowFrame.full.w0, tk.windowFrame.full.h0, tk.windowFrame.full.w1, tk.windowFrame.full.h1, 0)
|
me.baseGui.SetView(tk.windowFrame.cuiName, tk.windowFrame.full.w0, tk.windowFrame.full.h0, tk.windowFrame.full.w1, tk.windowFrame.full.h1, 0)
|
||||||
|
|
||||||
|
@ -205,13 +210,6 @@ func (tk *guiWidget) makeWindowActive() {
|
||||||
|
|
||||||
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||||
|
|
||||||
/*
|
|
||||||
// print out the window list
|
|
||||||
for _, tk := range me.allwin {
|
|
||||||
log.Info("makeWindowActive() Window", tk.labelN, tk.window.active, tk.window.order)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tk *guiWidget) makeTK(ddItems []string) {
|
func (tk *guiWidget) makeTK(ddItems []string) {
|
||||||
|
@ -222,25 +220,7 @@ func (tk *guiWidget) makeTK(ddItems []string) {
|
||||||
tk.gocuiSize.w1 = 120
|
tk.gocuiSize.w1 = 120
|
||||||
tk.gocuiSize.h0 = 15
|
tk.gocuiSize.h0 = 15
|
||||||
tk.gocuiSize.h1 = 18
|
tk.gocuiSize.h1 = 18
|
||||||
/*
|
|
||||||
var err error
|
|
||||||
tk.v, err = me.baseGui.SetView(tk.cuiName,
|
|
||||||
tk.gocuiSize.w0,
|
|
||||||
tk.gocuiSize.h0,
|
|
||||||
tk.gocuiSize.w1,
|
|
||||||
tk.gocuiSize.h1, 0)
|
|
||||||
if err != nil {
|
|
||||||
log.Info("makeTK() err", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if tk.v == nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
tk.v.Wrap = true
|
|
||||||
tk.v.Frame = true
|
|
||||||
tk.v.Clear()
|
|
||||||
fmt.Fprint(tk.v, items)
|
|
||||||
*/
|
|
||||||
tk.Show()
|
tk.Show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue