dropdown menus are maybe working again

This commit is contained in:
Jeff Carr 2025-02-06 05:41:51 -06:00
parent 9c7b139e5a
commit 6d991fef63
5 changed files with 142 additions and 137 deletions

View File

@ -90,55 +90,30 @@ func addDropdownNew(wId int) *tree.Node {
func (tk *guiWidget) showDropdown() { func (tk *guiWidget) showDropdown() {
// todo: fix this after switching to protobuf // todo: fix this after switching to protobuf
// var items []string me.dropdown.items = []string{} // zero out whatever was there before
// items = tk.node.State.Strings for i, s := range tk.node.Strings() {
//for i, s := range items { log.Log(GOCUI, "showDropdown()", tk.String(), i, s)
/* me.dropdown.items = append(me.dropdown.items, s)
var ddItems string }
for i, s := range tk.node.Strings() {
// log.Log(GOCUI, "showDropdown()", tk.String(), i, s)
ddItems += s + "\n"
}
*/
// log.Log(GOCUI, "new dropdown items should be set to:", ddItems) log.Log(GOCUI, "new dropdown items should be set to:", me.dropdown.items)
// sizeW, sizeH := tk.Size()
// log.Log(GOCUI, "showDropdown() size W,H=", sizeW, sizeH) if me.dropdown.tk == nil {
me.dropdown.tk = addDropdownTK(-77)
}
if me.dropdown.tk == nil {
log.Log(GOCUI, "showDropdown() IS BROKEN")
return
}
startW, startH := tk.Position() startW, startH := tk.Position()
log.Log(GOCUI, "showDropdown() IS BROKEN W,H=", startW, startH) log.Log(GOCUI, "showDropdown() SHOWING AT W,H=", startW, startH)
// me.dropdownV.MoveToOffset(startW+3, startH+2) me.dropdown.tk.MoveToOffset(startW+3, startH+2)
// me.dropdownV.labelN = ddItems me.dropdown.tk.labelN = strings.Join(me.dropdown.items, "\n")
// me.dropdownV.Show() me.dropdown.tk.Show()
me.dropdown.active = true
me.dropdown.callerTK = tk
} }
/*
func hideDDview() error {
w, h := me.baseGui.MousePosition()
log.Log(GOCUI, "hide dropdown menu() view (w,h) =", w, h)
if me.dropdownV == nil {
return gocui.ErrUnknownView
}
if me.dropdownV.v == nil {
return gocui.ErrUnknownView
}
me.dropdownV.SetVisible(false)
return nil
}
func showDDview() error {
w, h := me.baseGui.MousePosition()
log.Log(GOCUI, "show dropdown menu() view (w,h) =", w, h)
if me.dropdownV == nil {
return gocui.ErrUnknownView
}
if me.dropdownV.v == nil {
return gocui.ErrUnknownView
}
me.dropdownV.SetVisible(true)
return nil
}
*/
// if there is a drop down view active, treat it like a dialog box and close it // if there is a drop down view active, treat it like a dialog box and close it
func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string { func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string {
w.Hide() w.Hide()
@ -150,7 +125,7 @@ func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string {
// log.Log(GOCUI, "dropdownClicked() at (w,h) =", mouseW, mouseH) // log.Log(GOCUI, "dropdownClicked() at (w,h) =", mouseW, mouseH)
itemNumber := mouseH - startH itemNumber := mouseH - startH
items := strings.Split(w.labelN, "\n") items := me.dropdown.items
// log.Log(GOCUI, "dropdownClicked() look for item", itemNumber, "len(items) =", len(items)) // log.Log(GOCUI, "dropdownClicked() look for item", itemNumber, "len(items) =", len(items))
if itemNumber < 1 { if itemNumber < 1 {
return "" return ""
@ -159,11 +134,11 @@ func (w *guiWidget) dropdownClicked(mouseW, mouseH int) string {
if len(items) >= itemNumber { if len(items) >= itemNumber {
// log.Log(GOCUI, "dropdownClicked() found", items[itemNumber-1]) // log.Log(GOCUI, "dropdownClicked() found", items[itemNumber-1])
if items[itemNumber-1] != "" { if items[itemNumber-1] != "" {
if me.dropdownW != nil { if me.dropdown.tk != nil {
// log.Log(GOCUI, "dropdownClicked() send event for", me.dropdownW.cuiName, me.dropdownW.node.WidgetType) // log.Log(GOCUI, "dropdownClicked() send event for", me.dropdownW.cuiName, me.dropdownW.node.WidgetType)
me.dropdownW.SetText(items[itemNumber-1]) me.dropdown.callerTK.SetText(items[itemNumber-1])
me.dropdownW.node.SetCurrentS(items[itemNumber-1]) me.dropdown.callerTK.node.SetCurrentS(items[itemNumber-1])
me.myTree.SendUserEvent(me.dropdownW.node) me.myTree.SendUserEvent(me.dropdown.callerTK.node)
} }
} }
return items[itemNumber-1] return items[itemNumber-1]

View File

@ -37,6 +37,8 @@ func registerHandlers(g *gocui.Gui) {
g.SetKeybinding("", 'q', gocui.ModNone, doExit) // 'q' exit g.SetKeybinding("", 'q', gocui.ModNone, doExit) // 'q' exit
// debugging // debugging
g.SetKeybinding("", gocui.KeyTab, gocui.ModNone, theNotsure) // '2' use this to test new ideas
g.SetKeybinding("", gocui.KeyTab, gocui.ModShift, theNotsure) // '2' use this to test new ideas
g.SetKeybinding("", '2', gocui.ModNone, theNotsure) // '2' use this to test new ideas g.SetKeybinding("", '2', gocui.ModNone, theNotsure) // '2' use this to test new ideas
g.SetKeybinding("", 'S', gocui.ModNone, theSuperMouse) // 'S' Super Mouse mode! g.SetKeybinding("", 'S', gocui.ModNone, theSuperMouse) // 'S' Super Mouse mode!
g.SetKeybinding("", 'M', gocui.ModNone, printWidgetPlacements) // 'M' list all widgets with positions g.SetKeybinding("", 'M', gocui.ModNone, printWidgetPlacements) // 'M' list all widgets with positions
@ -94,6 +96,7 @@ func addDropdown() *tree.Node {
// use this to test code ideas // put whatever you want here and hit '2' to activate it // use this to test code ideas // put whatever you want here and hit '2' to activate it
func theNotsure(g *gocui.Gui, v *gocui.View) error { func theNotsure(g *gocui.Gui, v *gocui.View) error {
log.Info("got keypress 2. now what?") log.Info("got keypress 2. now what?")
log.Info("try to switch windows here")
// w, h := g.MousePosition() // w, h := g.MousePosition()
// me.newWindowTrigger <- true // me.newWindowTrigger <- true
return nil return nil

View File

@ -36,25 +36,47 @@ func mouseUp(g *gocui.Gui, v *gocui.View) error {
// widget was underneath so you can active // widget was underneath so you can active
// the right response for the toolkit user's app // the right response for the toolkit user's app
func mouseDown(g *gocui.Gui, v *gocui.View) error { func mouseDown(g *gocui.Gui, v *gocui.View) error {
mx, my := g.MousePosition()
log.Info("mouseDown() setting globalMouseDown = true") log.Info("mouseDown() setting globalMouseDown = true")
me.globalMouseDown = true me.globalMouseDown = true
if me.dropdown.active {
w, h := g.MousePosition()
log.Info("mouseDown() stopping here. dropdwon menu is in effect")
for _, tk := range findByXY(w, h) {
if tk.node.WidgetType == widget.Flag {
log.Info("SENDING CLICK TO Dropdown Flag")
tk.doWidgetClick(w, h)
return nil
}
}
log.Info("never found dropdown")
me.dropdown.active = false
return nil
}
var found bool = false var found bool = false
for _, tk := range findByXY(mx, my) { w, h := g.MousePosition()
for _, tk := range findByXY(w, h) {
tk.dumpWidget("mouseDown()") tk.dumpWidget("mouseDown()")
if tk.node.WidgetType == widget.Button { if tk.node.WidgetType == widget.Button {
log.Info("SENDING CLICK TO Button") log.Info("SENDING CLICK TO Button")
tk.doWidgetClick(mx, my) tk.doWidgetClick(w, h)
return nil return nil
} }
if tk.node.WidgetType == widget.Checkbox { if tk.node.WidgetType == widget.Checkbox {
log.Info("SENDING CLICK TO Checkbox") log.Info("SENDING CLICK TO Checkbox")
tk.doWidgetClick(mx, my) tk.doWidgetClick(w, h)
return nil
}
if tk.node.WidgetType == widget.Dropdown {
log.Info("SENDING CLICK TO Dropdown")
tk.doWidgetClick(w, h)
return nil return nil
} }
found = true found = true
} }
mx, my := g.MousePosition()
for _, tk := range findByXY(mx, my) { for _, tk := range findByXY(mx, my) {
if tk.node.WidgetType == widget.Window { if tk.node.WidgetType == widget.Window {
tk.dragW = mx - tk.gocuiSize.w0 tk.dragW = mx - tk.gocuiSize.w0

View File

@ -30,16 +30,18 @@ func (tk *guiWidget) doWidgetClick(w int, h int) {
tk.redrawWindow(w-2, h-2) // TODO: fix these hard coded things with offsets tk.redrawWindow(w-2, h-2) // TODO: fix these hard coded things with offsets
return return
case widget.Group: case widget.Group:
if tk.active { /*
tk.active = false if tk.active {
tk.placeWidgets(tk.startW, tk.startH) tk.active = false
tk.showWidgets() tk.placeWidgets(tk.startW, tk.startH)
} else { tk.showWidgets()
tk.active = true } else {
for _, child := range tk.children { tk.active = true
child.hideWidgets() for _, child := range tk.children {
child.hideWidgets()
}
} }
} */
case widget.Checkbox: case widget.Checkbox:
if tk.node.State.Checked { if tk.node.State.Checked {
log.Log(WARN, "checkbox is being set to false") log.Log(WARN, "checkbox is being set to false")
@ -52,43 +54,36 @@ func (tk *guiWidget) doWidgetClick(w int, h int) {
} }
me.myTree.SendUserEvent(tk.node) me.myTree.SendUserEvent(tk.node)
case widget.Grid: case widget.Grid:
newR := tk.realGocuiSize() /*
newR := tk.realGocuiSize()
// w,h := n.logicalSize() tk.placeGrid(newR.w0, newR.h0)
// w := newR.w1 - newR.w0 tk.showWidgets()
// h := newR.h1 - newR.h0 */
tk.placeGrid(newR.w0, newR.h0)
tk.showWidgets()
case widget.Box: case widget.Box:
if tk.node.State.Direction == widget.Horizontal { /*
log.Log(GOCUI, "BOX IS HORIZONTAL", tk.String()) if tk.node.State.Direction == widget.Horizontal {
} else { log.Log(GOCUI, "BOX IS HORIZONTAL", tk.String())
log.Log(GOCUI, "BOX IS VERTICAL", tk.String()) } else {
} log.Log(GOCUI, "BOX IS VERTICAL", tk.String())
tk.placeWidgets(tk.startW, tk.startH) }
tk.toggleTree() tk.placeWidgets(tk.startW, tk.startH)
tk.toggleTree()
*/
case widget.Button: case widget.Button:
// doUserEvent(n)
me.myTree.SendFromUser(tk.node) me.myTree.SendFromUser(tk.node)
case widget.Combobox: case widget.Combobox:
log.Log(GOCUI, "do the combobox here")
tk.showDropdown() tk.showDropdown()
me.dropdownW = tk
case widget.Dropdown: case widget.Dropdown:
// log.Log(GOCUI, "do the dropdown here")
tk.showDropdown() tk.showDropdown()
me.dropdownW = tk
case widget.Stdout: case widget.Stdout:
log.Log(GOCUI, "stdout widget found!") /*
tk.dumpWidget("stdout click") log.Log(GOCUI, "stdout widget found!")
tk.dumpWidget("stdout click")
*/
case widget.Flag: case widget.Flag:
// log.Log(GOCUI, "flag widget found!")
tk.dropdownClicked(w, h) tk.dropdownClicked(w, h)
// got_ := dropdownClicked(w, h)
// log.Log(GOCUI, "flag click got", got)
default: default:
tk.dumpWidget("blank click()") tk.dumpWidget("undef click()")
} }
} }

View File

@ -29,62 +29,72 @@ var me config
// it got me here, but now it's time to clean it up for good // it got me here, but now it's time to clean it up for good
// I can't get a GO plugins that use protobuf to load yet (versioning mismatch) // I can't get a GO plugins that use protobuf to load yet (versioning mismatch)
type config struct { type config struct {
baseGui *gocui.Gui // the main gocui handle baseGui *gocui.Gui // the main gocui handle
treeRoot *tree.Node // the base of the binary tree. it should have id == 0 treeRoot *tree.Node // the base of the binary tree. it should have id == 0
myTree *tree.TreeInfo // ? myTree *tree.TreeInfo // ?
ctrlDown *tree.Node // shown if you click the mouse when the ctrl key is pressed ctrlDown *tree.Node // shown if you click the mouse when the ctrl key is pressed
currentWindow *guiWidget // this is the current tab or window to show currentWindow *guiWidget // this is the current tab or window to show
helpLabel *gocui.View // ? helpLabel *gocui.View // ?
showHelp bool // toggle boolean for the help menu (deprecate?) showHelp bool // toggle boolean for the help menu (deprecate?)
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)
dtoggle bool // is a dropdown or combobox currently active? 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()
newWindowTrigger chan bool // work around hack to redraw windows a bit after NewWindow() stdout stdout // information for the STDOUT window
stdout stdout // information for the STDOUT window showDebug bool // todo: move this into config struct
showDebug bool // todo: move this into config struct dropdown dropdown // the dropdown menu
} }
// settings for the stdout window // settings for the stdout window
type stdout struct { type stdout struct {
tk *guiWidget // where to show STDOUT tk *guiWidget // where to show STDOUT
w int // the width w int // the width
h int // the width h int // the height
outputOnTop bool // is the STDOUT window on top? outputOnTop bool // is the STDOUT window on top?
outputOffscreen bool // is the STDOUT window offscreen? outputOffscreen bool // is the STDOUT window offscreen?
// offscreenW int // where to place the window offscreen lastW int // the last 'w' location (used to move from offscreen to onscreen)
// offscreenH int // where to place the window offscreen lastH int // the last 'h' location (used to move from offscreen to onscreen)
lastW int // the last 'w' location (used to move from offscreen to onscreen) mouseOffsetW int // the current 'w' offset
lastH int // the last 'h' location (used to move from offscreen to onscreen) mouseOffsetH int // the current 'h' offset
mouseOffsetW int // the current 'w' offset init bool // moves the window offscreen on startup
mouseOffsetH int // the current 'h' offset resize bool // user is resizing the window
init bool // moves the window offscreen on startup }
resize bool // user is resizing the window
// settings for the dropdown window
type dropdown struct {
tk *guiWidget // where to show STDOUT
callerTK *guiWidget // which widget called the dropdown menu
items []string // what is currently in the menu
w int // the width
h int // the height
active bool // is the dropdown menu currently in use?
init bool // moves the window offscreen on startup
// dtoggle bool // is a dropdown or combobox currently active?
} }
// this is the gocui way // this is the gocui way