Compare commits
No commits in common. "guimaster" and "v0.22.20" have entirely different histories.
|
@ -5,4 +5,3 @@
|
|||
go.mod
|
||||
go.sum
|
||||
gocui
|
||||
resources/*.so
|
||||
|
|
8
Makefile
8
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = $(shell git describe --tags)
|
||||
BUILDTIME = $(shell date +%Y.%m.%d)
|
||||
|
||||
all: clean goimports vet gocui
|
||||
all: goimports vet gocui
|
||||
@ldd gocui.so
|
||||
|
||||
vet:
|
||||
|
@ -9,7 +9,7 @@ vet:
|
|||
@echo this go plugin builds okay
|
||||
|
||||
gocui:
|
||||
GO111MODULE=off go build -v -x -buildmode=plugin -o gocui.so \
|
||||
GO111MODULE=off go build -v -buildmode=plugin -o gocui.so \
|
||||
-ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}"
|
||||
|
||||
install:
|
||||
|
@ -23,9 +23,9 @@ custom:
|
|||
GO111MODULE=off go build -v -work -buildmode=blah
|
||||
|
||||
clean:
|
||||
rm -f gocui *.so go.*
|
||||
rm -f gocui gocui.so
|
||||
rm -f *.pb.go *.patch
|
||||
go-mod-clean purge
|
||||
go-mod-clean --purge
|
||||
|
||||
# Test the README.md & doc.go file
|
||||
# this runs pkgsite, the binary that does dev.go.dev
|
||||
|
|
14
checkbox.go
14
checkbox.go
|
@ -23,16 +23,16 @@ func setChecked(n *tree.Node, b bool) {
|
|||
|
||||
// redraw the checkbox
|
||||
func (tk *guiWidget) setCheckbox() {
|
||||
if tk.WidgetType() != widget.Checkbox {
|
||||
log.Log(WARN, "setCheckbox() being run on widget:", tk.WidgetType())
|
||||
if tk.node.WidgetType != widget.Checkbox {
|
||||
log.Log(WARN, "setCheckbox() being run on widget:", tk.node.WidgetType)
|
||||
return
|
||||
}
|
||||
if tk.Checked() {
|
||||
log.Log(WARN, "setCheckbox() got true", tk.Checked())
|
||||
tk.labelN = "X " + tk.GetLabel()
|
||||
if tk.node.State.Checked {
|
||||
log.Log(WARN, "setCheckbox() got true", tk.node.State.Checked)
|
||||
tk.labelN = "X " + tk.node.State.Label
|
||||
} else {
|
||||
log.Log(WARN, "setCheckbox() got false", tk.Checked())
|
||||
tk.labelN = "_ " + tk.GetLabel()
|
||||
log.Log(WARN, "setCheckbox() got false", tk.node.State.Checked)
|
||||
tk.labelN = "_ " + tk.node.State.Label
|
||||
}
|
||||
|
||||
tk.Hide()
|
||||
|
|
554
color.go
554
color.go
|
@ -3,328 +3,217 @@
|
|||
|
||||
package main
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
// simple colors for light and dark
|
||||
|
||||
// information about how terminfo works
|
||||
// https://jvns.ca/blog/2024/10/01/terminal-colours/
|
||||
|
||||
// TODO: move all this to a protobuf
|
||||
import (
|
||||
"math/rand"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
//w.v.SelBgColor = gocui.ColorCyan
|
||||
//color.go: w.v.SelFgColor = gocui.ColorBlack
|
||||
//color.go: w.v.BgColor = gocui.ColorGreen
|
||||
|
||||
var none gocui.Attribute = gocui.AttrNone
|
||||
var lightPurple gocui.Attribute = gocui.GetColor("#DDDDDD") // light purple
|
||||
var darkPurple gocui.Attribute = gocui.GetColor("#FFAA55") // Dark Purple
|
||||
var heavyPurple gocui.Attribute = gocui.GetColor("#88AA55") // heavy purple
|
||||
var powdererBlue gocui.Attribute = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
|
||||
var superLightGrey gocui.Attribute = gocui.GetColor("#55AAFF") // super light grey
|
||||
|
||||
// Standard defined colors from gocui:
|
||||
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
|
||||
|
||||
// v.BgColor = gocui.GetColor("#111111") // crazy red
|
||||
// v.BgColor = gocui.GetColor("#FF9911") // heavy red
|
||||
// v.SelBgColor = gocui.GetColor("#FFEE11") // blood red
|
||||
|
||||
// v.BgColor = gocui.GetColor("#55AAFF") // super light grey
|
||||
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
|
||||
|
||||
// Normal Text On mouseover
|
||||
//
|
||||
// Widget Frame Text background Text background
|
||||
var colorWindow colorT = colorT{
|
||||
frame: none,
|
||||
fg: gocui.ColorBlue,
|
||||
bg: none,
|
||||
selFg: gocui.ColorWhite,
|
||||
// selBg: powdererBlue,
|
||||
selBg: gocui.ColorBlue,
|
||||
name: "normal window",
|
||||
}
|
||||
|
||||
var colorActiveW colorT = colorT{
|
||||
frame: none,
|
||||
fg: gocui.ColorWhite,
|
||||
bg: gocui.ColorBlue,
|
||||
selFg: gocui.ColorBlue,
|
||||
selBg: none,
|
||||
name: "normal window",
|
||||
}
|
||||
|
||||
// var colorActiveW colorT = colorT{none, none, powdererBlue, none, powdererBlue, "active window"} // sets the window to blue
|
||||
|
||||
var colorTab colorT = colorT{gocui.ColorBlue, gocui.ColorBlue, none, none, powdererBlue, "normal tab"}
|
||||
var colorActiveT colorT = colorT{gocui.ColorBlue, none, powdererBlue, none, powdererBlue, "active tab"}
|
||||
|
||||
// var colorLabel colorT = colorT{none, none, superLightGrey, none, superLightGrey, "normal label"}
|
||||
// var colorGroup colorT = colorT{none, none, superLightGrey, none, superLightGrey, "normal group"}
|
||||
|
||||
var colorDisabled colorT = colorT{
|
||||
frame: superLightGrey,
|
||||
fg: superLightGrey,
|
||||
bg: superLightGrey,
|
||||
selFg: gocui.ColorBlack,
|
||||
selBg: gocui.ColorBlack,
|
||||
name: "disabled widget",
|
||||
}
|
||||
|
||||
var colorLabel colorT = colorT{
|
||||
frame: gocui.ColorWhite,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: none,
|
||||
selBg: none,
|
||||
name: "normal label",
|
||||
}
|
||||
|
||||
var colorGroup colorT = colorT{
|
||||
frame: none,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: gocui.ColorWhite,
|
||||
selBg: none,
|
||||
name: "normal label",
|
||||
}
|
||||
|
||||
var colorButton colorT = colorT{
|
||||
frame: gocui.ColorGreen,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: gocui.ColorGreen,
|
||||
selBg: none,
|
||||
name: "normal button",
|
||||
}
|
||||
|
||||
var colorButtonDense colorT = colorT{
|
||||
frame: none,
|
||||
fg: none,
|
||||
bg: gocui.ColorGreen,
|
||||
// bg: tcell.ColorGreen,
|
||||
selFg: none,
|
||||
selBg: gocui.ColorWhite,
|
||||
name: "normal button",
|
||||
}
|
||||
|
||||
var colorDropdown colorT = colorT{
|
||||
frame: gocui.ColorYellow,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: gocui.ColorYellow,
|
||||
selBg: gocui.ColorBlack,
|
||||
name: "normal dropdown",
|
||||
}
|
||||
|
||||
var colorCombobox colorT = colorT{
|
||||
frame: gocui.ColorBlue,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: gocui.ColorBlue,
|
||||
selBg: gocui.ColorBlack,
|
||||
name: "normal combobox",
|
||||
}
|
||||
|
||||
var colorCheckbox colorT = colorT{
|
||||
frame: gocui.ColorRed,
|
||||
fg: none,
|
||||
bg: none,
|
||||
selFg: gocui.ColorRed,
|
||||
selBg: gocui.ColorWhite,
|
||||
name: "normal checkbox",
|
||||
}
|
||||
|
||||
// widget debugging colors. these widgets aren't displayed unless you are debugging
|
||||
var colorRoot colorT = colorT{gocui.ColorRed, none, powdererBlue, none, gocui.ColorBlue, "debug root"}
|
||||
var colorFlag colorT = colorT{gocui.ColorRed, none, powdererBlue, none, gocui.ColorGreen, "debug flag"}
|
||||
var colorBox colorT = colorT{gocui.ColorRed, none, lightPurple, none, gocui.ColorCyan, "debug box"}
|
||||
var colorGrid colorT = colorT{gocui.ColorRed, none, lightPurple, none, gocui.ColorRed, "debug grid"}
|
||||
var colorNone colorT = colorT{none, none, none, none, none, "debug none"}
|
||||
|
||||
// actually sets the colors for the gocui element
|
||||
// the user will see the colors change when this runs
|
||||
// TODO: add black/white only flag for ttyS0
|
||||
// TODO: fix kvm/qemu serial console & SIGWINCH.
|
||||
// TODO: check minicom (doesn't work)
|
||||
// TODO: fix riscv boards
|
||||
|
||||
// DONE ON ENABLE() WIDGET
|
||||
// restores the last saved color and makes it active
|
||||
func (tk *guiWidget) restoreEnableColor() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
// TODO: or fix kvm/qemu serial console & SIGWINCH.
|
||||
// TODO: and minicom and uboot and 5 million other things.
|
||||
// TODO: maybe enough of us could actually do that if we made it a goal.
|
||||
// TODO: start with riscv boards and fix it universally there
|
||||
// TODO: so just a small little 'todo' item here
|
||||
func (tk *guiWidget) setColor(newColor *colorT) {
|
||||
if tk.color == newColor {
|
||||
// nothing to do since the colors have nto changed
|
||||
return
|
||||
}
|
||||
tk.color.frame = tk.colorLast.frame
|
||||
tk.color.fg = tk.colorLast.fg
|
||||
tk.color.bg = tk.colorLast.bg
|
||||
tk.color.selFg = tk.colorLast.selFg
|
||||
tk.color.selBg = tk.colorLast.selBg
|
||||
|
||||
tk.activateColor()
|
||||
}
|
||||
|
||||
// DONE ON DISABLE() WIDGET
|
||||
// makes the button look disabled
|
||||
func (tk *guiWidget) setColorDisable() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
// save the current color
|
||||
tk.color.frame = superLightGrey
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = superLightGrey
|
||||
tk.color.selFg = superLightGrey
|
||||
tk.color.selBg = superLightGrey
|
||||
tk.activateColor()
|
||||
}
|
||||
|
||||
// sets the current gocui highlight colors
|
||||
func (tk *guiWidget) activateColor() {
|
||||
tk.color = newColor
|
||||
if tk.v == nil {
|
||||
return
|
||||
}
|
||||
tk.v.FrameColor = tk.color.frame
|
||||
tk.v.FgColor = tk.color.fg
|
||||
tk.v.BgColor = tk.color.bg
|
||||
tk.v.SelFgColor = tk.color.selFg
|
||||
tk.v.SelBgColor = tk.color.selBg
|
||||
if tk.color == nil {
|
||||
// log.Log(NOW, "Set the node to color = nil")
|
||||
tk.color = &colorNone
|
||||
}
|
||||
// log.Log(NOW, "Set the node to color =", tk.color.name)
|
||||
tk.Show()
|
||||
}
|
||||
|
||||
// saves the color and makes it active
|
||||
func (tk *guiWidget) updateColor() {
|
||||
if tk.v == nil {
|
||||
func (w *guiWidget) disableColor() {
|
||||
if w.color != &colorDisabled {
|
||||
w.defaultColor = w.color
|
||||
}
|
||||
w.setColor(&colorDisabled)
|
||||
}
|
||||
|
||||
func (w *guiWidget) enableColor() {
|
||||
w.setColor(w.defaultColor)
|
||||
}
|
||||
|
||||
func (w *guiWidget) setDefaultHighlight() {
|
||||
if w.v == nil {
|
||||
log.Log(ERROR, "SetColor() failed on view == nil")
|
||||
return
|
||||
}
|
||||
if tk.color != nil {
|
||||
tk.colorLast.frame = tk.color.frame
|
||||
tk.colorLast.fg = tk.color.fg
|
||||
tk.colorLast.bg = tk.color.bg
|
||||
tk.colorLast.selFg = tk.color.selFg
|
||||
tk.colorLast.selBg = tk.color.selBg
|
||||
}
|
||||
tk.activateColor()
|
||||
w.v.SelBgColor = gocui.ColorGreen
|
||||
w.v.SelFgColor = gocui.ColorBlack
|
||||
}
|
||||
|
||||
// Below are all the colors. TODO: move to protobuf and save in a config file
|
||||
|
||||
func (tk *guiWidget) setColorWindowFrame() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark { // use a dark color palette
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
} else {
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
}
|
||||
|
||||
tk.updateColor()
|
||||
func randColor() gocui.Attribute {
|
||||
colors := []string{"Green", "#FFAA55", "Yellow", "Blue", "Red", "Black", "White"}
|
||||
i := rand.Intn(len(colors))
|
||||
log.Log(NOW, "randColor() i =", i)
|
||||
return gocui.GetColor(colors[i])
|
||||
}
|
||||
|
||||
// weird. lots of color problems for me on debian sid using the traditional Andy Herzfield 'gnome'
|
||||
func (tk *guiWidget) setColorWindowTitleActive() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark { // use a dark color palette
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorWhite
|
||||
tk.color.fg = gocui.ColorWhite
|
||||
tk.color.bg = gocui.ColorBlue
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
func (w *guiWidget) redoColor(draw bool) {
|
||||
if w == nil {
|
||||
return
|
||||
}
|
||||
|
||||
tk.updateColor()
|
||||
log.Sleep(.05)
|
||||
w.setDefaultHighlight()
|
||||
// w.setDefaultWidgetColor()
|
||||
w.Show()
|
||||
|
||||
for _, child := range w.children {
|
||||
child.redoColor(draw)
|
||||
}
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorWindowTitle() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark { // use a dark color palette
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorWhite
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
}
|
||||
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorBG() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorWhite
|
||||
tk.color.fg = gocui.ColorWhite
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
}
|
||||
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorLabel() {
|
||||
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.ColorWhite
|
||||
}
|
||||
|
||||
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() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
} else {
|
||||
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) 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() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorBlack
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorBlue
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
}
|
||||
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorInput() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorYellow
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorYellow
|
||||
tk.color.selBg = gocui.ColorBlack
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorYellow
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorYellow
|
||||
tk.color.selBg = gocui.ColorBlack
|
||||
}
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorModal() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.ColorRed
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorBlack
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.ColorWhite
|
||||
}
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
// what genius figured this out?
|
||||
func (tk *guiWidget) setColorTextbox() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.ColorRed
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorBlack
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
} else {
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.ColorWhite
|
||||
}
|
||||
tk.updateColor()
|
||||
}
|
||||
|
||||
// just notes down here
|
||||
|
||||
// what genius figured this out?
|
||||
// originally from github.com/dimasma0305/GoFetch
|
||||
func get_teminal_color_palette() string {
|
||||
|
@ -345,28 +234,51 @@ func get_teminal_color_palette() string {
|
|||
return color1 + " " + color2 + " " + color3 + " " + color4 + " " + color5 + " " + color6 + " " + color7 + " " + color8
|
||||
}
|
||||
|
||||
func randColor() gocui.Attribute {
|
||||
colors := []string{"Green", "#FFAA55", "Yellow", "Blue", "Red", "Black", "White"}
|
||||
i := rand.Intn(len(colors))
|
||||
log.Log(NOW, "randColor() i =", i)
|
||||
return gocui.GetColor(colors[i])
|
||||
func (tk *guiWidget) SetColorRed() {
|
||||
tk.color = new(colorT)
|
||||
tk.color.fg = gocui.ColorRed
|
||||
}
|
||||
|
||||
var none gocui.Attribute = gocui.AttrNone
|
||||
var colorNone colorT = colorT{none, none, none, none, none, "debug none"}
|
||||
func (tk *guiWidget) setColorBlue() {
|
||||
// r, g, b :=
|
||||
// newgreen := gocui.NewRGBColor(tcell.ColorLightBlue.RGB())
|
||||
|
||||
var lightPurple gocui.Attribute = gocui.GetColor("#DDDDDD") // light purple
|
||||
var darkPurple gocui.Attribute = gocui.GetColor("#FFAA55") // Dark Purple
|
||||
var heavyPurple gocui.Attribute = gocui.GetColor("#88AA55") // heavy purple
|
||||
var powdererBlue gocui.Attribute = gocui.GetColor("#B0E0E6") // w3c 'powerder blue'
|
||||
var superLightGrey gocui.Attribute = gocui.GetColor("#55AAFF") // super light grey
|
||||
// tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.NewRGBColor(tcell.ColorLightBlue.RGB())
|
||||
}
|
||||
|
||||
// Standard defined colors from gocui:
|
||||
// ColorBlack ColorRed ColorGreen ColorYellow ColorBlue ColorMagenta ColorCyan ColorWhite
|
||||
// weird. lots of color problems for me on debian sid using the traditional Andy Herzfield 'gnome'
|
||||
func (tk *guiWidget) setColorButtonDenseOLD() {
|
||||
/*
|
||||
cellgreen := tcell.ColorLightGreen
|
||||
r, g, b := cellgreen.RGB()
|
||||
newgreen := gocui.NewRGBColor(r, g, b)
|
||||
*/
|
||||
|
||||
// v.BgColor = gocui.GetColor("#111111") // crazy red
|
||||
// v.BgColor = gocui.GetColor("#FF9911") // heavy red
|
||||
// v.SelBgColor = gocui.GetColor("#FFEE11") // blood red
|
||||
// tk.color.fg = gocui.ColorBlue
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
lightGreen := gocui.GetColor("0x90EE90")
|
||||
lightGreen = gocui.GetColor("0x008000")
|
||||
lightGreen = gocui.NewRGBColor(0x00, 0x80, 0x00)
|
||||
|
||||
// v.BgColor = gocui.GetColor("#55AAFF") // super light grey
|
||||
// v.BgColor = gocui.GetColor("#FFC0CB") // 'w3c pink' yellow
|
||||
tk.color.frame = gocui.ColorYellow
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.ColorGreen
|
||||
tk.color.bg = lightGreen
|
||||
tk.color.bg = gocui.Attribute(tcell.ColorLightGreen)
|
||||
tk.color.bg = superLightGrey
|
||||
// bg: gocui.ColorGreen,
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.ColorGreen
|
||||
|
||||
// tk.color = &colorButtonDense
|
||||
|
||||
/*
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
r, g, b := tcell.ColorLightGreen.RGB()
|
||||
log.Info("color =", tcell.ColorLightGreen.CSS(), r, g, b)
|
||||
tk.color.selBg = gocui.NewRGBColor(r, g, b)
|
||||
*/
|
||||
}
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
// simple colors for light and dark
|
||||
|
||||
import (
|
||||
"github.com/awesome-gocui/gocui"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) setColorWindowFrame() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark { // use a dark color palette
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
}
|
||||
|
||||
// weird. lots of color problems for me on debian sid using the traditional Andy Herzfield 'gnome'
|
||||
func (tk *guiWidget) setColorWindowTitle() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark { // use a dark color palette
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.ColorWhite
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.ColorBlue
|
||||
tk.color.selFg = gocui.ColorBlue
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorBG() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.ColorWhite
|
||||
tk.color.fg = gocui.ColorWhite
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorLabel() {
|
||||
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
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlack
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.ColorWhite
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorButtonDense() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.AttrNone
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
return
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorButton() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorBlack
|
||||
tk.color.fg = gocui.ColorBlue
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.ColorBlue
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorWhite
|
||||
tk.color.selBg = gocui.ColorBlue
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorInput() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorYellow
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorYellow
|
||||
tk.color.selBg = gocui.ColorBlack
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.ColorYellow
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.ColorYellow
|
||||
tk.color.selBg = gocui.ColorBlack
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setColorModal() {
|
||||
if tk.color == nil {
|
||||
tk.color = new(colorT)
|
||||
}
|
||||
if me.dark {
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.ColorRed
|
||||
tk.color.bg = gocui.ColorBlack
|
||||
tk.color.selFg = gocui.ColorBlack
|
||||
tk.color.selBg = gocui.AttrNone
|
||||
return
|
||||
}
|
||||
tk.color.frame = gocui.ColorRed
|
||||
tk.color.fg = gocui.AttrNone
|
||||
tk.color.bg = gocui.AttrNone
|
||||
tk.color.selFg = gocui.AttrNone
|
||||
tk.color.selBg = gocui.ColorWhite
|
||||
}
|
36
debug.go
36
debug.go
|
@ -12,9 +12,9 @@ import (
|
|||
)
|
||||
|
||||
func (w *guiWidget) dumpTree(s string) {
|
||||
// log.Log(ERROR, "dump w", w.WidgetId(), w.WidgetType, w.String())
|
||||
// log.Log(ERROR, "dump w", w.node.WidgetId, w.WidgetType, w.String())
|
||||
if w == nil {
|
||||
log.Log(ERROR, "dump w.TK == nil", w.WidgetId(), w.WidgetType(), w.String())
|
||||
log.Log(ERROR, "dump w.TK == nil", w.node.WidgetId, w.node.WidgetType, w.String())
|
||||
return
|
||||
}
|
||||
w.dumpWidget("dumpTree() " + s)
|
||||
|
@ -25,12 +25,12 @@ func (w *guiWidget) dumpTree(s string) {
|
|||
}
|
||||
|
||||
func (w *guiWidget) dumpWindows(s string) {
|
||||
// log.Log(ERROR, "dump w", w.WidgetId(), w.WidgetType, w.String())
|
||||
// log.Log(ERROR, "dump w", w.node.WidgetId, w.WidgetType, w.String())
|
||||
if w == nil {
|
||||
log.Log(ERROR, "dump w.TK == nil", w.WidgetId(), w.WidgetType(), w.String())
|
||||
log.Log(ERROR, "dump w.TK == nil", w.node.WidgetId, w.node.WidgetType, w.String())
|
||||
return
|
||||
}
|
||||
if w.WidgetType() == widget.Window {
|
||||
if w.node.WidgetType == widget.Window {
|
||||
s += fmt.Sprintf(" F(%d,%d)", w.force.w0, w.force.h0)
|
||||
// can't set this here. doesn't work
|
||||
// w.full.w0 = w.force.w0
|
||||
|
@ -49,13 +49,13 @@ func (tk *guiWidget) dumpWidget(s string) {
|
|||
var s1 string
|
||||
var pId int
|
||||
// tk.verifyRect()
|
||||
if tk.parent == nil {
|
||||
log.Logf(WARN, "showWidgetPlacement() parent == nil wId=%d cuiName=%s", tk.WidgetId(), tk.cuiName)
|
||||
if tk.node.Parent == nil {
|
||||
log.Logf(WARN, "showWidgetPlacement() parent == nil wId=%d cuiName=%s", tk.node.WidgetId, tk.cuiName)
|
||||
pId = 0
|
||||
} else {
|
||||
pId = tk.parent.WidgetId()
|
||||
pId = tk.node.Parent.WidgetId
|
||||
}
|
||||
s1 = fmt.Sprintf("(wId,pId)=(%4d,%4d) ", tk.WidgetId(), pId)
|
||||
s1 = fmt.Sprintf("(wId,pId)=(%4d,%4d) ", tk.node.WidgetId, pId)
|
||||
sizeW, sizeH := tk.Size()
|
||||
hide := "S"
|
||||
if tk.Hidden() {
|
||||
|
@ -69,10 +69,10 @@ func (tk *guiWidget) dumpWidget(s string) {
|
|||
s1 += fmt.Sprintf(" %3s %3s %3s %3s ", "", "", "", "")
|
||||
}
|
||||
s1 += fmt.Sprintf(" full=(%3d,%3d,%3d,%3d)", tk.full.w0, tk.full.h0, tk.full.w1, tk.full.h1)
|
||||
if tk.parent != nil {
|
||||
if tk.parent.WidgetType() == widget.Grid {
|
||||
s1 += fmt.Sprintf("At(%3d,%3d)", tk.GridW(), tk.GridH())
|
||||
s1 += fmt.Sprintf("(%3d,%3d) ", tk.parent.widths[tk.GridW()], tk.parent.heights[tk.GridH()])
|
||||
if tk.node.Parent != nil {
|
||||
if tk.node.Parent.WidgetType == widget.Grid {
|
||||
s1 += fmt.Sprintf("At(%3d,%3d)", tk.node.State.AtW, tk.node.State.AtH)
|
||||
s1 += fmt.Sprintf("(%3d,%3d) ", tk.parent.widths[tk.node.State.AtW], tk.parent.heights[tk.node.State.AtH])
|
||||
} else {
|
||||
s1 += fmt.Sprintf(" %3s %3s ", "", "")
|
||||
s1 += fmt.Sprintf(" %3s %3s ", "", "")
|
||||
|
@ -81,14 +81,10 @@ func (tk *guiWidget) dumpWidget(s string) {
|
|||
s1 += fmt.Sprintf(" %3s %3s ", "", "")
|
||||
}
|
||||
var end string
|
||||
if tk.WidgetType() == widget.Box {
|
||||
end = fmt.Sprintf("%-8s %-8s %s %s", tk.WidgetType(), tk.cuiName, tk.Direction().String(), tk.String())
|
||||
if tk.node.WidgetType == widget.Box {
|
||||
end = fmt.Sprintf("%-8s %-8s %s %s", tk.node.WidgetType, tk.cuiName, tk.node.State.Direction.String(), tk.String())
|
||||
} else {
|
||||
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)"
|
||||
end = fmt.Sprintf("%-8s %-8s %s", tk.node.WidgetType, tk.cuiName, tk.String())
|
||||
}
|
||||
log.Log(GOCUI, s1, s, end)
|
||||
}
|
||||
|
|
|
@ -15,12 +15,6 @@ import (
|
|||
|
||||
// tells 'gocui' where to send events
|
||||
func registerHandlers(g *gocui.Gui) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Info("EVENT BINDINGS recovered in r", r)
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
// mouse handlers
|
||||
g.SetKeybinding("", gocui.MouseLeft, gocui.ModNone, mouseDown) // normal left mouse down
|
||||
|
@ -58,7 +52,6 @@ func registerHandlers(g *gocui.Gui) {
|
|||
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("", '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 (?)
|
||||
}
|
||||
|
||||
|
@ -78,23 +71,6 @@ 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
|
||||
func theNotsure(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Info("got to theNotsure(). now what? dark =", me.dark)
|
||||
me.refresh = true
|
||||
log.Info("running VerifyParentId()")
|
||||
me.treeRoot.VerifyParentId()
|
||||
/*
|
||||
if me.debug {
|
||||
log.Info("debugging off")
|
||||
me.debug = false
|
||||
} else {
|
||||
log.Info("debugging on")
|
||||
me.debug = true
|
||||
}
|
||||
win := findWindowUnderMouse()
|
||||
if win != nil {
|
||||
win.dumpWidget("found() win. redrawing window:")
|
||||
win.makeWindowActive()
|
||||
}
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -104,20 +80,18 @@ func theDarkness(g *gocui.Gui, v *gocui.View) error {
|
|||
log.Info("you have seen the light")
|
||||
} else {
|
||||
me.dark = true
|
||||
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")
|
||||
log.Info("you have entered into darkness")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func wheelsUp(g *gocui.Gui, v *gocui.View) error {
|
||||
stdoutWheelsUp()
|
||||
log.Info("private wheels up")
|
||||
return nil
|
||||
}
|
||||
|
||||
func wheelsDown(g *gocui.Gui, v *gocui.View) error {
|
||||
stdoutWheelsDown()
|
||||
log.Info("you've landed")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -132,6 +106,8 @@ func tabCycleWindows(g *gocui.Gui, v *gocui.View) error {
|
|||
return nil
|
||||
}
|
||||
tk.makeWindowActive()
|
||||
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -141,13 +117,11 @@ func doEsc(g *gocui.Gui, v *gocui.View) error {
|
|||
me.dropdown.tk.Hide()
|
||||
me.dropdown.active = false
|
||||
log.Info("escaped from dropdown")
|
||||
me.baseGui.SetCurrentView(me.notify.clock.tk.cuiName)
|
||||
}
|
||||
if me.textbox.active {
|
||||
me.textbox.tk.Hide()
|
||||
me.textbox.active = false
|
||||
log.Info("escaped from textbox")
|
||||
me.baseGui.SetCurrentView(me.notify.clock.tk.cuiName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -185,19 +159,6 @@ func theFind(g *gocui.Gui, v *gocui.View) error {
|
|||
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)
|
||||
func theLetterD(g *gocui.Gui, v *gocui.View) error {
|
||||
// widgets that don't have physical existance in
|
||||
|
|
|
@ -8,14 +8,12 @@ import (
|
|||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
)
|
||||
|
||||
func theStdout(g *gocui.Gui, v *gocui.View) error {
|
||||
// me.stdout.pager = 0
|
||||
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)
|
||||
me.stdout.changed = true
|
||||
|
||||
if me.stdout.outputOnTop {
|
||||
if me.stdout.outputOffscreen {
|
||||
|
@ -24,44 +22,27 @@ func theStdout(g *gocui.Gui, v *gocui.View) error {
|
|||
me.stdout.lastW = me.stdout.tk.gocuiSize.w0
|
||||
me.stdout.lastH = me.stdout.tk.gocuiSize.h0
|
||||
relocateStdoutOffscreen()
|
||||
new1 := new(tree.ToolkitConfig)
|
||||
new1.Plugin = "gocui"
|
||||
new1.Name = "stdoutoffscreen"
|
||||
new1.Value = "true"
|
||||
me.myTree.ConfigSave(new1)
|
||||
return nil
|
||||
} else {
|
||||
me.stdout.outputOffscreen = true
|
||||
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
|
||||
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
||||
me.stdout.outputOnTop = false
|
||||
setThingsOnTop()
|
||||
new1 := new(tree.ToolkitConfig)
|
||||
new1.Plugin = "gocui"
|
||||
new1.Name = "stdoutlevel"
|
||||
new1.Value = "bottom"
|
||||
me.myTree.ConfigSave(new1)
|
||||
// me.baseGui.SetViewOnBottom("msg")
|
||||
// setBottomBG()
|
||||
} else {
|
||||
me.stdout.outputOnTop = true
|
||||
setThingsOnTop()
|
||||
new1 := new(tree.ToolkitConfig)
|
||||
new1.Plugin = "gocui"
|
||||
new1.Name = "stdoutlevel"
|
||||
new1.Value = "top"
|
||||
me.myTree.ConfigSave(new1)
|
||||
// me.baseGui.SetViewOnTop("msg")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func stdoutPgup(g *gocui.Gui, v *gocui.View) error {
|
||||
me.stdout.pager -= me.stdout.Height() - 2
|
||||
me.stdout.pager -= 40
|
||||
if me.stdout.pager < 0 {
|
||||
me.stdout.pager = 0
|
||||
}
|
||||
|
@ -77,55 +58,21 @@ func stdoutHome(g *gocui.Gui, v *gocui.View) error {
|
|||
}
|
||||
|
||||
func stdoutArrowUp(g *gocui.Gui, v *gocui.View) error {
|
||||
if me.stdout.reverse {
|
||||
stdoutWheelsDown()
|
||||
} else {
|
||||
stdoutWheelsUp()
|
||||
}
|
||||
me.stdout.pager += 1
|
||||
me.stdout.tk.refreshStdout()
|
||||
return nil
|
||||
}
|
||||
|
||||
func stdoutArrowDown(g *gocui.Gui, v *gocui.View) error {
|
||||
if me.stdout.reverse {
|
||||
stdoutWheelsUp()
|
||||
} else {
|
||||
stdoutWheelsDown()
|
||||
}
|
||||
me.stdout.pager -= 1
|
||||
me.stdout.tk.refreshStdout()
|
||||
return nil
|
||||
}
|
||||
|
||||
func stdoutPgdn(g *gocui.Gui, v *gocui.View) error {
|
||||
win := findWindowUnderMouse()
|
||||
if win != nil {
|
||||
if win.full.Height() > 50 {
|
||||
log.Info("paging through really large window pager =", win.window.pager)
|
||||
win.window.pager += 10
|
||||
return nil
|
||||
}
|
||||
}
|
||||
me.stdout.pager += 10
|
||||
|
||||
tk := me.stdout.tk
|
||||
tk.refreshStdout()
|
||||
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()
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
|
||||
"go.wit.com/log"
|
||||
)
|
||||
|
||||
|
@ -40,36 +44,6 @@ func quit(g *gocui.Gui, v *gocui.View) error {
|
|||
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 {
|
||||
if me.baseGui == nil {
|
||||
log.Log(ERROR, "SetView() ERROR: me.baseGui == nil")
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/awesome-gocui/gocui"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func mouseUp(g *gocui.Gui, v *gocui.View) error {
|
||||
|
@ -21,6 +22,7 @@ func mouseUp(g *gocui.Gui, v *gocui.View) error {
|
|||
*/
|
||||
|
||||
me.mouse.mouseUp = true
|
||||
// me.mouse.globalMouseDown = false
|
||||
me.mouse.currentDrag = nil
|
||||
|
||||
if me.mouse.double && (time.Since(me.mouse.down) < me.mouse.doubletime) {
|
||||
|
@ -44,6 +46,7 @@ func mouseDown(g *gocui.Gui, v *gocui.View) error {
|
|||
if time.Since(me.mouse.down) < me.mouse.doubletime {
|
||||
me.mouse.double = true
|
||||
}
|
||||
// me.mouse.globalMouseDown = true
|
||||
me.mouse.mouseUp = false
|
||||
me.mouse.down = time.Now()
|
||||
w, h := g.MousePosition()
|
||||
|
@ -54,11 +57,11 @@ func mouseDown(g *gocui.Gui, v *gocui.View) error {
|
|||
if win != nil {
|
||||
w, h := g.MousePosition()
|
||||
s := fmt.Sprintf("mouse(%d,%d) ", w, h)
|
||||
offW := win.full.w1 - w
|
||||
offH := win.full.h1 - h
|
||||
offW := win.gocuiSize.w1 - w
|
||||
offH := win.gocuiSize.h1 - h
|
||||
s += fmt.Sprintf("corner(%d,%d)", offW, offH)
|
||||
if (offW < 3) && (offH < 3) {
|
||||
log.Info("attempting resize on ", s, win.cuiName)
|
||||
// log.Info("mouse down resize on ", s)
|
||||
me.mouse.resize = true
|
||||
// store the stdout corner for computing the drag size
|
||||
me.stdout.lastW = me.stdout.tk.gocuiSize.w0
|
||||
|
@ -69,6 +72,79 @@ func mouseDown(g *gocui.Gui, v *gocui.View) error {
|
|||
}
|
||||
win.setAsDragging()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if time.Since(me.mouse.down) < me.mouse.clicktime {
|
||||
log.Info("not yet")
|
||||
return nil
|
||||
}
|
||||
|
||||
w, h := g.MousePosition()
|
||||
|
||||
// if the dropdown is active, never do anything else
|
||||
if me.dropdown.active {
|
||||
log.Info("mouseDown() stopping here. dropdwon menu is in effect")
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if (tk.node.WidgetType == widget.Flag) && (tk == me.dropdown.tk) {
|
||||
// log.Info("SENDING CLICK TO Flag (dropdown)")
|
||||
tk.doWidgetClick(w, h)
|
||||
me.dropdown.active = false
|
||||
return nil
|
||||
}
|
||||
}
|
||||
log.Info("never found dropdown at", w, h)
|
||||
return nil
|
||||
}
|
||||
|
||||
// if the textbox is active, never do anything else
|
||||
if me.textbox.active {
|
||||
log.Info("mouseDown() stopping here. textbox widget is open")
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if (tk.node.WidgetType == widget.Flag) && (tk == me.textbox.tk) {
|
||||
me.textbox.active = false
|
||||
textboxClosed()
|
||||
return nil
|
||||
}
|
||||
}
|
||||
log.Info("never found textbox at", w, h)
|
||||
return nil
|
||||
}
|
||||
|
||||
// figre out what window this is
|
||||
tk := findWindowUnderMouse()
|
||||
if tk == nil {
|
||||
log.Info("mouseDown() nothing to click on at", w, h)
|
||||
return nil
|
||||
}
|
||||
tk.makeWindowActive()
|
||||
// log.Info("SENDING mouseDown() to findWindowUnderMouse()")
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
// check to see if this is a direct click on a widget
|
||||
for _, tk := range tk.findByXYreal(w, h) {
|
||||
// tk.dumpWidget("mouseDown()")
|
||||
if tk.node.WidgetType == widget.Button {
|
||||
// log.Info("SENDING CLICK TO Button")
|
||||
tk.doWidgetClick(w, h)
|
||||
return nil
|
||||
}
|
||||
if tk.node.WidgetType == widget.Checkbox {
|
||||
// log.Info("SENDING CLICK TO Checkbox")
|
||||
tk.doWidgetClick(w, h)
|
||||
return nil
|
||||
}
|
||||
if tk.node.WidgetType == widget.Dropdown {
|
||||
// log.Info("SENDING CLICK TO Dropdown")
|
||||
tk.doWidgetClick(w, h)
|
||||
return nil
|
||||
}
|
||||
if tk.node.WidgetType == widget.Textbox {
|
||||
// log.Info("SENDING CLICK TO Textbox")
|
||||
tk.doWidgetClick(w, h)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
me.mouse.currentDrag = tk
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -4,18 +4,107 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/awesome-gocui/gocui"
|
||||
"fmt"
|
||||
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) doButtonClick() {
|
||||
if tk.IsEnabled() {
|
||||
tk.dumpWidget("click()") // enable this to debug widget clicks
|
||||
me.myTree.SendFromUser(tk.node)
|
||||
/*
|
||||
// this didn't work. panic()
|
||||
func (tk *guiWidget) DeleteNode() {
|
||||
p := tk.parent
|
||||
for i, child := range p.children {
|
||||
log.Log(GOCUI, "parent has child:", i, child.node.WidgetId, child.node.GetProgName())
|
||||
if tk == child {
|
||||
log.Log(GOCUI, "Found child ==", i, child.node.WidgetId, child.node.GetProgName())
|
||||
log.Log(GOCUI, "Found n ==", i, tk.node.WidgetId, tk.node.GetProgName())
|
||||
p.children = append(p.children[:i], p.children[i+1:]...)
|
||||
}
|
||||
}
|
||||
for i, child := range p.children {
|
||||
log.Log(TREE, "parent now has child:", i, child.WidgetId, child.GetProgName())
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func (tk *guiWidget) doWindowClick() {
|
||||
w, h := me.baseGui.MousePosition()
|
||||
tk.dumpWidget(fmt.Sprintf("doWindowClick(%d,%d)", w, h))
|
||||
|
||||
// compare the mouse location to the 'X' indicator to close the window
|
||||
if tk.gocuiSize.inRect(w, h) {
|
||||
offset := w - tk.gocuiSize.w1
|
||||
if (offset < 2) && (offset > -2) {
|
||||
// close enough // close the window here
|
||||
tk.dumpWidget(fmt.Sprintf("Close Window(%d,%d) (off=%d)", w, h, offset))
|
||||
tk.hideWindow()
|
||||
n := tk.node
|
||||
tk.deleteNode()
|
||||
me.myTree.SendWindowCloseEvent(n)
|
||||
/*
|
||||
n.DeleteNode()
|
||||
|
||||
tk.DeleteNode()
|
||||
*/
|
||||
return
|
||||
}
|
||||
if tk.window.collapsed {
|
||||
tk.dumpWidget(fmt.Sprintf("collapse = false"))
|
||||
tk.window.collapsed = false
|
||||
} else {
|
||||
log.Info("button is currently disabled by the application")
|
||||
// tk.dumpWidget("disabled()") // enable this to debug widget clicks
|
||||
tk.dumpWidget(fmt.Sprintf("collapse = true"))
|
||||
tk.window.collapsed = true
|
||||
}
|
||||
} else {
|
||||
tk.window.collapsed = false
|
||||
}
|
||||
// if there is a current window, hide it
|
||||
if me.currentWindow != nil {
|
||||
me.currentWindow.setColor(&colorWindow)
|
||||
}
|
||||
|
||||
// now set this window as the current window
|
||||
me.currentWindow = tk
|
||||
|
||||
tk.redrawWindow(w, h)
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
}
|
||||
|
||||
// this whole things was impossible to make but it got me where I am now
|
||||
// the debugging is way way better now with it being visible in the Stdout window
|
||||
// so now it's possible to redo all this and make it better
|
||||
func (tk *guiWidget) doWidgetClick(w int, h int) {
|
||||
tk.dumpWidget(fmt.Sprintf("doWidgetClick(%d,%d)", w, h))
|
||||
switch tk.node.WidgetType {
|
||||
case widget.Window:
|
||||
tk.doWindowClick()
|
||||
return
|
||||
case widget.Checkbox:
|
||||
if tk.node.State.Checked {
|
||||
log.Log(WARN, "checkbox is being set to false")
|
||||
tk.node.State.Checked = false
|
||||
tk.setCheckbox()
|
||||
} else {
|
||||
log.Log(WARN, "checkbox is being set to true")
|
||||
tk.node.State.Checked = true
|
||||
tk.setCheckbox()
|
||||
}
|
||||
me.myTree.SendUserEvent(tk.node)
|
||||
case widget.Button:
|
||||
me.myTree.SendFromUser(tk.node)
|
||||
case widget.Combobox:
|
||||
tk.showDropdown()
|
||||
case widget.Dropdown:
|
||||
tk.showDropdown()
|
||||
case widget.Textbox:
|
||||
tk.showTextbox()
|
||||
case widget.Flag:
|
||||
tk.dropdownClicked(w, h)
|
||||
case widget.Stdout:
|
||||
tk.dumpWidget("stdout click()")
|
||||
default:
|
||||
tk.dumpWidget("undef click()")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,12 +115,12 @@ func doMouseClick(w int, h int) {
|
|||
if me.dropdown.active || me.textbox.active {
|
||||
// can't drag or do anything when dropdown or textbox are visible
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if tk.WidgetId() == me.dropdown.wId {
|
||||
log.Info("got dropdown click", w, h, tk.cuiName)
|
||||
if tk.node.WidgetId == me.dropdown.wId {
|
||||
log.Info("got dropdwon click", w, h, tk.cuiName)
|
||||
tk.dropdownClicked(w, h)
|
||||
return
|
||||
}
|
||||
if tk.WidgetId() == me.textbox.wId {
|
||||
if tk.node.WidgetId == me.textbox.wId {
|
||||
log.Info("got textbox click", w, h, tk.cuiName)
|
||||
textboxClosed()
|
||||
return
|
||||
|
@ -42,63 +131,26 @@ func doMouseClick(w int, h int) {
|
|||
}
|
||||
|
||||
win := findWindowUnderMouse()
|
||||
if win == nil {
|
||||
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
|
||||
}
|
||||
if !win.isWindowActive() {
|
||||
win.makeWindowActive()
|
||||
return
|
||||
} else {
|
||||
// potentally the user is closing the window
|
||||
if win.checkWindowClose(w, h) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if win != nil {
|
||||
// look in this window for widgets
|
||||
// widgets have priority. send the click here first
|
||||
for _, tk := range win.findByXYreal(w, h) {
|
||||
switch tk.WidgetType() {
|
||||
switch tk.node.WidgetType {
|
||||
case widget.Checkbox:
|
||||
if tk.Checked() {
|
||||
if tk.node.State.Checked {
|
||||
log.Log(WARN, "checkbox is being set to false")
|
||||
tk.SetChecked(false)
|
||||
tk.node.State.Checked = false
|
||||
tk.setCheckbox()
|
||||
} else {
|
||||
log.Log(WARN, "checkbox is being set to true")
|
||||
tk.SetChecked(true)
|
||||
tk.node.State.Checked = true
|
||||
tk.setCheckbox()
|
||||
}
|
||||
me.myTree.SendUserEvent(tk.node)
|
||||
return
|
||||
case widget.Button:
|
||||
tk.doButtonClick()
|
||||
tk.dumpWidget("click()") // enable this to debug widget clicks
|
||||
me.myTree.SendFromUser(tk.node)
|
||||
return
|
||||
case widget.Combobox:
|
||||
tk.showDropdown()
|
||||
|
@ -107,28 +159,39 @@ func doMouseClick(w int, h int) {
|
|||
tk.showDropdown()
|
||||
return
|
||||
case widget.Textbox:
|
||||
log.Log(WARN, "TODO: textbox click")
|
||||
tk.prepTextbox()
|
||||
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")
|
||||
}
|
||||
}
|
||||
tk.showTextbox()
|
||||
return
|
||||
default:
|
||||
// TODO: enable the GUI debugger in gocui
|
||||
// tk.dumpWidget("undef click()") // enable this to debug widget clicks
|
||||
}
|
||||
}
|
||||
}
|
||||
log.Info("you clicked on a window, but not any widgets", win.cuiName)
|
||||
win.redrawWindow(win.gocuiSize.w0, win.gocuiSize.h0)
|
||||
me.stdout.outputOnTop = false
|
||||
setThingsOnTop()
|
||||
return
|
||||
}
|
||||
|
||||
// todo: use this?
|
||||
func ctrlDown(g *gocui.Gui, v *gocui.View) error {
|
||||
log.Info("todo: clicked with ctrlDown")
|
||||
return nil
|
||||
var found bool
|
||||
|
||||
for _, tk := range findByXY(w, h) {
|
||||
// will show you everything found on a mouse click. great for debugging!
|
||||
// tk.dumpWidget("click()")
|
||||
if tk.node.WidgetType == widget.Stdout {
|
||||
// don't send clicks to the stdout debugging window
|
||||
// continue
|
||||
}
|
||||
found = true
|
||||
// tk.doWidgetClick(w, h)
|
||||
return
|
||||
}
|
||||
if found {
|
||||
return
|
||||
}
|
||||
|
||||
log.Log(GOCUI, "click() nothing was at:", w, h)
|
||||
return
|
||||
}
|
||||
|
||||
func doMouseDoubleClick(w int, h int) {
|
||||
|
@ -142,12 +205,14 @@ func doMouseDoubleClick(w int, h int) {
|
|||
}
|
||||
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if tk.WidgetType() == widget.Window {
|
||||
tk.makeWindowActive()
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||
me.stdout.outputOnTop = false
|
||||
setThingsOnTop()
|
||||
return
|
||||
}
|
||||
|
||||
if tk.WidgetType() == widget.Stdout {
|
||||
if tk.node.WidgetType == widget.Stdout {
|
||||
if me.stdout.outputOnTop {
|
||||
me.stdout.outputOnTop = false
|
||||
setThingsOnTop()
|
||||
|
|
|
@ -23,16 +23,16 @@ import (
|
|||
// this function uses the mouse position to highlight & unhighlight things
|
||||
// this is run every time the user moves the mouse over the terminal window
|
||||
func mouseMove(g *gocui.Gui) {
|
||||
me.ok = true // this tells init() it's okay to work with gocui
|
||||
|
||||
// this runs while the user moves the mouse. this highlights text
|
||||
// toggle off all highlight views except for whatever is under the mouse
|
||||
// START HIGHLIGHTING
|
||||
for _, view := range g.Views() {
|
||||
view.Highlight = false
|
||||
}
|
||||
w, h := g.MousePosition()
|
||||
// TODO: try to highlight entire grid rows
|
||||
if v, err := g.ViewByPosition(w, h); err == nil {
|
||||
// block anything from highlighting while a dialog box is open
|
||||
// todo: identify and highlight grid rows here
|
||||
if me.dropdown.active || me.textbox.active {
|
||||
if me.dropdown.tk != nil && me.dropdown.tk.v == v {
|
||||
v.Highlight = true
|
||||
|
@ -45,19 +45,7 @@ func mouseMove(g *gocui.Gui) {
|
|||
}
|
||||
}
|
||||
|
||||
// old hack. create the 'msg' view if it does not yet exist
|
||||
// TODO: put this somewhere more correct
|
||||
if widgetView, _ := g.View("msg"); widgetView == nil {
|
||||
me.stdout.changed = true
|
||||
if createStdout(g) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// END HIGHLIGHTING
|
||||
|
||||
// Super Mouse Mode. very useful for debugging in the past. also, just fun
|
||||
// very useful for debugging in the past. also, just fun
|
||||
if me.supermouse {
|
||||
w, h := g.MousePosition()
|
||||
for _, tk := range findByXY(w, h) {
|
||||
|
@ -66,19 +54,33 @@ func mouseMove(g *gocui.Gui) {
|
|||
}
|
||||
}
|
||||
|
||||
if me.mouse.mouseUp {
|
||||
return
|
||||
}
|
||||
// EVERYTHING BELOW THIS IS RELATED TO MOUSE DRAGGING
|
||||
|
||||
// has the mouse been pressed down long enough to start dragging?
|
||||
if time.Since(me.mouse.down) < me.mouse.clicktime {
|
||||
// not dragging
|
||||
// log.Info("not yet")
|
||||
return
|
||||
}
|
||||
|
||||
if me.dropdown.active || me.textbox.active {
|
||||
// can't drag
|
||||
// can't drag or do anything when dropdown or textbox are visible
|
||||
return
|
||||
}
|
||||
// okay, the mouse is down and it has been long enough
|
||||
// the user is trying to drag something. let's figure out what
|
||||
|
||||
// create the 'msg' view if it does not yet exist // TODO: put this somewhere more correct
|
||||
if widgetView, _ := g.View("msg"); widgetView == nil {
|
||||
if createStdout(g) {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
if me.mouse.globalMouseDown && (me.dropdown.active || me.textbox.active) {
|
||||
log.Info("can't drag while dropdown or textbox are active", w, h)
|
||||
return
|
||||
}
|
||||
*/
|
||||
if me.mouse.mouseUp {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -88,8 +90,43 @@ func mouseMove(g *gocui.Gui) {
|
|||
me.mouse.currentDrag.moveNew()
|
||||
return
|
||||
}
|
||||
log.Info(fmt.Sprintf("gocui gui toolkit plugin error. nothing to drag at (%d,%d)", w, h))
|
||||
log.Info(fmt.Sprintf("gui toolkit error. nothing to drag at (%d,%d)", w, h))
|
||||
return
|
||||
|
||||
// if me.mouse.globalMouseDown {
|
||||
// log.Info("msgMouseDown == true")
|
||||
// plugin will segfault if you don't keep this inside a check for msgMouseDown
|
||||
// don't move this code out of here
|
||||
/*
|
||||
// new function that is smarter
|
||||
if tk := findWindowUnderMouse(); tk != nil {
|
||||
tk.setAsDragging()
|
||||
return
|
||||
}
|
||||
// first look for windows
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
tk.setAsDragging()
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// now look for the STDOUT window
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if tk.node.WidgetType == widget.Flag {
|
||||
tk.setAsDragging()
|
||||
return
|
||||
}
|
||||
}
|
||||
for _, tk := range findByXY(w, h) {
|
||||
if tk.node.WidgetType == widget.Stdout {
|
||||
tk.setAsDragging()
|
||||
// tk.moveNew()
|
||||
return
|
||||
}
|
||||
found = true
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func (tk *guiWidget) setAsDragging() {
|
||||
|
@ -101,18 +138,26 @@ func (tk *guiWidget) setAsDragging() {
|
|||
// this is how the window gets dragged around
|
||||
func (tk *guiWidget) moveNew() {
|
||||
w, h := me.baseGui.MousePosition()
|
||||
if tk.WidgetType() == widget.Window {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
tk.window.wasDragged = true
|
||||
|
||||
// compute the new location based off how far the mouse has moved
|
||||
// since the mouse button was pressed down
|
||||
tk.gocuiSize.w0 = tk.lastW + w - me.mouse.downW
|
||||
tk.gocuiSize.h0 = tk.lastH + h - me.mouse.downH
|
||||
tk.makeWindowActive()
|
||||
newW := tk.lastW + w - me.mouse.downW
|
||||
newH := tk.lastH + h - me.mouse.downH
|
||||
tk.redrawWindow(newW, newH)
|
||||
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
return
|
||||
}
|
||||
|
||||
if tk.WidgetType() == widget.Stdout {
|
||||
if tk.node.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.node.WidgetType == widget.Stdout {
|
||||
if me.mouse.resize {
|
||||
newW := w - me.stdout.lastW
|
||||
newH := h - me.stdout.lastH
|
||||
|
@ -130,7 +175,7 @@ func (tk *guiWidget) moveNew() {
|
|||
tk.relocateStdout(newW, newH)
|
||||
// log.Info("Resize false", w, h, newW, newH)
|
||||
}
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
me.stdout.changed = true
|
||||
}
|
||||
// always place the help menu on top
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
}
|
||||
|
|
88
find.go
88
find.go
|
@ -61,7 +61,7 @@ func (tk *guiWidget) findByXYreal(w int, h int) []*guiWidget {
|
|||
if tk.full.inRect(w, h) {
|
||||
widgets = append(widgets, tk)
|
||||
}
|
||||
// log.Log(GOCUI, "findByXY() found", widget.WidgetType(), w, h)
|
||||
// log.Log(GOCUI, "findByXY() found", widget.node.WidgetType, w, h)
|
||||
// }
|
||||
// }
|
||||
// tk.verifyRect()
|
||||
|
@ -84,7 +84,7 @@ func findWindows() []*guiWidget {
|
|||
func (tk *guiWidget) findWindows() []*guiWidget {
|
||||
var found []*guiWidget
|
||||
|
||||
if tk.WidgetType() == widget.Window {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
found = append(found, tk)
|
||||
}
|
||||
|
||||
|
@ -94,6 +94,25 @@ func (tk *guiWidget) findWindows() []*guiWidget {
|
|||
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.node.WidgetType == widget.Stdout {
|
||||
if tk.node.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
|
||||
func findNextWindow() *guiWidget {
|
||||
var found bool
|
||||
|
@ -129,6 +148,13 @@ 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
|
||||
for _, tk := range me.allwin {
|
||||
if tk.window.active {
|
||||
|
@ -145,6 +171,12 @@ func findWindowUnderMouse() *guiWidget {
|
|||
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 {
|
||||
if win.full.inRect(w, h) {
|
||||
// log.Info(fmt.Sprintf("findWindowUnderMouse() found %s window (%dx%d)", win.cuiName, w, h))
|
||||
|
@ -163,8 +195,14 @@ func findWindowUnderMouse() *guiWidget {
|
|||
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 {
|
||||
if tk.WidgetType() == widget.Window {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
return tk
|
||||
}
|
||||
if tk.parent == nil {
|
||||
|
@ -172,47 +210,3 @@ func (tk *guiWidget) findParentWindow() *guiWidget {
|
|||
}
|
||||
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
|
||||
}
|
||||
|
|
116
help.go
116
help.go
|
@ -1,7 +1,7 @@
|
|||
// Copyright 2014 The gocui Authors. All rights reserved.
|
||||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// 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
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
@ -11,6 +11,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
log "go.wit.com/log"
|
||||
|
@ -25,20 +26,16 @@ import (
|
|||
|
||||
var helpText []string = []string{"Help Menu",
|
||||
"",
|
||||
"Tab toggle through windows",
|
||||
"'O' toggle STDOUT",
|
||||
"'H' toggle this gocui menu",
|
||||
"'D' toggle light/dark mode",
|
||||
"CTRL-z background to shell",
|
||||
"CTRL-c quit()",
|
||||
"H: toggle z(H)elp",
|
||||
"D: toggle light/dark mode",
|
||||
"Tab: toggle through windows",
|
||||
"q: quit()",
|
||||
"",
|
||||
"Debugging:",
|
||||
"'S' Supermouse mode",
|
||||
"'M' list all widget positions",
|
||||
"'L' list all widgets in tree",
|
||||
"<Pgup> scroll up the STDOUT window",
|
||||
"<Pgdn> scroll down the STDOUT window",
|
||||
"'r' reverse STDOUT scrolling",
|
||||
"O: toggle (O)output (os.STDOUT)",
|
||||
"S: super mouse",
|
||||
"M: list all widgets positions",
|
||||
"L: list all widgets in tree",
|
||||
}
|
||||
|
||||
func hideHelp() {
|
||||
|
@ -69,18 +66,17 @@ func showHelp() error {
|
|||
}
|
||||
}
|
||||
|
||||
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)
|
||||
help, err := g.SetView("help", maxX-(newW+me.FramePadW), 0, maxX-1, len(helpText)+me.FramePadH, 0)
|
||||
if err != nil {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
help.SelBgColor = gocui.ColorGreen
|
||||
help.SelFgColor = gocui.ColorBlack
|
||||
// fmt.Fprintln(help, "Enter: Click Button")
|
||||
// fmt.Fprintln(help, "Tab/Space: Switch Buttons")
|
||||
// fmt.Fprintln(help, "Backspace: Delete Button")
|
||||
// fmt.Fprintln(help, "Arrow keys: Move Button")
|
||||
|
||||
fmt.Fprintln(help, strings.Join(helpText, "\n"))
|
||||
|
||||
|
@ -90,19 +86,85 @@ func showHelp() error {
|
|||
}
|
||||
g.SetViewOnTop("help")
|
||||
me.helpLabel = help
|
||||
|
||||
/*
|
||||
if me.treeRoot == nil {
|
||||
log.Info("gogui makeClock() error. treeRoot == nil")
|
||||
return nil
|
||||
} else {
|
||||
if me.clock.tk == nil {
|
||||
makeClock()
|
||||
me.clock.tk.MoveToOffset(maxX-10, 1)
|
||||
me.clock.tk.Hide()
|
||||
me.clock.tk.Show()
|
||||
}
|
||||
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 {
|
||||
makeOutputWidget(me.baseGui, "made this in showHelp()")
|
||||
msg := fmt.Sprintf("test to stdout from in showHelp() %d\n", me.ecount)
|
||||
me.stdout.Write([]byte(msg))
|
||||
log.Log(NOW, "log.log(NOW) test")
|
||||
}
|
||||
}
|
||||
*/
|
||||
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.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("attempting to locate stdout on screen for the first time")
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
482
init.go
482
init.go
|
@ -9,13 +9,9 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"runtime/pprof"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
|
@ -27,130 +23,49 @@ import (
|
|||
var VERSION string
|
||||
var BUILDTIME string
|
||||
|
||||
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 queueToolkitClose() {
|
||||
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()
|
||||
|
||||
func queueSetChecked(n *tree.Node, b bool) {
|
||||
setChecked(n, b)
|
||||
}
|
||||
|
||||
// sets defaults and establishes communication
|
||||
// to this toolkit from the wit/gui golang package
|
||||
func initPlugin() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
fmt.Fprintf(me.outf, "PANIC: initPlugin() recovered %v\n", r)
|
||||
return
|
||||
}
|
||||
}()
|
||||
func init() {
|
||||
log.Log(INFO, "Init() of awesome-gocui")
|
||||
|
||||
var err error
|
||||
// init the config struct default values
|
||||
Set(&me, "default")
|
||||
|
||||
// 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
|
||||
|
||||
me.mouse.mouseUp = true
|
||||
me.mouse.clicktime = time.Millisecond * 200
|
||||
me.mouse.doubletime = time.Millisecond * 400
|
||||
|
||||
me.myTree = tree.New()
|
||||
me.myTree.PluginName = "gocui"
|
||||
go refreshGocui()
|
||||
|
||||
// read in defaults from config protobuf
|
||||
if val, err := me.myTree.ConfigFind("stdout"); err == nil {
|
||||
if val == "true" {
|
||||
me.stdout.startOnscreen = true
|
||||
// me.stdout.Write([]byte("starting with stdout onscreen\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
|
||||
me.stdout.Write([]byte("starting with stdout onscreen\n"))
|
||||
} else {
|
||||
me.stdout.Write([]byte("starting with stdout offscreen\n"))
|
||||
}
|
||||
}
|
||||
if val, err := me.myTree.ConfigFind("dark"); err == nil {
|
||||
|
@ -163,159 +78,30 @@ func initPlugin() {
|
|||
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.myTree.NodeAction = newaction
|
||||
me.myTree.Add = newAdd
|
||||
me.myTree.SetTitle = newSetTitle
|
||||
me.myTree.SetLabel = newSetLabel
|
||||
me.myTree.SetText = newSetText
|
||||
me.myTree.AddText = newAddText
|
||||
me.myTree.SetChecked = queueSetChecked
|
||||
me.myTree.ToolkitClose = queueToolkitClose
|
||||
|
||||
me.newWindowTrigger = make(chan *guiWidget, 1)
|
||||
go newWindowTrigger()
|
||||
go refreshGocui()
|
||||
|
||||
log.Log(NOW, "Init() start pluginChan")
|
||||
if me.stdout.disable {
|
||||
log.Info("Using STDOUT")
|
||||
} else {
|
||||
log.Info("Using gocui STDOUT")
|
||||
os.Stdout = me.outf
|
||||
log.CaptureMode(me.outf)
|
||||
}
|
||||
|
||||
// init gocui
|
||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
||||
if err != nil {
|
||||
os.Exit(-1)
|
||||
return
|
||||
}
|
||||
me.baseGui = g
|
||||
g.Cursor = true
|
||||
g.Mouse = true
|
||||
|
||||
// this sets the function that is run on every event. For example:
|
||||
// When you click the mouse, move the mouse, or press a key on the keyboard
|
||||
// This is equivalent to xev or similar to cat /dev/input on linux
|
||||
g.SetManagerFunc(gocuiEvent)
|
||||
|
||||
// register how the 'gocui' will work as a GO toolkit plugin
|
||||
// all applications will use these keys. they are universal.
|
||||
// registered event handlers still have the events sent to gocuiEvent() above
|
||||
registerHandlers(g)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
if me.outf != nil {
|
||||
fmt.Fprintln(me.outf, "hello world", time.Since(me.starttime))
|
||||
}
|
||||
|
||||
// coreStdout()
|
||||
// createStdout(g)
|
||||
// tell 'tree' that we are okay to start talking to
|
||||
me.myTree.InitOK()
|
||||
me.ok = true // this tells init() it's okay to work with gocui
|
||||
|
||||
go gocuiMain()
|
||||
}
|
||||
|
||||
// This goroutine sits in gocui's MainLoop()
|
||||
func gocuiMain() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("PANIC ecovered in gocuiMain()", r)
|
||||
if me.outf == nil {
|
||||
debug.PrintStack()
|
||||
pprof.Lookup("goroutine").WriteTo(os.Stdout, 1)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
// me.stdout.Write([]byte("begin gogui.MainLoop()\n"))
|
||||
if err := me.baseGui.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Log(NOW, "g.MainLoop() panic err =", err)
|
||||
// normally panic here
|
||||
panic("gocuiTKmainloop OOPS")
|
||||
}
|
||||
// log.Sleep(.1) // probably not needed, but in here for now under development
|
||||
go mainGogui()
|
||||
// log.Sleep(.1) // probably not needed, but in here for now under development
|
||||
}
|
||||
|
||||
func standardExit() {
|
||||
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
||||
me.baseGui.Close()
|
||||
if me.outf != nil {
|
||||
log.Log(NOW, "standardExit() doing outf.Close()")
|
||||
me.outf.Close()
|
||||
os.Remove(me.outf.Name())
|
||||
}
|
||||
outf.Close()
|
||||
// log(true, "standardExit() setOutput(os.Stdout)")
|
||||
// setOutput(os.Stdout)
|
||||
log.Log(NOW, "standardExit() send back Quit()")
|
||||
|
@ -330,17 +116,109 @@ func standardClose() {
|
|||
log.Log(NOW, "standardExit() doing baseGui.Close()")
|
||||
me.baseGui.Close()
|
||||
log.Log(NOW, "standardExit() doing outf.Close()")
|
||||
me.outf.Close()
|
||||
os.Remove(me.outf.Name())
|
||||
outf.Close()
|
||||
// os.Stdin = os.Stdin
|
||||
// os.Stdout = os.Stdout
|
||||
// os.Stderr = os.Stderr
|
||||
log.Log(NOW, "standardExit() send back Quit()")
|
||||
}
|
||||
|
||||
var outf *os.File
|
||||
|
||||
func main() {
|
||||
}
|
||||
|
||||
var origStdout *os.File
|
||||
var origStderr *os.File
|
||||
|
||||
func mainGogui() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("YAHOOOO Recovered in guiMain application:", r)
|
||||
log.Warn("Recovered from panic:", r)
|
||||
me.baseGui.Close()
|
||||
log.CaptureMode(nil)
|
||||
log.Warn("YAHOOOO Recovered in guiMain application:", r)
|
||||
log.Warn("Recovered from panic:", r)
|
||||
me.myTree.SendToolkitPanic()
|
||||
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
var err error
|
||||
|
||||
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)
|
||||
}
|
||||
origStdout = os.Stdout
|
||||
os.Stdout = outf
|
||||
defer outf.Close()
|
||||
|
||||
log.CaptureMode(outf)
|
||||
|
||||
gocuiMain()
|
||||
}
|
||||
|
||||
// This initializes the gocui package
|
||||
// it runs SetManagerFunc which passes every input
|
||||
// event (keyboard, mouse, etc) to the function "gocuiEvent()"
|
||||
func gocuiMain() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Warn("YAHOOOO Recovered in gocuiMain()", r)
|
||||
log.Warn("Recovered from panic:", r)
|
||||
me.baseGui.Close()
|
||||
|
||||
// allow gocui to close if possible, then print stack
|
||||
log.Sleep(1)
|
||||
os.Stdout = origStdout
|
||||
os.Stderr = origStderr
|
||||
me.myTree.SendToolkitPanic()
|
||||
log.Warn("Stack trace:")
|
||||
debug.PrintStack()
|
||||
// panic("BUMMER 2")
|
||||
|
||||
// attempt to switch to the nocui toolkit
|
||||
log.Sleep(1)
|
||||
me.myTree.SendToolkitLoad("nocui")
|
||||
log.Sleep(3)
|
||||
me.myTree.SendToolkitLoad("nocui")
|
||||
// panic("BUMMER")
|
||||
return
|
||||
}
|
||||
}()
|
||||
g, err := gocui.NewGui(gocui.OutputNormal, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
defer g.Close()
|
||||
|
||||
me.baseGui = g
|
||||
|
||||
g.Cursor = true
|
||||
g.Mouse = true
|
||||
|
||||
// this sets the function that is run on every event. For example:
|
||||
// When you click the mouse, move the mouse, or press a key on the keyboard
|
||||
// This is equivalent to xev or similar to cat /dev/input on linux
|
||||
g.SetManagerFunc(gocuiEvent)
|
||||
|
||||
// register how the 'gocui' will work as a GO toolkit plugin
|
||||
// all applications will use these keys. they are universal.
|
||||
// registered event handlers still have the events sent to gocuiEvent() above
|
||||
registerHandlers(g)
|
||||
|
||||
me.stdout.Write([]byte("begin gogui.MainLoop()\n"))
|
||||
if err := g.MainLoop(); err != nil && !errors.Is(err, gocui.ErrQuit) {
|
||||
log.Log(NOW, "g.MainLoop() panic err =", err)
|
||||
// normally panic here
|
||||
panic("gocuiTKmainloop OOPS")
|
||||
}
|
||||
}
|
||||
|
||||
// this hack is to wait for the application to send something
|
||||
// before trying to do anything. todo: rethink this someday
|
||||
func waitOK() {
|
||||
|
@ -352,17 +230,6 @@ func waitOK() {
|
|||
}
|
||||
}
|
||||
|
||||
// this hack is to wait for the application to send something
|
||||
// before trying to do anything. todo: rethink this someday
|
||||
func waitFirstWindow() {
|
||||
for {
|
||||
if me.firstWindowOk {
|
||||
return
|
||||
}
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// empty function. this triggers gocui to refresh the screen
|
||||
func testRefresh(*gocui.Gui) error {
|
||||
// log.Info("in testRefresh")
|
||||
|
@ -371,94 +238,59 @@ func testRefresh(*gocui.Gui) error {
|
|||
|
||||
// refresh the screen 10 times a second
|
||||
func refreshGocui() {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
if me.outf == nil {
|
||||
log.Info("INIT PLUGIN recovered in r", r)
|
||||
} else {
|
||||
fmt.Fprintln(me.outf, "INIT PLUGIN recovered in r", r)
|
||||
}
|
||||
return
|
||||
}
|
||||
}()
|
||||
var lastRefresh time.Time
|
||||
lastRefresh = time.Now()
|
||||
me.refresh = false
|
||||
for {
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
// log.Info("refresh checking ok")
|
||||
if !me.ok {
|
||||
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 {
|
||||
// artificially pause clock while dragging.
|
||||
// this is a reminder to make this refresh code smarter
|
||||
// after the switch to protocol buffers
|
||||
me.myTree.Lock()
|
||||
if me.mouse.mouseUp {
|
||||
// log.Info("refresh now on mouseUp")
|
||||
// todo: add logic here to see if the application has changed anything
|
||||
libNotifyUpdate()
|
||||
lastRefresh = time.Now()
|
||||
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)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if time.Since(lastRefresh) > 3*time.Second {
|
||||
libNotifyUpdate()
|
||||
// log.Info("refresh skip on mouseDown")
|
||||
// me.baseGui.Update()
|
||||
}
|
||||
lastRefresh = time.Now()
|
||||
}
|
||||
}
|
||||
me.myTree.Unlock()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set the widget start width & height
|
||||
|
||||
func newWindowTrigger() {
|
||||
// log.Log(NOW, "newWindowTriggerl() START")
|
||||
log.Log(NOW, "newWindowTriggerl() START")
|
||||
for {
|
||||
// log.Log(NOW, "GO plugin toolkit made a new window")
|
||||
select {
|
||||
case tk := <-me.newWindowTrigger:
|
||||
// log.Log(NOW, "newWindowTrigger() got new window", tk.cuiName)
|
||||
// time.Sleep(200 * time.Millisecond)
|
||||
time.Sleep(200 * time.Millisecond)
|
||||
waitOK()
|
||||
me.myTree.Lock()
|
||||
// time.Sleep(200 * time.Millisecond)
|
||||
redoWindows(me.FirstWindowW, me.FirstWindowH)
|
||||
me.firstWindowOk = true
|
||||
redoWindows(1, -1)
|
||||
if !me.stdout.init {
|
||||
me.stdout.init = true
|
||||
relocateStdoutOffscreen()
|
||||
}
|
||||
if me.textbox.tk == nil {
|
||||
initTextbox()
|
||||
}
|
||||
tk.makeWindowActive()
|
||||
me.myTree.Unlock()
|
||||
// place the new window relative to the mouse
|
||||
tk.redrawWindow(me.mouse.downW+8, me.mouse.downH-2)
|
||||
// tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
// log.Log(NOW, "newWindowTrigger() after sleep")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
295
libnotify.go
295
libnotify.go
|
@ -1,295 +0,0 @@
|
|||
// 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()
|
||||
}
|
63
node.go
63
node.go
|
@ -1,63 +0,0 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) WidgetType() widget.WidgetType {
|
||||
if tk.node == nil {
|
||||
return widget.Label
|
||||
}
|
||||
return tk.node.WidgetType
|
||||
}
|
||||
|
||||
func (tk *guiWidget) WidgetId() int {
|
||||
return tk.node.WidgetId
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GetLabel() string {
|
||||
return tk.node.GetLabel()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) IsEnabled() bool {
|
||||
return tk.node.IsEnabled()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Checked() bool {
|
||||
return tk.node.State.Checked
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Hidden() bool {
|
||||
if tk.node == nil {
|
||||
return false
|
||||
}
|
||||
if tk.parent == nil {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.WidgetId() == 0 {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.Hidden() {
|
||||
return true
|
||||
}
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Direction() widget.Orientation {
|
||||
return tk.node.State.Direction
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GridW() int {
|
||||
return tk.node.State.AtW
|
||||
}
|
||||
|
||||
func (tk *guiWidget) GridH() int {
|
||||
return tk.node.State.AtH
|
||||
}
|
||||
|
||||
func (tk *guiWidget) SetChecked(b bool) {
|
||||
tk.node.State.Checked = b
|
||||
}
|
62
place.go
62
place.go
|
@ -34,7 +34,7 @@ func (tk *guiWidget) Position() (int, int) {
|
|||
}
|
||||
|
||||
func (w *guiWidget) placeBox(startW int, startH int) {
|
||||
if w.WidgetType() != widget.Box {
|
||||
if w.node.WidgetType != widget.Box {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -50,7 +50,7 @@ func (w *guiWidget) placeBox(startW int, startH int) {
|
|||
// re-get the Size (they should not have changed, but maybe they can?)
|
||||
// TODO: figure this out or report that they did
|
||||
sizeW, sizeH = child.Size()
|
||||
if w.Direction() == widget.Vertical {
|
||||
if w.node.State.Direction == widget.Vertical {
|
||||
log.Log(INFO, "BOX IS VERTICAL ", w.String(), "newWH()", newW, newH, "child()", sizeW, sizeH, child.String())
|
||||
// expand based on the child height
|
||||
newH += sizeH
|
||||
|
@ -77,7 +77,7 @@ func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
|||
tk.startW = startW
|
||||
tk.startH = startH
|
||||
|
||||
switch tk.WidgetType() {
|
||||
switch tk.node.WidgetType {
|
||||
case widget.Window:
|
||||
tk.full.w0 = startW
|
||||
tk.full.h0 = startH
|
||||
|
@ -143,17 +143,11 @@ func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
|||
// tk.dumpWidget(fmt.Sprintf("PlaceGroup(%d,%d)", maxW, newH))
|
||||
return maxW, newH
|
||||
case widget.Button:
|
||||
if tk.isDense() && tk.isInGrid() {
|
||||
if tk.isWindowDense() && tk.isInGrid() {
|
||||
tk.frame = false
|
||||
// tk.color = nil
|
||||
// tk.defaultColor = nil
|
||||
/*
|
||||
if tk.IsEnabled() {
|
||||
tk.color = nil
|
||||
tk.defaultColor = nil
|
||||
tk.setColorButtonDense()
|
||||
} else {
|
||||
tk.setColorDisable()
|
||||
}
|
||||
*/
|
||||
// if tk.full.Height() > 0 {
|
||||
tk.full.h1 = tk.full.h0
|
||||
// }
|
||||
|
@ -167,16 +161,8 @@ func (tk *guiWidget) placeWidgets(startW int, startH int) (int, int) {
|
|||
return 0, 0
|
||||
}
|
||||
|
||||
func (tk *guiWidget) isDense() bool {
|
||||
if tk.node.InTable() {
|
||||
return true
|
||||
}
|
||||
|
||||
return tk.isWindowDense()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) isWindowDense() bool {
|
||||
if tk.WidgetType() == widget.Window {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
return tk.window.dense
|
||||
}
|
||||
if tk.parent == nil {
|
||||
|
@ -186,7 +172,7 @@ func (tk *guiWidget) isWindowDense() bool {
|
|||
}
|
||||
|
||||
func (tk *guiWidget) isInGrid() bool {
|
||||
if tk.WidgetType() == widget.Grid {
|
||||
if tk.node.WidgetType == widget.Grid {
|
||||
return true
|
||||
}
|
||||
if tk.parent == nil {
|
||||
|
@ -197,10 +183,12 @@ func (tk *guiWidget) isInGrid() bool {
|
|||
|
||||
func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
||||
// w.showWidgetPlacement("grid0:")
|
||||
if w.WidgetType() != widget.Grid {
|
||||
if w.node.WidgetType != widget.Grid {
|
||||
return 0, 0
|
||||
}
|
||||
|
||||
dense := w.isWindowDense()
|
||||
|
||||
w.full.w0 = startW
|
||||
w.full.h0 = startH
|
||||
|
||||
|
@ -209,22 +197,22 @@ func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
|||
childW, childH := child.placeWidgets(child.startW, child.startH)
|
||||
|
||||
// set the child's realWidth, and grid offset
|
||||
if w.widths[child.GridW()] < childW {
|
||||
w.widths[child.GridW()] = childW
|
||||
if w.widths[child.node.State.AtW] < childW {
|
||||
w.widths[child.node.State.AtW] = childW
|
||||
}
|
||||
if w.heights[child.GridH()] < childH {
|
||||
w.heights[child.GridH()] = childH
|
||||
if w.heights[child.node.State.AtH] < childH {
|
||||
w.heights[child.node.State.AtH] = childH
|
||||
}
|
||||
if child.isDense() {
|
||||
if w.heights[child.GridH()] > 0 {
|
||||
w.heights[child.GridH()] = 1
|
||||
if dense {
|
||||
if w.heights[child.node.State.AtH] > 0 {
|
||||
w.heights[child.node.State.AtH] = 1
|
||||
} else {
|
||||
w.heights[child.GridH()] = 0
|
||||
w.heights[child.node.State.AtH] = 0
|
||||
}
|
||||
}
|
||||
|
||||
// child.showWidgetPlacement("grid: ")
|
||||
log.Log(INFO, "placeGrid:", child.String(), "child()", childW, childH, "At()", child.GridW(), child.GridH())
|
||||
log.Log(INFO, "placeGrid:", child.String(), "child()", childW, childH, "At()", child.node.State.AtW, child.node.State.AtH)
|
||||
}
|
||||
|
||||
var maxW int = 0
|
||||
|
@ -236,12 +224,12 @@ func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
|||
|
||||
var totalW, totalH int
|
||||
for i, w := range w.widths {
|
||||
if i < child.GridW() {
|
||||
if i < child.node.State.AtW {
|
||||
totalW += w
|
||||
}
|
||||
}
|
||||
for i, h := range w.heights {
|
||||
if i < child.GridH() {
|
||||
if i < child.node.State.AtH {
|
||||
totalH += h
|
||||
}
|
||||
}
|
||||
|
@ -257,7 +245,7 @@ func (w *guiWidget) placeGrid(startW int, startH int) (int, int) {
|
|||
maxH = totalH
|
||||
}
|
||||
|
||||
log.Log(INFO, "placeGrid:", child.String(), "new()", newW, newH, "At()", child.GridW(), child.GridH())
|
||||
log.Log(INFO, "placeGrid:", child.String(), "new()", newW, newH, "At()", child.node.State.AtW, child.node.State.AtH)
|
||||
child.placeWidgets(newW, newH)
|
||||
// child.showWidgetPlacement("grid2:")
|
||||
}
|
||||
|
@ -326,8 +314,8 @@ func textSize(n *tree.Node) (int, int) {
|
|||
*/
|
||||
|
||||
func (tk *guiWidget) gocuiSetWH(sizeW, sizeH int) {
|
||||
w := len(tk.GetLabel())
|
||||
lines := strings.Split(tk.GetLabel(), "\n")
|
||||
w := len(tk.node.GetLabel())
|
||||
lines := strings.Split(tk.node.GetLabel(), "\n")
|
||||
h := len(lines)
|
||||
|
||||
if tk.Hidden() {
|
||||
|
|
170
plugin.go
170
plugin.go
|
@ -4,7 +4,8 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/awesome-gocui/gocui"
|
||||
// if you include more than just this import
|
||||
// then your plugin might be doing something un-ideal (just a guess from 2023/02/27)
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
|
@ -16,7 +17,7 @@ func newAdd(n *tree.Node) {
|
|||
return
|
||||
}
|
||||
if n.TK != nil {
|
||||
log.Log(INFO, "Tree Add() sent a widget we aleady seem to have")
|
||||
log.Warn("Tree Add() sent a widget we aleady seem to have")
|
||||
// this is done to protect the plugin being 'refreshed' with the
|
||||
// widget binary tree. TODO: find a way to keep them in sync
|
||||
return
|
||||
|
@ -34,26 +35,24 @@ func newAdd(n *tree.Node) {
|
|||
w = n.TK.(*guiWidget)
|
||||
}
|
||||
*/
|
||||
// w.setColor(&colorDisabled)
|
||||
w := n.TK.(*guiWidget)
|
||||
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
|
||||
func setTitle(n *tree.Node, s string) {
|
||||
setText(n, s)
|
||||
me.refresh = true // testing code to see if refresh can work
|
||||
func newSetTitle(n *tree.Node, s string) {
|
||||
newSetText(n, s)
|
||||
}
|
||||
|
||||
func setLabel(n *tree.Node, s string) {
|
||||
setText(n, s)
|
||||
me.refresh = true // testing code to see if refresh can work
|
||||
func newSetLabel(n *tree.Node, s string) {
|
||||
newSetText(n, s)
|
||||
}
|
||||
|
||||
// setText() and addText() are simple. They take the event sent
|
||||
// newSetText() and newAddText() are simple. They take the event sent
|
||||
// to the GO plugin from the application and lookup the plugin structure
|
||||
// then pass that event to gocui. This is the transfer point
|
||||
func setText(n *tree.Node, s string) {
|
||||
func newSetText(n *tree.Node, s string) {
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
return
|
||||
|
@ -64,10 +63,9 @@ func setText(n *tree.Node, s string) {
|
|||
}
|
||||
w := n.TK.(*guiWidget)
|
||||
w.SetText(s)
|
||||
me.refresh = true // testing code to see if refresh can work
|
||||
}
|
||||
|
||||
func addText(n *tree.Node, s string) {
|
||||
func newAddText(n *tree.Node, s string) {
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
return
|
||||
|
@ -78,7 +76,61 @@ func addText(n *tree.Node, s string) {
|
|||
}
|
||||
w := n.TK.(*guiWidget)
|
||||
w.AddText(s)
|
||||
me.refresh = true // testing code to see if refresh can work
|
||||
}
|
||||
|
||||
func newaction(n *tree.Node, atype widget.ActionType) {
|
||||
log.Log(INFO, "newaction() START", atype)
|
||||
if !me.ok {
|
||||
log.Log(INFO, "newaction() START NOT OKAY", atype)
|
||||
log.Log(INFO, "newaction() START NOT OKAY", atype)
|
||||
log.Log(INFO, "newaction() START NOT OKAY", atype)
|
||||
waitOK()
|
||||
}
|
||||
if n == nil {
|
||||
log.Warn("Tree Error: Add() sent n == nil")
|
||||
return
|
||||
}
|
||||
if n.TK == nil {
|
||||
log.Warn("Tree sent an action on a widget we didn't seem to have.")
|
||||
// do this init here again? Probably something
|
||||
// went wrong and we should reset the our while gocui.View tree
|
||||
n.TK = initWidget(n)
|
||||
}
|
||||
w := n.TK.(*guiWidget)
|
||||
switch atype {
|
||||
case widget.Show:
|
||||
w.Show()
|
||||
case widget.Hide:
|
||||
if n.Hidden() {
|
||||
// already hidden
|
||||
} else {
|
||||
log.Log(NOW, "attempt to hide() =", atype, n.WidgetId, n.WidgetType, n.ProgName())
|
||||
w.node.State.Hidden = true
|
||||
w.Hide()
|
||||
}
|
||||
case widget.Move:
|
||||
log.Log(NOW, "attempt to move() =", atype, n.WidgetType, n.ProgName())
|
||||
case widget.ToolkitClose:
|
||||
log.Log(NOW, "attempting to close the plugin and release stdout and stderr")
|
||||
standardClose()
|
||||
case widget.Enable:
|
||||
w.enable = true
|
||||
w.enableColor()
|
||||
case widget.Disable:
|
||||
w.enable = false
|
||||
w.disableColor()
|
||||
case widget.Delete:
|
||||
if w == nil {
|
||||
return
|
||||
} else {
|
||||
w.hideWidgets()
|
||||
w.deleteNode()
|
||||
}
|
||||
n.DeleteNode()
|
||||
default:
|
||||
log.Log(ERROR, "newaction() UNHANDLED Action Type =", atype, "WidgetType =", n.WidgetType, "Name =", n.ProgName())
|
||||
}
|
||||
log.Log(INFO, "newaction() END", atype, n.String())
|
||||
}
|
||||
|
||||
func (w *guiWidget) deleteGocuiViews() {
|
||||
|
@ -116,7 +168,7 @@ func (w *guiWidget) AddText(text string) {
|
|||
}
|
||||
w.vals = append(w.vals, text)
|
||||
for i, s := range w.vals {
|
||||
log.Log(INFO, "AddText()", w.String(), i, s)
|
||||
log.Log(NOW, "AddText()", w.String(), i, s)
|
||||
}
|
||||
w.SetText(text)
|
||||
}
|
||||
|
@ -156,92 +208,8 @@ func (tk *guiWidget) GetText() string {
|
|||
// return gocui.view name?
|
||||
return tk.cuiName
|
||||
}
|
||||
if tk.GetLabel() != "" {
|
||||
return tk.GetLabel()
|
||||
if tk.node.State.Label != "" {
|
||||
return tk.node.State.Label
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// hack. use "textbox widget" to "disable" user events
|
||||
func hideDisable() {
|
||||
if me.textbox.tk == nil {
|
||||
initTextbox()
|
||||
}
|
||||
|
||||
me.textbox.tk.Hide()
|
||||
me.textbox.tk.enable = false
|
||||
me.textbox.tk.node.State.Enable = false
|
||||
me.textbox.active = false
|
||||
me.baseGui.SetCurrentView("help")
|
||||
// me.baseGui.DeleteView(me.textbox.tk.cuiName)
|
||||
// me.baseGui.DeleteView(me.textbox.tk.v.Name())
|
||||
}
|
||||
|
||||
// hack. use "textbox widget" to "disable" user events
|
||||
func showDisable() {
|
||||
if me.textbox.tk == nil {
|
||||
initTextbox()
|
||||
me.textbox.tk.prepTextbox()
|
||||
}
|
||||
r := new(rectType)
|
||||
r.w0 = 2
|
||||
r.h0 = 1
|
||||
r.w1 = r.w0 + 24
|
||||
r.h1 = r.h0 + 2
|
||||
me.textbox.tk.forceSizes(r)
|
||||
me.textbox.tk.Show() // actually makes the gocui view. TODO: redo this
|
||||
// log.Info("textbox should be shown")
|
||||
// showTextbox("Running...")
|
||||
// me.textbox.tk.dumpWidget("shown?")
|
||||
|
||||
me.textbox.tk.setColorModal()
|
||||
me.textbox.tk.v.Clear()
|
||||
me.textbox.tk.v.WriteString("Running...")
|
||||
|
||||
me.textbox.tk.v.Editable = true
|
||||
me.textbox.tk.v.Wrap = true
|
||||
|
||||
me.textbox.tk.SetViewRect(r)
|
||||
me.baseGui.SetCurrentView(me.textbox.tk.v.Name())
|
||||
|
||||
// bind the enter key to a function so we can close the textbox
|
||||
me.baseGui.SetKeybinding(me.textbox.tk.v.Name(), gocui.KeyEnter, gocui.ModNone, theCloseTheTextbox)
|
||||
|
||||
me.textbox.active = true
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Disable() {
|
||||
if tk == nil {
|
||||
log.Log(NOW, "widget is nil")
|
||||
return
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
case widget.Box:
|
||||
showDisable()
|
||||
return
|
||||
case widget.Button:
|
||||
tk.setColorDisable()
|
||||
return
|
||||
default:
|
||||
tk.dumpWidget("fixme: disable")
|
||||
}
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Enable() {
|
||||
if tk == nil {
|
||||
log.Log(NOW, "widget is nil")
|
||||
return
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
case widget.Box:
|
||||
hideDisable()
|
||||
return
|
||||
case widget.Button:
|
||||
tk.restoreEnableColor()
|
||||
return
|
||||
default:
|
||||
tk.dumpWidget("fixme: enable")
|
||||
}
|
||||
}
|
||||
|
|
45
size.go
45
size.go
|
@ -9,6 +9,19 @@ import (
|
|||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) Hidden() bool {
|
||||
if tk.parent == nil {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.node.WidgetId == 0 {
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
if tk.parent.Hidden() {
|
||||
return true
|
||||
}
|
||||
return tk.node.Hidden()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) Size() (int, int) {
|
||||
if tk == nil {
|
||||
return 0, 0
|
||||
|
@ -22,7 +35,7 @@ func (tk *guiWidget) Size() (int, int) {
|
|||
return 0, 0
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
switch tk.node.WidgetType {
|
||||
case widget.Window:
|
||||
var maxH int = 0
|
||||
var maxW int = 0
|
||||
|
@ -63,11 +76,11 @@ func (tk *guiWidget) Size() (int, int) {
|
|||
case widget.Label:
|
||||
return len(tk.String()) + 2, 1
|
||||
case widget.Textbox:
|
||||
return len(tk.String()) + 10, 3 // TODO: compute this based on 'window dense'
|
||||
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
||||
case widget.Checkbox:
|
||||
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
||||
case widget.Button:
|
||||
if tk.isDense() {
|
||||
if tk.isWindowDense() {
|
||||
return len(tk.String()) + 2, 0
|
||||
}
|
||||
return len(tk.String()) + 2, 3 // TODO: compute this based on 'window dense'
|
||||
|
@ -91,11 +104,11 @@ func (w *guiWidget) sizeGrid() (int, int) {
|
|||
sizeW, sizeH := child.Size()
|
||||
|
||||
// set the child's realWidth, and grid offset
|
||||
if w.widths[child.GridW()] < sizeW {
|
||||
w.widths[child.GridW()] = sizeW
|
||||
if w.widths[child.node.State.AtW] < sizeW {
|
||||
w.widths[child.node.State.AtW] = sizeW
|
||||
}
|
||||
if w.heights[child.GridH()] < sizeH {
|
||||
w.heights[child.GridH()] = sizeH
|
||||
if w.heights[child.node.State.AtH] < sizeH {
|
||||
w.heights[child.node.State.AtH] = sizeH
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -112,7 +125,7 @@ func (w *guiWidget) sizeGrid() (int, int) {
|
|||
}
|
||||
|
||||
func (w *guiWidget) sizeBox() (int, int) {
|
||||
if w.WidgetType() != widget.Box {
|
||||
if w.node.WidgetType != widget.Box {
|
||||
return 0, 0
|
||||
}
|
||||
if w.Hidden() {
|
||||
|
@ -126,7 +139,7 @@ func (w *guiWidget) sizeBox() (int, int) {
|
|||
continue
|
||||
}
|
||||
sizeW, sizeH := child.Size()
|
||||
if child.Direction() == widget.Vertical {
|
||||
if child.node.State.Direction == widget.Vertical {
|
||||
maxW += sizeW
|
||||
if sizeH > maxH {
|
||||
maxH = sizeH
|
||||
|
@ -241,10 +254,10 @@ func (tk *guiWidget) setFullSize() bool {
|
|||
tk.full.h1 = r.h1
|
||||
changed = true
|
||||
}
|
||||
if tk.WidgetType() == widget.Button {
|
||||
if tk.node.WidgetType == widget.Button {
|
||||
tk.full.h1 = tk.full.h0 + 1
|
||||
}
|
||||
if tk.isDense() && tk.isInGrid() {
|
||||
if tk.isWindowDense() && tk.isInGrid() {
|
||||
tk.full.h1 = tk.full.h0
|
||||
}
|
||||
if changed {
|
||||
|
@ -309,7 +322,7 @@ func (tk *guiWidget) buttonFullSize() rectType {
|
|||
tk.full.h1 = r.h1
|
||||
|
||||
// total hack. fix this somewhere eventually correctly
|
||||
if tk.isDense() { // total hack. fix this somewhere eventually correctly
|
||||
if tk.isWindowDense() { // 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
|
||||
}
|
||||
|
@ -337,13 +350,13 @@ func (tk *guiWidget) getFullSize() rectType {
|
|||
return r
|
||||
}
|
||||
|
||||
if tk.WidgetType() == widget.Grid {
|
||||
if tk.node.WidgetType == widget.Grid {
|
||||
return tk.gridFullSize()
|
||||
}
|
||||
|
||||
// these are 'simple' widgets
|
||||
// the full size is exactly what gocui uses
|
||||
switch tk.WidgetType() {
|
||||
switch tk.node.WidgetType {
|
||||
case widget.Label:
|
||||
r := tk.buttonFullSize()
|
||||
r.w1 += 5
|
||||
|
@ -355,9 +368,7 @@ func (tk *guiWidget) getFullSize() rectType {
|
|||
case widget.Checkbox:
|
||||
return tk.buttonFullSize()
|
||||
case widget.Dropdown:
|
||||
r := tk.buttonFullSize()
|
||||
r.w1 += 7 // TODO: fix this to be real
|
||||
return r
|
||||
return tk.buttonFullSize()
|
||||
default:
|
||||
}
|
||||
|
||||
|
|
144
stdoutShow.go
144
stdoutShow.go
|
@ -4,6 +4,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
|
@ -17,24 +18,21 @@ import (
|
|||
func createStdout(g *gocui.Gui) bool {
|
||||
if me.stdout.tk == nil {
|
||||
makeOutputWidget(g, "this is a create before a mouse click")
|
||||
// me.logStdout.v.Write([]byte(msg))
|
||||
|
||||
// this will show very early debugging output
|
||||
// keep this code commented out but do not remove it. when it doubt, this will be the Light of Elendil
|
||||
// NEVER REMOVE THIS CODE
|
||||
|
||||
msg := fmt.Sprintf("test out gocuiEvent() %d\n", me.ecount)
|
||||
// me.logStdout.v.Write([]byte(msg))
|
||||
me.stdout.tk.Write([]byte(msg))
|
||||
|
||||
log.Log(NOW, "logStdout test out")
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func coreStdout() {
|
||||
if me.stdout.tk != nil {
|
||||
return
|
||||
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||
if me.treeRoot == nil {
|
||||
// keep skipping this until the binary tree is initialized
|
||||
return nil
|
||||
}
|
||||
|
||||
if me.stdout.tk == nil {
|
||||
a := new(widget.Action)
|
||||
a.ProgName = "2stdout2"
|
||||
a.WidgetType = widget.Stdout
|
||||
|
@ -45,37 +43,38 @@ func coreStdout() {
|
|||
me.stdout.tk = initWidget(n)
|
||||
|
||||
tk := me.stdout.tk
|
||||
tk.cuiName = "msg"
|
||||
tk.gocuiSize.w0 = me.stdout.lastW
|
||||
tk.gocuiSize.h0 = me.stdout.lastH
|
||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + me.stdout.w
|
||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + me.stdout.h
|
||||
}
|
||||
|
||||
func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
||||
if me.treeRoot == nil {
|
||||
// keep skipping this until the binary tree is initialized
|
||||
return nil
|
||||
}
|
||||
|
||||
coreStdout()
|
||||
|
||||
if me.stdout.tk == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
me.stdout.tk.cuiName = "msg"
|
||||
me.stdout.tk.SetView()
|
||||
|
||||
v, err := g.View("msg")
|
||||
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 {
|
||||
log.Log(NOW, "makeoutputwindow() msg != nil. WTF now? err =", err)
|
||||
return v
|
||||
}
|
||||
|
||||
v = me.stdout.tk.v
|
||||
rect := me.stdout.tk.gocuiSize
|
||||
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.SelBgColor = gocui.ColorCyan
|
||||
|
@ -84,8 +83,16 @@ func makeOutputWidget(g *gocui.Gui, stringFromMouseClick string) *gocui.View {
|
|||
// g.SetViewOnBottom("msg")
|
||||
// setBottomBG()
|
||||
|
||||
me.stdout.tk.v = v
|
||||
me.stdout.tk.DrawAt(me.stdout.lastW, me.stdout.lastH)
|
||||
relocateStdoutOffscreen()
|
||||
/*
|
||||
if me.stdout.outputOffscreen {
|
||||
me.stdout.tk.relocateStdout(me.stdout.lastW, me.stdout.lastH)
|
||||
} else {
|
||||
relocateStdoutOffscreen()
|
||||
}
|
||||
*/
|
||||
return v
|
||||
}
|
||||
|
||||
|
@ -93,32 +100,14 @@ func relocateStdoutOffscreen() {
|
|||
if me.stdout.tk == nil {
|
||||
return
|
||||
}
|
||||
if !me.stdout.disable {
|
||||
log.Info("Using gocui STDOUT")
|
||||
log.CaptureMode(me.stdout.tk)
|
||||
}
|
||||
// log.Log(ERROR, "setting log.CaptureMode(tk.v) in relocateStdoutOffscreen()")
|
||||
newW := 10
|
||||
newH := 0 - me.stdout.h - 4
|
||||
me.stdout.tk.relocateStdout(newW, newH)
|
||||
}
|
||||
|
||||
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
|
||||
h0 := h
|
||||
w1 := w + me.stdout.w
|
||||
|
@ -134,7 +123,8 @@ func (tk *guiWidget) relocateStdout(w int, h int) {
|
|||
tk.full.h0 = h0
|
||||
tk.full.h1 = h1
|
||||
|
||||
tk.SetView()
|
||||
me.baseGui.SetView("msg", w0, h0, w1, h1, 0)
|
||||
// me.baseGui.SetViewOnBottom("msg")
|
||||
}
|
||||
|
||||
// from the gocui devs:
|
||||
|
@ -143,40 +133,22 @@ func (tk *guiWidget) relocateStdout(w int, h int) {
|
|||
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
|
||||
// be called to clear the view's buffer.
|
||||
|
||||
func (w stdout) Height() int {
|
||||
if w.tk == nil {
|
||||
return 40
|
||||
}
|
||||
return w.tk.gocuiSize.Height() - 2
|
||||
}
|
||||
|
||||
func (w stdout) Write(p []byte) (n int, err error) {
|
||||
me.writeMutex.Lock()
|
||||
defer me.writeMutex.Unlock()
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
||||
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
||||
if me.outf != nil {
|
||||
fmt.Fprint(me.outf, string(p))
|
||||
}
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (w *guiWidget) Write(p []byte) (n int, err error) {
|
||||
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...)
|
||||
return len(p), nil
|
||||
}
|
||||
w.tainted = true
|
||||
me.writeMutex.Lock()
|
||||
defer me.writeMutex.Unlock()
|
||||
|
||||
lines := strings.Split(strings.TrimSpace(string(p)), "\n")
|
||||
me.stdout.outputS = append(me.stdout.outputS, lines...)
|
||||
|
||||
tk := me.stdout.tk
|
||||
|
@ -184,14 +156,43 @@ func (w *guiWidget) Write(p []byte) (n int, err error) {
|
|||
return len(p), nil
|
||||
}
|
||||
if tk.v == nil {
|
||||
// redo this old code
|
||||
v, _ := me.baseGui.View("msg")
|
||||
if v != nil {
|
||||
// fmt.Fprintln(outf, "found msg")
|
||||
tk.v = v
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
tk.refreshStdout()
|
||||
/*
|
||||
// optionally write the output to /tmp
|
||||
s := fmt.Sprint(string(p))
|
||||
s = strings.TrimSuffix(s, "\n")
|
||||
fmt.Fprintln(outf, s)
|
||||
v, _ := me.baseGui.View("msg")
|
||||
if v != nil {
|
||||
// fmt.Fprintln(outf, "found msg")
|
||||
tk.v = v
|
||||
}
|
||||
} else {
|
||||
// display the output in the gocui window
|
||||
var cur []string
|
||||
// chop off the last lines in the buffer
|
||||
chop := len(me.stdout.outputS) - (me.stdout.h - 1)
|
||||
if chop < 0 {
|
||||
chop = 0
|
||||
}
|
||||
if len(me.stdout.outputS) > chop {
|
||||
cur = append(cur, me.stdout.outputS[chop:]...)
|
||||
} else {
|
||||
cur = append(cur, me.stdout.outputS...)
|
||||
}
|
||||
slices.Reverse(cur)
|
||||
tk.v.Clear()
|
||||
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
||||
}
|
||||
*/
|
||||
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
|
@ -199,11 +200,6 @@ func (w *guiWidget) Write(p []byte) (n int, err error) {
|
|||
func (tk *guiWidget) refreshStdout() {
|
||||
if len(me.stdout.outputS) < me.stdout.h+me.stdout.pager {
|
||||
// log.Info(fmt.Sprintf("buffer too small=%d len(%d)", me.stdout.pager, len(me.stdout.outputS)))
|
||||
var cur []string
|
||||
cur = append(cur, me.stdout.outputS...)
|
||||
slices.Reverse(cur)
|
||||
tk.v.Clear()
|
||||
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -211,9 +207,7 @@ func (tk *guiWidget) refreshStdout() {
|
|||
// chop off the last lines in the buffer
|
||||
chop := len(me.stdout.outputS) - (me.stdout.pager + me.stdout.h)
|
||||
cur = append(cur, me.stdout.outputS[chop:chop+me.stdout.h]...)
|
||||
if me.stdout.reverse {
|
||||
slices.Reverse(cur)
|
||||
}
|
||||
tk.v.Clear()
|
||||
fmt.Fprintln(tk.v, strings.Join(cur, "\n"))
|
||||
}
|
||||
|
|
57
structs.go
57
structs.go
|
@ -10,7 +10,6 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
|
@ -18,14 +17,10 @@ import (
|
|||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
|
||||
"go.wit.com/lib/protobuf/guipb"
|
||||
log "go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
var initOnce sync.Once // run initPlugin() only once
|
||||
|
||||
// It's probably a terrible idea to call this 'me'
|
||||
// 2025 note: doesn't seem terrible to call this 'me' anymore. notsure.
|
||||
var me config
|
||||
|
@ -39,13 +34,9 @@ type config struct {
|
|||
myTree *tree.TreeInfo // ?
|
||||
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
|
||||
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
|
||||
helpLabel *gocui.View // ?
|
||||
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
|
||||
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
|
||||
|
@ -62,7 +53,6 @@ type config struct {
|
|||
RawW int `default:"1"` // the raw beginning of each window (or tab)
|
||||
RawH int `default:"5"` // the raw beginning of each window (or tab)
|
||||
FakeW int `default:"20"` // offset for the hidden widgets
|
||||
DropdownId int `default:"-78"` // the widget id to use
|
||||
padded bool // add space between things like buttons
|
||||
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
|
||||
canvas bool // if set to true, the windows are a raw canvas
|
||||
|
@ -77,17 +67,11 @@ type config struct {
|
|||
stdout stdout // information for the STDOUT window
|
||||
dropdown dropdown // the dropdown menu
|
||||
textbox dropdown // the textbox popup window
|
||||
BG dropdown // the background widget
|
||||
notify libnotify // emulates the desktop libnotify menu
|
||||
clock dropdown // the textbox popup window
|
||||
allwin []*guiWidget // for tracking which window is next
|
||||
dark bool // use a 'dark' color palette
|
||||
mouse mouse // mouse settings
|
||||
showDebug 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
|
||||
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
|
||||
|
@ -113,14 +97,13 @@ type stdout struct {
|
|||
outputOnTop bool // is the STDOUT window on top?
|
||||
outputOffscreen bool // is the STDOUT window offscreen?
|
||||
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)
|
||||
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
|
||||
outputS []string // the buffer of all the output
|
||||
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
|
||||
|
@ -132,27 +115,8 @@ type dropdown struct {
|
|||
h int // the height
|
||||
active bool // is the dropdown menu currently in use?
|
||||
init bool // moves the window offscreen on startup
|
||||
// Id 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
|
||||
// dtoggle bool // is a dropdown or combobox currently active?
|
||||
}
|
||||
|
||||
// this is the gocui way
|
||||
|
@ -190,12 +154,11 @@ type window struct {
|
|||
currentTab bool // the visible tab
|
||||
selectedTab *tree.Node // for a window, this is currently selected tab
|
||||
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
|
||||
// resize bool // only set the title once
|
||||
collapsed bool // only show the window title bar
|
||||
dense bool // true if the window is dense
|
||||
large bool // true if the window is huge
|
||||
pager int // allows the user to page through the window
|
||||
dense bool // true if the window is huge
|
||||
}
|
||||
|
||||
type colorT struct {
|
||||
|
@ -213,8 +176,6 @@ type guiWidget struct {
|
|||
parent *guiWidget // mirrors the binary node tree
|
||||
children []*guiWidget // mirrors the binary node tree
|
||||
node *tree.Node // the pointer back to the tree
|
||||
pb *guipb.Widget // the guipb Widget
|
||||
wtype widget.WidgetType // used for Tables for now. todo: fix this correctly
|
||||
windowFrame *guiWidget // this is the frame for a window widget
|
||||
internal bool // indicates the widget is internal to gocui and should be treated differently
|
||||
hasTabs bool // does the window have tabs?
|
||||
|
@ -239,9 +200,8 @@ type guiWidget struct {
|
|||
frame bool // ?
|
||||
selectedTab *tree.Node // for a window, this is currently selected tab
|
||||
color *colorT // what color to use
|
||||
colorLast colorT // the last color the widget had
|
||||
defaultColor *colorT // the default colors // TODO: make a function for this instead
|
||||
isTable bool // is this a table?
|
||||
isBG bool // means this is the background widget. There is only one of these
|
||||
}
|
||||
|
||||
// THIS IS GO COMPILER MAGIC
|
||||
|
@ -266,11 +226,12 @@ func Set(ptr interface{}, tag string) error {
|
|||
}
|
||||
|
||||
func setField(field reflect.Value, defaultVal string, name string) error {
|
||||
|
||||
if !field.CanSet() {
|
||||
// log("setField() Can't set value", field, defaultVal)
|
||||
return fmt.Errorf("Can't set value\n")
|
||||
} else {
|
||||
// log.Log(NOW, "setField() Can set value", name, defaultVal)
|
||||
log.Log(NOW, "setField() Can set value", name, defaultVal)
|
||||
}
|
||||
|
||||
switch field.Kind() {
|
||||
|
|
93
table.go
93
table.go
|
@ -1,93 +0,0 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"slices"
|
||||
|
||||
"go.wit.com/lib/protobuf/guipb"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func initGridPB(pb *guipb.Widget) *guiWidget {
|
||||
var w *guiWidget
|
||||
w = new(guiWidget)
|
||||
|
||||
w.pb = pb
|
||||
w.wtype = widget.Grid
|
||||
w.cuiName = fmt.Sprintf("%d %s", pb.Id, "TK")
|
||||
w.labelN = pb.Name
|
||||
w.isTable = true
|
||||
return w
|
||||
}
|
||||
|
||||
func showTable(t *guipb.Table) {
|
||||
log.Info("gocui: should show table here")
|
||||
if t == nil {
|
||||
return
|
||||
}
|
||||
log.Info("gocui: table.Title", t.Title)
|
||||
// log.Info("gocui: need to add window here id =", t.Window.Id, t.Window.Name)
|
||||
if t.Grid == nil {
|
||||
log.Info("gocui: missing grid widget. tree plugin error")
|
||||
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)
|
||||
grid := initGridPB(t.Grid)
|
||||
grid.parent = parent
|
||||
}
|
||||
|
||||
func enableWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Enable()
|
||||
}
|
||||
|
||||
func disableWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Disable()
|
||||
}
|
||||
|
||||
func showWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
tk.Show()
|
||||
}
|
||||
|
||||
func hideWidget(n *tree.Node) {
|
||||
tk := n.TK.(*guiWidget)
|
||||
if n.WidgetType == widget.Window {
|
||||
tk.windowFrame.Hide()
|
||||
tk.hideWidgets()
|
||||
}
|
||||
tk.Hide()
|
||||
tk.deleteWidget()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) deleteWidget() {
|
||||
log.Log(INFO, "gocui deleteWidget() looking for child to delete:", tk.cuiName)
|
||||
p := tk.parent
|
||||
for i, child := range p.children {
|
||||
if tk == child {
|
||||
log.Log(INFO, "deleteWidget() found parent with child to delete:", i, child.cuiName, child.WidgetId())
|
||||
p.children = slices.Delete(p.children, i, i+1)
|
||||
}
|
||||
}
|
||||
tk.deleteTree()
|
||||
}
|
||||
|
||||
func (tk *guiWidget) deleteTree() {
|
||||
for _, child := range tk.children {
|
||||
child.deleteTree()
|
||||
}
|
||||
tk.Hide()
|
||||
}
|
64
textbox.go
64
textbox.go
|
@ -7,7 +7,6 @@ package main
|
|||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
log "go.wit.com/log"
|
||||
|
@ -30,21 +29,18 @@ func (tk *guiWidget) forceSizes(r *rectType) {
|
|||
tk.force.h1 = r.h1
|
||||
}
|
||||
|
||||
func initTextbox() {
|
||||
func (callertk *guiWidget) showTextbox() {
|
||||
if me.textbox.tk == nil {
|
||||
// should only happen once
|
||||
me.textbox.tk = makeNewFlagWidget(me.textbox.wId)
|
||||
// me.textbox.tk.dumpWidget("init() textbox")
|
||||
me.textbox.tk.dumpWidget("init() textbox")
|
||||
}
|
||||
}
|
||||
|
||||
func (callertk *guiWidget) prepTextbox() {
|
||||
initTextbox()
|
||||
if me.textbox.tk == nil {
|
||||
log.Log(WARN, "prepTextbox() Is Broken")
|
||||
log.Log(GOCUI, "showTextbox() Is Broken")
|
||||
return
|
||||
}
|
||||
|
||||
tk := me.textbox.tk
|
||||
r := new(rectType)
|
||||
// startW, startH := tk.Position()
|
||||
r.w0 = callertk.gocuiSize.w0 + 4
|
||||
|
@ -54,56 +50,28 @@ func (callertk *guiWidget) prepTextbox() {
|
|||
me.textbox.tk.forceSizes(r)
|
||||
me.textbox.tk.dumpWidget("after sizes")
|
||||
|
||||
me.textbox.callerTK = callertk
|
||||
|
||||
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) {
|
||||
// tk := me.textbox.tk
|
||||
// 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 {
|
||||
log.Log(WARN, "textbox.tk.v == nil showTextbox() is broken")
|
||||
log.Info("wtf went wrong")
|
||||
return
|
||||
}
|
||||
|
||||
me.textbox.tk.setColorModal()
|
||||
me.textbox.tk.v.Clear()
|
||||
cur := strings.TrimSpace(callers)
|
||||
// log.Info("setting textbox string to:", cur)
|
||||
me.textbox.tk.v.WriteString(cur)
|
||||
|
||||
me.textbox.tk.v.Editable = true
|
||||
me.textbox.tk.v.Wrap = true
|
||||
|
||||
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())
|
||||
|
||||
// bind the enter key to a function so we can close the textbox
|
||||
me.baseGui.SetKeybinding(me.textbox.tk.v.Name(), gocui.KeyEnter, gocui.ModNone, theCloseTheTextbox)
|
||||
|
||||
me.textbox.active = true
|
||||
me.textbox.callerTK = callertk
|
||||
|
||||
me.baseGui.SetViewOnTop(me.textbox.tk.v.Name())
|
||||
me.textbox.tk.dumpWidget("showTextbox()")
|
||||
tk.dumpWidget("showTextbox()")
|
||||
}
|
||||
|
||||
func theCloseTheTextbox(g *gocui.Gui, v *gocui.View) error {
|
||||
|
@ -114,7 +82,7 @@ func theCloseTheTextbox(g *gocui.Gui, v *gocui.View) error {
|
|||
// updates the text and sends an event back to the application
|
||||
func textboxClosed() {
|
||||
// get the text the user entered
|
||||
var newtext string
|
||||
newtext := "testing"
|
||||
if me.textbox.tk.v == nil {
|
||||
newtext = ""
|
||||
} else {
|
||||
|
@ -123,9 +91,9 @@ func textboxClosed() {
|
|||
newtext = strings.TrimSpace(newtext)
|
||||
me.textbox.active = false
|
||||
me.textbox.tk.Hide()
|
||||
// log.Info("textbox closed with text:", newtext, me.textbox.callerTK.cuiName)
|
||||
log.Info("textbox closed", newtext)
|
||||
|
||||
if me.notify.clock.tk.v != nil {
|
||||
if me.clock.tk.v != nil {
|
||||
me.baseGui.SetCurrentView("help")
|
||||
} else {
|
||||
me.baseGui.SetCurrentView("msg")
|
||||
|
@ -140,12 +108,12 @@ func textboxClosed() {
|
|||
|
||||
win := me.textbox.callerTK.findParentWindow()
|
||||
if win != nil {
|
||||
// win.dumpWidget("redraw this!!!")
|
||||
win.dumpWidget("redraw this!!!")
|
||||
tk := me.textbox.callerTK
|
||||
// me.textbox.callerTK.dumpWidget("resize this!!!")
|
||||
me.textbox.callerTK.dumpWidget("resize this!!!")
|
||||
me.textbox.callerTK.Size()
|
||||
me.textbox.callerTK.placeWidgets(tk.gocuiSize.w0-4, tk.gocuiSize.h0-4)
|
||||
// tk.dumpWidget("resize:" + tk.String())
|
||||
win.makeWindowActive()
|
||||
tk.dumpWidget("resize:" + tk.String())
|
||||
win.redrawWindow(win.gocuiSize.w0, win.gocuiSize.h0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func setFake(n *tree.Node) {
|
|||
}
|
||||
}
|
||||
|
||||
// mostly just sets the colors of things
|
||||
// func (n *node) addWidget(n *tree.Node) {
|
||||
func addWidget(n *tree.Node) {
|
||||
if !me.ok {
|
||||
log.Log(INFO, "addWidget() START NOT OKAY")
|
||||
|
@ -36,36 +36,38 @@ func addWidget(n *tree.Node) {
|
|||
log.Log(INFO, "addWidget() START NOT OKAY")
|
||||
waitOK()
|
||||
}
|
||||
tk := n.TK.(*guiWidget)
|
||||
var tk *guiWidget
|
||||
tk = n.TK.(*guiWidget)
|
||||
log.Log(INFO, "setStartWH() w.id =", n.WidgetId, "n.name", n.String())
|
||||
switch n.WidgetType {
|
||||
case widget.Root:
|
||||
log.Log(INFO, "setStartWH() rootNode w.id =", n.WidgetId, "w.name", n.String())
|
||||
tk.color = &colorRoot
|
||||
setFake(n)
|
||||
return
|
||||
case widget.Flag:
|
||||
tk.color = &colorFlag
|
||||
setFake(n)
|
||||
return
|
||||
case widget.Window:
|
||||
tk.frame = false
|
||||
tk.labelN = tk.GetText() + " X"
|
||||
tk.setColor(&colorWindow)
|
||||
me.newWindowTrigger <- tk
|
||||
redoWindows(0, 0)
|
||||
hideHelp()
|
||||
showHelp()
|
||||
return
|
||||
case widget.Stdout:
|
||||
tk.labelN = "moreSTDOUT"
|
||||
n.State.ProgName = "moreSTDOUT"
|
||||
n.State.Label = "moreSTDOUT"
|
||||
tk.isFake = true
|
||||
return
|
||||
case widget.Tab:
|
||||
tk.color = &colorTab
|
||||
return
|
||||
case widget.Button:
|
||||
tk.setColorButton()
|
||||
if tk.IsEnabled() {
|
||||
} else {
|
||||
tk.setColorDisable()
|
||||
}
|
||||
return
|
||||
case widget.Checkbox:
|
||||
tk.setColorInput()
|
||||
|
@ -75,18 +77,20 @@ func addWidget(n *tree.Node) {
|
|||
tk.setColorInput()
|
||||
return
|
||||
case widget.Textbox:
|
||||
n.State.Label = ""
|
||||
tk.labelN = " "
|
||||
tk.setColorInput()
|
||||
n.State.Label = "TEXTBOX"
|
||||
tk.labelN = " " + n.State.Label
|
||||
tk.color = &colorDropdown
|
||||
return
|
||||
case widget.Combobox:
|
||||
tk.setColorInput()
|
||||
tk.color = &colorCombobox
|
||||
return
|
||||
case widget.Box:
|
||||
// tk.color = &colorBox
|
||||
tk.isFake = true
|
||||
setFake(n)
|
||||
return
|
||||
case widget.Grid:
|
||||
// tk.color = &colorGrid
|
||||
tk.isFake = true
|
||||
setFake(n)
|
||||
return
|
||||
|
@ -95,17 +99,7 @@ func addWidget(n *tree.Node) {
|
|||
tk.frame = false
|
||||
return
|
||||
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()
|
||||
}
|
||||
} else {
|
||||
tk.setColorLabel()
|
||||
}
|
||||
tk.frame = false
|
||||
return
|
||||
default:
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
package main
|
||||
|
||||
/*
|
||||
This is reference code for toolkit developers
|
||||
|
||||
This is how information is passed in GO back to the application
|
||||
via the GO 'plugin' concept
|
||||
|
||||
TODO: switch this to protocol buffers
|
||||
*/
|
||||
|
||||
import (
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
// Other goroutines must use this to access the GUI
|
||||
//
|
||||
// You can not acess / process the GUI thread directly from
|
||||
// other goroutines. This is due to the nature of how
|
||||
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
||||
//
|
||||
// this sets the channel to send user events back from the plugin
|
||||
func Callback(guiCallback chan widget.Action) {
|
||||
me.myTree.Callback(guiCallback)
|
||||
}
|
||||
|
||||
func PluginChannel() chan widget.Action {
|
||||
return me.myTree.PluginChannel()
|
||||
}
|
|
@ -13,74 +13,11 @@ import (
|
|||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
// don't draw widgets that are too far down the window
|
||||
func (tk *guiWidget) doNotDraw() bool {
|
||||
var check bool
|
||||
switch tk.WidgetType() {
|
||||
case widget.Button:
|
||||
check = true
|
||||
case widget.Label:
|
||||
check = true
|
||||
default:
|
||||
}
|
||||
if !check {
|
||||
return false
|
||||
}
|
||||
win := tk.findParentWindow()
|
||||
if win == nil {
|
||||
// don't draw anything if you can't find the parent window
|
||||
return true
|
||||
}
|
||||
|
||||
h := tk.gocuiSize.h0 - win.gocuiSize.h0
|
||||
|
||||
if h > 20 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// page widgets in the window
|
||||
func (tk *guiWidget) pageWidget() *rectType {
|
||||
r := new(rectType)
|
||||
|
||||
var check bool
|
||||
switch tk.WidgetType() {
|
||||
case widget.Button:
|
||||
check = true
|
||||
case widget.Label:
|
||||
check = true
|
||||
default:
|
||||
}
|
||||
if !check {
|
||||
return nil
|
||||
}
|
||||
win := tk.findParentWindow()
|
||||
if win == nil {
|
||||
// don't draw anything if you can't find the parent window
|
||||
return nil
|
||||
}
|
||||
|
||||
r.w0 = tk.gocuiSize.w0
|
||||
r.h0 = tk.gocuiSize.h0
|
||||
r.w1 = tk.gocuiSize.w1
|
||||
r.h1 = tk.gocuiSize.h1
|
||||
|
||||
// r.h0 = tk.gocuiSize.h0 - win.gocuiSize.h0
|
||||
|
||||
if r.h0 > 20 {
|
||||
return r
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// display's the text of the widget in gocui
|
||||
// deletes the old view if it exists and recreates it
|
||||
func (tk *guiWidget) drawView() {
|
||||
var err error
|
||||
log.Log(INFO, "drawView() START", tk.WidgetType(), tk.String())
|
||||
log.Log(INFO, "drawView() START", tk.node.WidgetType, tk.String())
|
||||
if me.baseGui == nil {
|
||||
log.Log(ERROR, "drawView() ERROR: me.baseGui == nil", tk)
|
||||
return
|
||||
|
@ -88,7 +25,7 @@ func (tk *guiWidget) drawView() {
|
|||
|
||||
if tk.cuiName == "" {
|
||||
log.Log(ERROR, "drawView() tk.cuiName was not set for widget", tk)
|
||||
tk.cuiName = strconv.Itoa(tk.WidgetId()) + " TK"
|
||||
tk.cuiName = strconv.Itoa(tk.node.WidgetId) + " TK"
|
||||
}
|
||||
log.Log(INFO, "drawView() labelN =", tk.labelN)
|
||||
|
||||
|
@ -101,40 +38,8 @@ func (tk *guiWidget) drawView() {
|
|||
c := tk.gocuiSize.w1
|
||||
d := tk.gocuiSize.h1
|
||||
|
||||
/*
|
||||
// testing code for paging large windows
|
||||
if tk.doNotDraw() {
|
||||
return
|
||||
}
|
||||
|
||||
if tk.window.pager != 0 {
|
||||
if r := tk.pageWidget(); r == nil {
|
||||
// if nil, draw whatever it is anyway
|
||||
} else {
|
||||
if r.Width() == 0 && r.Height() == 0 {
|
||||
// don't draw empty stuff
|
||||
return
|
||||
}
|
||||
a = r.w0
|
||||
b = r.h0
|
||||
c = r.w1
|
||||
d = r.h1
|
||||
}
|
||||
}
|
||||
|
||||
if tk.WidgetType() == widget.Window || tk.WidgetType() == widget.Flag {
|
||||
if tk.window.pager != 0 {
|
||||
if tk.gocuiSize.Height() > 40 {
|
||||
tk.window.large = true
|
||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + 40
|
||||
d = tk.gocuiSize.h1
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// this is all terrible. This sets the title. kinda
|
||||
if tk.WidgetType() == widget.Window {
|
||||
if tk.node.WidgetType == widget.Window {
|
||||
tk.textResize()
|
||||
tk.full.w0 = tk.force.w0
|
||||
tk.full.h0 = tk.force.h0
|
||||
|
@ -154,6 +59,7 @@ func (tk *guiWidget) drawView() {
|
|||
b = tk.gocuiSize.h0
|
||||
c = tk.gocuiSize.w1
|
||||
d = tk.gocuiSize.h1
|
||||
|
||||
}
|
||||
|
||||
tk.v, err = me.baseGui.SetView(tk.cuiName, a, b, c, d, 0)
|
||||
|
@ -162,55 +68,18 @@ func (tk *guiWidget) drawView() {
|
|||
log.Log(ERROR, "drawView() internal plugin error err = nil")
|
||||
return
|
||||
}
|
||||
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
tk.dumpWidget("drawView() err")
|
||||
log.Log(ERROR, "drawView() internal plugin error error.IS()", err)
|
||||
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
|
||||
tk.v.Wrap = true
|
||||
tk.v.Frame = tk.frame
|
||||
tk.v.Clear()
|
||||
fmt.Fprint(tk.v, tk.labelN)
|
||||
|
||||
// tmp hack to disable buttons on window open
|
||||
if tk.WidgetType() == widget.Button {
|
||||
if tk.IsEnabled() {
|
||||
} else {
|
||||
tk.setColorDisable()
|
||||
}
|
||||
}
|
||||
|
||||
switch tk.WidgetType() {
|
||||
case widget.Button:
|
||||
if tk.IsEnabled() {
|
||||
if tk.isDense() && tk.isInGrid() {
|
||||
tk.setColorButtonDense()
|
||||
} else {
|
||||
tk.setColorButton()
|
||||
}
|
||||
} else {
|
||||
tk.setColorDisable()
|
||||
}
|
||||
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 tk.color != nil {
|
||||
tk.v.FrameColor = tk.color.frame
|
||||
|
@ -219,16 +88,20 @@ func (tk *guiWidget) drawView() {
|
|||
tk.v.SelFgColor = tk.color.selFg
|
||||
tk.v.SelBgColor = tk.color.selBg
|
||||
}
|
||||
|
||||
log.Log(INFO, "drawView() END")
|
||||
}
|
||||
|
||||
// redraw the widget tree starting at this location
|
||||
func (w *guiWidget) DrawAt(offsetW, offsetH int) {
|
||||
w.setColor(&colorActiveW)
|
||||
w.placeWidgets(offsetW, offsetH) // compute the sizes & places for each widget
|
||||
// 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
|
||||
func (w *guiWidget) drawTree(draw bool) {
|
||||
if w == nil {
|
||||
|
@ -258,9 +131,6 @@ func (w *guiWidget) Show() {
|
|||
// never show hidden widgets
|
||||
return
|
||||
}
|
||||
if me.debug {
|
||||
w.dumpWidget("drawView()")
|
||||
}
|
||||
|
||||
w.drawView()
|
||||
}
|
90
treeInit.go
90
treeInit.go
|
@ -1,90 +0,0 @@
|
|||
// Copyright 2017-2025 WIT.COM Inc. All rights reserved.
|
||||
// Use of this source code is governed by the GPL 3.0
|
||||
|
||||
/*
|
||||
DO NOT EDIT THIS FILE
|
||||
|
||||
this file is the same for every GUI toolkit plugin
|
||||
when you are making a new GUI toolkit plugin for
|
||||
a specific toolkit, you just need to define these
|
||||
functions.
|
||||
|
||||
for example, in the "gocui" toolkit, the functions
|
||||
below are what triggers the "gocui" GO package
|
||||
to draw labels, buttons, windows, etc
|
||||
|
||||
If you are starting out trying to make a new GUI toolkit,
|
||||
all you have to do is copy this file over. Then
|
||||
work on making these functions. addWidget(), setText(), etc.
|
||||
|
||||
That's it!
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
/*
|
||||
This is reference code for toolkit developers
|
||||
|
||||
This is how information is passed in GO back to the application
|
||||
via the GO 'plugin' concept
|
||||
|
||||
TODO: switch this to protocol buffers
|
||||
*/
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
log "go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
// Other goroutines must use this to access the GUI
|
||||
//
|
||||
// You can not acess / process the GUI thread directly from
|
||||
// other goroutines. This is due to the nature of how
|
||||
// Linux, MacOS and Windows work (they all work differently. suprise. surprise.)
|
||||
//
|
||||
// this sets the channel to send user events back from the plugin
|
||||
func Callback(guiCallback chan widget.Action) {
|
||||
me.myTree.Callback(guiCallback)
|
||||
}
|
||||
|
||||
func PluginChannel() chan widget.Action {
|
||||
initOnce.Do(initPlugin)
|
||||
for {
|
||||
if me.myTree != nil {
|
||||
break
|
||||
}
|
||||
log.Info("me.myTree == nil")
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
}
|
||||
return me.myTree.PluginChannel()
|
||||
}
|
||||
|
||||
func FrozenChannel() chan widget.Action {
|
||||
return me.myTree.FrozenChannel()
|
||||
}
|
||||
|
||||
func initTree() *tree.TreeInfo {
|
||||
t := tree.New()
|
||||
t.PluginName = PLUGIN
|
||||
t.Add = newAdd
|
||||
t.SetTitle = setTitle
|
||||
t.SetLabel = setLabel
|
||||
t.SetText = setText
|
||||
t.AddText = addText
|
||||
|
||||
t.Enable = enableWidget
|
||||
t.Disable = disableWidget
|
||||
|
||||
t.Show = showWidget
|
||||
t.Hide = hideWidget
|
||||
|
||||
t.SetChecked = setChecked
|
||||
t.ToolkitInit = toolkitInit
|
||||
t.ToolkitClose = toolkitClose
|
||||
t.ShowTable = showTable
|
||||
|
||||
return t
|
||||
}
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/awesome-gocui/gocui"
|
||||
"go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
|
@ -17,8 +18,8 @@ func initWidget(n *tree.Node) *guiWidget {
|
|||
w = new(guiWidget)
|
||||
|
||||
w.node = n
|
||||
w.cuiName = strconv.Itoa(w.WidgetId()) + " TK"
|
||||
// w.WidgetType() = n.WidgetType
|
||||
w.cuiName = strconv.Itoa(w.node.WidgetId) + " TK"
|
||||
// w.node.WidgetType = n.WidgetType
|
||||
w.labelN = n.State.Label
|
||||
if w.labelN == "" {
|
||||
// remove this debugging hack once things are stable and fixed
|
||||
|
@ -38,15 +39,11 @@ func initWidget(n *tree.Node) *guiWidget {
|
|||
|
||||
p := n.Parent
|
||||
if p == nil {
|
||||
log.Log(ERROR, "parent == nil", w.String(), n.WidgetId, w.WidgetType())
|
||||
log.Log(ERROR, "parent == nil", w.String(), n.WidgetId, w.node.WidgetType)
|
||||
return w
|
||||
}
|
||||
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.node.WidgetType)
|
||||
return w
|
||||
}
|
||||
|
||||
|
@ -72,22 +69,13 @@ func setupCtrlDownWidget() {
|
|||
|
||||
func (w *guiWidget) deleteView() {
|
||||
// make sure the view isn't really there
|
||||
// log.Log(GOCUI, "deleteView()", w.cuiName, w.WidgetType(), w.WidgetId())
|
||||
// log.Log(GOCUI, "deleteView()", w.cuiName, w.node.WidgetType, w.node.WidgetId)
|
||||
me.baseGui.DeleteView(w.cuiName)
|
||||
w.v = nil
|
||||
}
|
||||
|
||||
func (tk *guiWidget) String() string {
|
||||
// deprecate this?
|
||||
curval := strings.TrimSpace(tk.labelN)
|
||||
if curval != "" {
|
||||
return curval
|
||||
}
|
||||
curval = strings.TrimSpace(tk.GetLabel())
|
||||
if curval != "" {
|
||||
return curval
|
||||
}
|
||||
curval = tk.GetText()
|
||||
curval := strings.TrimSpace(tk.node.GetLabel())
|
||||
if curval != "" {
|
||||
return curval
|
||||
}
|
||||
|
@ -99,6 +87,11 @@ func (tk *guiWidget) String() string {
|
|||
if curval != "" {
|
||||
return curval
|
||||
}
|
||||
// deprecate this?
|
||||
curval = strings.TrimSpace(tk.labelN)
|
||||
if curval != "" {
|
||||
return curval
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
@ -124,3 +117,34 @@ func (tk *guiWidget) SetVisible(b bool) {
|
|||
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
|
||||
}
|
9
view.go
9
view.go
|
@ -23,13 +23,6 @@ func (tk *guiWidget) textResize() {
|
|||
h += 1
|
||||
}
|
||||
|
||||
// todo: fix all this old code
|
||||
if tk.WidgetType() == widget.Textbox {
|
||||
if w < 5 {
|
||||
w = 5
|
||||
}
|
||||
}
|
||||
|
||||
// this is old code. now move this somewhere smarter
|
||||
tk.gocuiSize.w1 = tk.gocuiSize.w0 + w + me.FramePadW // TODO: move this FramePadW out of here
|
||||
tk.gocuiSize.h1 = tk.gocuiSize.h0 + h + me.FramePadH // TODO: fix this size computation
|
||||
|
@ -50,7 +43,7 @@ func (w *guiWidget) hideWidgets() {
|
|||
if w == nil {
|
||||
return
|
||||
}
|
||||
switch w.WidgetType() {
|
||||
switch w.node.WidgetType {
|
||||
case widget.Root:
|
||||
case widget.Flag:
|
||||
case widget.Window:
|
||||
|
|
115
window.go
115
window.go
|
@ -7,32 +7,31 @@ import (
|
|||
"fmt"
|
||||
"strings"
|
||||
|
||||
log "go.wit.com/log"
|
||||
"go.wit.com/toolkits/tree"
|
||||
"go.wit.com/widget"
|
||||
)
|
||||
|
||||
func (tk *guiWidget) setTitle(s string) {
|
||||
if tk.WidgetType() != widget.Window {
|
||||
if tk.node.WidgetType != widget.Window {
|
||||
return
|
||||
}
|
||||
if tk.v == nil {
|
||||
return
|
||||
}
|
||||
tk.setColorWindowTitleActive()
|
||||
rect := tk.gocuiSize
|
||||
rect.w1 = rect.w0 + tk.full.Width() + 1
|
||||
// rect.h1 = rect.h0 + 1
|
||||
me.baseGui.SetView(tk.v.Name(), rect.w0-1, rect.h0, rect.w1+1, rect.h1, 0)
|
||||
me.baseGui.SetView(tk.v.Name(), rect.w0, rect.h0, rect.w1, rect.h1, 0)
|
||||
tk.v.Clear()
|
||||
f := " %-" + fmt.Sprintf("%d", tk.full.Width()-3) + "s %s"
|
||||
tmp := tk.GetLabel()
|
||||
labelN := fmt.Sprintf(f, tmp, "X")
|
||||
f := "%-" + fmt.Sprintf("%d", tk.full.Width()-3) + "s %s"
|
||||
// tmp := tk.node.GetLabel() + " " + tk.v.Name() + " " + f
|
||||
tmp := tk.node.GetLabel()
|
||||
labelN := fmt.Sprintf(f, tmp, "XX")
|
||||
tk.v.WriteString(labelN)
|
||||
}
|
||||
|
||||
func (tk *guiWidget) redrawWindow(w int, h int) {
|
||||
if tk.WidgetType() != widget.Window {
|
||||
if tk.node.WidgetType != widget.Window {
|
||||
return
|
||||
}
|
||||
// tk.dumpWidget(fmt.Sprintf("redrawWindow(%d,%d)", w, h))
|
||||
|
@ -42,8 +41,8 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
|||
// pin the window to (w,h)
|
||||
tk.gocuiSize.w0 = w
|
||||
tk.gocuiSize.h0 = h
|
||||
tk.gocuiSize.w1 = w + len(tk.GetLabel())
|
||||
tk.labelN = tk.GetLabel() // could set XX here also but don't have final size of window yet
|
||||
tk.gocuiSize.w1 = w + len(tk.node.GetLabel())
|
||||
tk.labelN = tk.node.GetLabel() // could set XX here also but don't have final size of window yet
|
||||
tk.force.w0 = w
|
||||
tk.force.w1 = w
|
||||
tk.force.h0 = h
|
||||
|
@ -55,8 +54,7 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
|||
tk.hasTabs = false
|
||||
|
||||
tk.DrawAt(w, h)
|
||||
// tk.setColor(&colorActiveW) // sets the window to Green BG
|
||||
tk.setColorWindowTitleActive()
|
||||
tk.setColor(&colorActiveW) // sets the window to Green BG
|
||||
|
||||
if tk.window.collapsed {
|
||||
// don't show anything but the title bar
|
||||
|
@ -70,18 +68,26 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
|||
tk.full.h0 = tk.force.h0
|
||||
|
||||
tk.setFullSize()
|
||||
tk.Show()
|
||||
if tk.v == nil {
|
||||
log.Info("redrawWindow on tk.v == nil")
|
||||
standardExit()
|
||||
/*
|
||||
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("crap. got an err", err)
|
||||
}
|
||||
if tk.v != v {
|
||||
log.Info("crap. got another problem v != tk.v")
|
||||
}
|
||||
*/
|
||||
tk.Show()
|
||||
tk.v.Clear()
|
||||
fmt.Fprint(tk.v, "ZZZ"+tk.GetText())
|
||||
tk.showWidgets()
|
||||
|
||||
// RE-VERIFY THIS CAN'T BE DONE IN A BETTER WAY. However, for now, this works finally so I am leaving it alone
|
||||
|
||||
if tk.windowFrame == nil {
|
||||
tk.addWindowFrameTK(0 - tk.WidgetId())
|
||||
tk.windowFrame.makeTK([]string{""})
|
||||
tk.addWindowFrameTK(0 - tk.node.WidgetId)
|
||||
tk.windowFrame.node.State.Label = " ZZzzzFrame" // temporary name. blank out when ready for release
|
||||
tk.windowFrame.makeTK([]string{" ZZzzzFrame"})
|
||||
}
|
||||
|
||||
// this seems to correctly create the window frame
|
||||
|
@ -100,7 +106,6 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
|||
|
||||
// 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)
|
||||
|
||||
// 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)
|
||||
|
||||
|
@ -109,7 +114,7 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
|
|||
tk.showWidgets()
|
||||
|
||||
// draw the window title
|
||||
tk.setTitle(tk.GetLabel())
|
||||
tk.setTitle(tk.node.GetLabel() + " jwc")
|
||||
}
|
||||
|
||||
// re-draws the buttons for each of the windows
|
||||
|
@ -118,7 +123,8 @@ func redoWindows(nextW int, nextH int) {
|
|||
// tk.dumpWidget(fmt.Sprintf("redoWindowsS (%d,%d)", nextW, nextH))
|
||||
if tk.window.wasDragged {
|
||||
// don't move windows around the user has dragged to a certain location
|
||||
tk.makeWindowActive()
|
||||
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||
setThingsOnTop() // sets help, Stdout, etc on the top after windows have been redrawn
|
||||
} else {
|
||||
w, _ := me.baseGui.Size()
|
||||
if nextW > w-20 {
|
||||
|
@ -157,11 +163,13 @@ func (win *guiWidget) addWindowFrame(wId int) *tree.Node {
|
|||
if tk.node.Parent == nil {
|
||||
tk.node.Parent = me.treeRoot
|
||||
}
|
||||
// copy the data from the action message
|
||||
tk.node.State.Label = "windowFrame"
|
||||
|
||||
// set the name used by gocui to the id
|
||||
tk.cuiName = fmt.Sprintf("%d DR", wId)
|
||||
|
||||
// tk.color = &colorGroup
|
||||
tk.color = &colorGroup
|
||||
|
||||
// add this new widget on the binary tree
|
||||
tk.parent = win
|
||||
|
@ -175,41 +183,29 @@ func (win *guiWidget) addWindowFrame(wId int) *tree.Node {
|
|||
return n
|
||||
}
|
||||
|
||||
func (tk *guiWidget) isWindowActive() bool {
|
||||
if !(tk.WidgetType() == widget.Window || tk.WidgetType() == widget.Stdout) {
|
||||
// only allow Window or the Stdout widgets to be made active
|
||||
return false
|
||||
}
|
||||
return tk.window.active
|
||||
}
|
||||
|
||||
// always redraws at the corner of the gocuiSize box
|
||||
func (tk *guiWidget) makeWindowActive() {
|
||||
if !(tk.WidgetType() == widget.Window || tk.WidgetType() == widget.Stdout) {
|
||||
if !(tk.node.WidgetType == widget.Window || tk.node.WidgetType == widget.Stdout) {
|
||||
// only allow Window or the Stdout widgets to be made active
|
||||
return
|
||||
}
|
||||
|
||||
if tk.WidgetType() == widget.Stdout {
|
||||
me.stdout.outputOnTop = true
|
||||
} else {
|
||||
// me.stdout.outputOnTop = false // ?
|
||||
}
|
||||
|
||||
// disable and increment all the windows
|
||||
for _, tk := range me.allwin {
|
||||
tk.window.order += 1
|
||||
tk.window.active = false
|
||||
// tk.setColor(&colorWindow) // color for inactive windows
|
||||
tk.setColorWindowTitle()
|
||||
tk.setColor(&colorWindow) // color for inactive windows
|
||||
}
|
||||
|
||||
// set this window as the active one
|
||||
tk.window.active = true
|
||||
tk.window.order = 0
|
||||
|
||||
tk.redrawWindow(tk.gocuiSize.w0, tk.gocuiSize.h0)
|
||||
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) {
|
||||
|
@ -220,21 +216,24 @@ func (tk *guiWidget) makeTK(ddItems []string) {
|
|||
tk.gocuiSize.w1 = 120
|
||||
tk.gocuiSize.h0 = 15
|
||||
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()
|
||||
}
|
||||
|
||||
func (win *guiWidget) checkWindowClose(w int, h int) bool {
|
||||
s := fmt.Sprintf("mouse(%d,%d) ", w, h)
|
||||
offW := win.full.w1 - w
|
||||
offH := h - win.full.h0
|
||||
s += fmt.Sprintf("offset(%d,%d)", offW, offH)
|
||||
if (offW < 2) && (offH < 2) {
|
||||
log.Info("attempting close on ", s, win.cuiName)
|
||||
me.myTree.SendWindowCloseEvent(win.node)
|
||||
// store the stdout corner for computing the drag size
|
||||
return true
|
||||
}
|
||||
// log.Info("not attempting close on ", s, win.cuiName)
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue