add a goroutine and channel to trigger window redraw

This commit is contained in:
Jeff Carr 2025-02-06 01:42:40 -06:00
parent 70a742c98a
commit 31c130045d
9 changed files with 137 additions and 49 deletions

View File

@ -15,9 +15,11 @@ func setChecked(n *tree.Node, b bool) {
var tk *guiWidget var tk *guiWidget
tk = n.TK.(*guiWidget) tk = n.TK.(*guiWidget)
if tk.node.State.Label == "" { /*
tk.node.State.Label = "BLANK" if tk.node.State.Label == "" {
} tk.node.State.Label = "BLANK"
}
*/
if tk.node.State.Checked { if tk.node.State.Checked {
log.Log(WARN, "setCheckbox() got true", tk.node.State.Checked) log.Log(WARN, "setCheckbox() got true", tk.node.State.Checked)
tk.labelN = "X " + tk.node.State.Label tk.labelN = "X " + tk.node.State.Label
@ -36,9 +38,11 @@ func (w *guiWidget) setCheckbox() {
log.Log(WARN, "setCheckbox() being run on widget:", w.node.WidgetType) log.Log(WARN, "setCheckbox() being run on widget:", w.node.WidgetType)
return return
} }
if w.node.State.Label == "" { /*
w.node.State.Label = "BLANK" if w.node.State.Label == "" {
} w.node.State.Label = "BLANK"
}
*/
if w.node.State.Checked { if w.node.State.Checked {
log.Log(WARN, "setCheckbox() got true", w.node.State.Checked) log.Log(WARN, "setCheckbox() got true", w.node.State.Checked)
w.labelN = "X " + w.node.State.Label w.labelN = "X " + w.node.State.Label

View File

@ -97,7 +97,7 @@ func addDropdown() *tree.Node {
func theNotsure(g *gocui.Gui, v *gocui.View) error { func theNotsure(g *gocui.Gui, v *gocui.View) error {
log.Info("got keypress 2. now what?") log.Info("got keypress 2. now what?")
// w, h := g.MousePosition() // w, h := g.MousePosition()
redoWindows(1, -1) me.newWindowTrigger <- true
return nil return nil
} }

View File

@ -42,12 +42,15 @@ func mouseMove(g *gocui.Gui) {
currentDrag.moveNew() currentDrag.moveNew()
return return
} }
// first look for windows
for _, tk := range findByXY(w, h) { for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Window { if tk.node.WidgetType == widget.Window {
currentDrag = tk currentDrag = tk
return return
} }
} }
// now look for the STDOUT window
for _, tk := range findByXY(w, h) { for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Flag { if tk.node.WidgetType == widget.Flag {
currentDrag = tk currentDrag = tk
@ -61,11 +64,13 @@ func mouseMove(g *gocui.Gui) {
// tk.moveNew() // tk.moveNew()
return return
} }
if tk.node.WidgetType == widget.Label { /*
currentDrag = tk if tk.node.WidgetType == widget.Label {
// tk.moveNew() currentDrag = tk
return // tk.moveNew()
} return
}
*/
found = true found = true
} }
if !found { if !found {
@ -92,9 +97,8 @@ func mouseMove(g *gocui.Gui) {
func (tk *guiWidget) moveNew() { func (tk *guiWidget) moveNew() {
w, h := me.baseGui.MousePosition() w, h := me.baseGui.MousePosition()
if tk.node.WidgetType == widget.Window { if tk.node.WidgetType == widget.Window {
tk.DrawAt(w, h)
tk.redrawWindow(w-tk.dragW, h-tk.dragH) // TODO: fix these hard coded things with offsets tk.redrawWindow(w-tk.dragW, h-tk.dragH) // TODO: fix these hard coded things with offsets
// tk.dumpWidget(fmt.Sprintf("move(%dx%d) %s WIN", w, h, tk.cuiName)) helpTop() // sets the help window as the top view
return return
} }
if tk.node.WidgetType == widget.Flag { if tk.node.WidgetType == widget.Flag {
@ -108,11 +112,36 @@ func (tk *guiWidget) moveNew() {
// tk.dumpWidget("moveNew() MSG" + tk.cuiName) // tk.dumpWidget("moveNew() MSG" + tk.cuiName)
outputW := 180 outputW := 180
outputH := 40 outputH := 40
me.baseGui.SetView("msg", w-xOffset, h-yOffset, w-xOffset+outputW, h-yOffset+outputH+me.FramePadH, 0) w0 := w - xOffset
h0 := h - yOffset
w1 := w - xOffset + outputW
h1 := h - yOffset + outputH + me.FramePadH
me.baseGui.SetView("msg", w0, h0, w1, h1, 0)
me.startOutputW = w - xOffset me.startOutputW = w - xOffset
me.startOutputH = h - yOffset me.startOutputH = h - yOffset
me.baseGui.SetViewOnBottom("msg") me.baseGui.SetViewOnBottom("msg")
tk.gocuiSize.w0 = w0
tk.gocuiSize.w1 = w1
tk.gocuiSize.h0 = h0
tk.gocuiSize.h1 = h1
tk.full.w0 = w0
tk.full.w1 = w1
tk.full.h0 = h0
tk.full.h1 = h1
/* this totally fucks up stdout
me.logStdout.full.w0 = w - xOffset
me.logStdout.full.h0 = h - xOffset
me.logStdout.full.w1 = me.logStdout.full.w0 + 120 + me.logStdout.gocuiSize.Width()
me.logStdout.full.h1 = me.logStdout.full.h0 + 40 + me.logStdout.gocuiSize.Height()
me.logStdout.DrawAt(me.logStdout.full.w0, me.logStdout.full.h0)
*/
} }
// always place the help menu on top
helpTop() // sets the help window as the top view
} }
func createStdout(g *gocui.Gui) bool { func createStdout(g *gocui.Gui) bool {

View File

@ -88,6 +88,15 @@ func showHelp() error {
return err return err
} }
} }
g.SetViewOnTop("help")
me.helpLabel = help me.helpLabel = help
return nil return nil
} }
func helpTop() {
if me.showHelp { // terrible variable name. FIXME
// log.Info("help is hidden")
return
}
me.baseGui.SetViewOnTop("help")
}

18
init.go
View File

@ -11,6 +11,7 @@ import (
"errors" "errors"
"os" "os"
"runtime/debug" "runtime/debug"
"time"
"github.com/awesome-gocui/gocui" "github.com/awesome-gocui/gocui"
"go.wit.com/log" "go.wit.com/log"
@ -51,6 +52,9 @@ func init() {
me.myTree.SetChecked = queueSetChecked me.myTree.SetChecked = queueSetChecked
me.myTree.ToolkitClose = queueToolkitClose me.myTree.ToolkitClose = queueToolkitClose
me.newWindowTrigger = make(chan bool, 1)
go newWindowTrigger()
log.Log(NOW, "Init() start pluginChan") log.Log(NOW, "Init() start pluginChan")
log.Sleep(.1) // probably not needed, but in here for now under development log.Sleep(.1) // probably not needed, but in here for now under development
go mainGogui() go mainGogui()
@ -184,3 +188,17 @@ func gocuiMain() {
panic("gocuiTKmainloop OOPS") panic("gocuiTKmainloop OOPS")
} }
} }
func newWindowTrigger() {
log.Log(NOW, "newWindowTriggerl() START")
for {
log.Log(NOW, "newWindowTrigger() for loop")
select {
case a := <-me.newWindowTrigger:
log.Log(NOW, "newWindowTrigger() got new window", a)
time.Sleep(200 * time.Millisecond)
redoWindows(1, -1)
log.Log(NOW, "newWindowTrigger() after sleep")
}
}
}

View File

@ -182,3 +182,22 @@ func (tk *guiWidget) SetText(text string) {
tk.Show() tk.Show()
} }
} }
func (tk *guiWidget) GetText() string {
if tk == nil {
log.Log(NOW, "widget is nil")
return ""
}
// deprecate this
if tk.labelN != "" {
return tk.labelN
}
if tk.node == nil {
// return gocui.view name?
return tk.cuiName
}
if tk.node.State.Label != "" {
return tk.node.State.Label
}
return ""
}

View File

@ -40,37 +40,37 @@ type config struct {
startOutputH int // ? startOutputH int // ?
helpLabel *gocui.View // ? helpLabel *gocui.View // ?
// dropdownV *guiWidget // this is a floating widget that we show whenever the user clicks on a // dropdownV *guiWidget // this is a floating widget that we show whenever the user clicks on a
dropdownW *guiWidget // grab the dropdown choices from this widget dropdownW *guiWidget // grab the dropdown choices from this widget
FramePadW int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side FramePadW int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
FramePadH int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side FramePadH int `default:"1" dense:"0"` // When the widget has a frame, like a button, it adds 2 lines runes on each side
PadW int `default:"1" dense:"0"` // pad spacing PadW int `default:"1" dense:"0"` // pad spacing
PadH int `default:"1" dense:"0"` // pad spacing PadH int `default:"1" dense:"0"` // pad spacing
WindowW int `default:"8" dense:"0"` // how far down to start Window or Tab headings WindowW int `default:"8" dense:"0"` // how far down to start Window or Tab headings
WindowH int `default:"-1"` // how far down to start Window or Tab headings WindowH int `default:"-1"` // how far down to start Window or Tab headings
TabW int `default:"5" dense:"0"` // how far down to start Window or Tab headings TabW int `default:"5" dense:"0"` // how far down to start Window or Tab headings
TabH int `default:"1" dense:"0"` // how far down to start Window or Tab headings TabH int `default:"1" dense:"0"` // how far down to start Window or Tab headings
WindowPadW int `default:"8" dense:"0"` // additional amount of space to put between window & tab widgets WindowPadW int `default:"8" dense:"0"` // additional amount of space to put between window & tab widgets
TabPadW int `default:"4" dense:"0"` // additional amount of space to put between window & tab widgets TabPadW int `default:"4" dense:"0"` // additional amount of space to put between window & tab widgets
GroupPadW int `default:"2" dense:"1"` // additional amount of space to indent on a group GroupPadW int `default:"2" dense:"1"` // additional amount of space to indent on a group
BoxPadW int `default:"2" dense:"1"` // additional amount of space to indent on a box BoxPadW int `default:"2" dense:"1"` // additional amount of space to indent on a box
GridPadW int `default:"2" dense:"1"` // additional amount of space to indent on a grid GridPadW int `default:"2" dense:"1"` // additional amount of space to indent on a grid
RawW int `default:"1"` // the raw beginning of each window (or tab) RawW int `default:"1"` // the raw beginning of each window (or tab)
RawH int `default:"5"` // 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 FakeW int `default:"20"` // offset for the hidden widgets
padded bool // add space between things like buttons padded bool // add space between things like buttons
bookshelf bool // do you want things arranged in the box like a bookshelf or a stack? bookshelf bool // do you want things arranged in the box like a bookshelf or a stack?
canvas bool // if set to true, the windows are a raw canvas canvas bool // if set to true, the windows are a raw canvas
menubar bool // for windows menubar bool // for windows
stretchy bool // expand things like buttons to the maximum size stretchy bool // expand things like buttons to the maximum size
margin bool // add space around the frames of windows margin bool // add space around the frames of windows
writeMutex sync.Mutex // writeMutex protects writes to *guiWidget (it's global right now maybe) writeMutex sync.Mutex // writeMutex protects writes to *guiWidget (it's global right now maybe)
// fakefile *FakeFile // JUNK? used to attempt to write to the stdout window dtoggle bool // is a dropdown or combobox currently active?
dtoggle bool // is a dropdown or combobox currently active? showHelp bool // toggle boolean for the help menu (deprecate?)
showHelp bool // toggle boolean for the help menu (deprecate?) ecount int // counts how many mouse and keyboard events have occurred
ecount int // counts how many mouse and keyboard events have occurred supermouse bool // prints out every widget found while you move the mouse around
supermouse bool // prints out every widget found while you move the mouse around depth int // used for listWidgets() debugging
depth int // used for listWidgets() debugging globalMouseDown bool // yep, mouse is pressed
globalMouseDown bool // yep, mouse is pressed newWindowTrigger chan bool // work around hack to redraw windows a bit after NewWindow()
} }
// deprecate these // deprecate these

View File

@ -48,6 +48,7 @@ func addWidget(n *tree.Node) {
nw.frame = false nw.frame = false
// nw.color = &colorWindow // nw.color = &colorWindow
nw.setColor(&colorWindow) nw.setColor(&colorWindow)
me.newWindowTrigger <- true
redoWindows(0, 0) redoWindows(0, 0)
hideHelp() hideHelp()
showHelp() showHelp()
@ -60,6 +61,7 @@ func addWidget(n *tree.Node) {
return return
case widget.Checkbox: case widget.Checkbox:
nw.color = &colorCheckbox nw.color = &colorCheckbox
nw.labelN = "X " + n.State.Label
return return
case widget.Dropdown: case widget.Dropdown:
nw.color = &colorDropdown nw.color = &colorDropdown

View File

@ -17,6 +17,7 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
// pin the window to (w,h) // pin the window to (w,h)
tk.gocuiSize.w0 = w tk.gocuiSize.w0 = w
tk.gocuiSize.h0 = h tk.gocuiSize.h0 = h
tk.gocuiSize.w1 = w + len(tk.GetText())
tk.force.w0 = w tk.force.w0 = w
tk.force.w1 = w tk.force.w1 = w
tk.force.h0 = h tk.force.h0 = h
@ -40,12 +41,15 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
tk.Show() tk.Show()
tk.showWidgets() 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 { if tk.windowFrame == nil {
tk.addWindowFrameTK(0 - tk.node.WidgetId) tk.addWindowFrameTK(0 - tk.node.WidgetId)
tk.windowFrame.node.State.Label = "windowFrame" tk.windowFrame.node.State.Label = "windowFrame"
tk.windowFrame.makeTK([]string{"windowFrame"}) tk.windowFrame.makeTK([]string{"windowFrame"})
} }
// tk.windowFrame.MoveToOffset(w, h+2)
// this seems to correctly create the window frame
r := tk.getFullSize() r := tk.getFullSize()
tk.windowFrame.gocuiSize.w0 = tk.force.w0 tk.windowFrame.gocuiSize.w0 = tk.force.w0
tk.windowFrame.gocuiSize.w1 = r.w1 + 1 tk.windowFrame.gocuiSize.w1 = r.w1 + 1
@ -55,14 +59,17 @@ func (tk *guiWidget) redrawWindow(w int, h int) {
tk.windowFrame.full.w1 = r.w1 + 1 tk.windowFrame.full.w1 = r.w1 + 1
tk.windowFrame.full.h0 = tk.force.h0 + 2 tk.windowFrame.full.h0 = tk.force.h0 + 2
tk.windowFrame.full.h1 = r.h1 + 1 tk.windowFrame.full.h1 = r.h1 + 1
// tk.windowFrame.drawView()
tk.windowFrame.Hide() tk.windowFrame.Hide()
tk.windowFrame.Show() tk.windowFrame.Show()
// set the window frame below the window widget, but this resizes the window widget it seems
me.baseGui.SetViewBeneath(tk.windowFrame.cuiName, tk.cuiName, 1) me.baseGui.SetViewBeneath(tk.windowFrame.cuiName, tk.cuiName, 1)
// so now we have to resize the window frame, but this moves it to the top?
me.baseGui.SetView(tk.windowFrame.cuiName, tk.windowFrame.full.w0, tk.windowFrame.full.h0, tk.windowFrame.full.w1, tk.windowFrame.full.h1, 0) me.baseGui.SetView(tk.windowFrame.cuiName, tk.windowFrame.full.w0, tk.windowFrame.full.h0, tk.windowFrame.full.w1, tk.windowFrame.full.h1, 0)
// so we have to redraw the widgets in the window anyway and then they will appear above he frame
tk.hideWidgets() tk.hideWidgets()
tk.showWidgets() tk.showWidgets()
// tk.windowFrame.drawView()
} }
// re-draws the buttons for each of the windows // re-draws the buttons for each of the windows