gocui/dropdown.go

191 lines
5.0 KiB
Go
Raw Normal View History

2025-02-01 11:42:31 -06:00
// 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"
"strings"
log "go.wit.com/log"
"go.wit.com/toolkits/tree"
"go.wit.com/widget"
)
// dropdowns don't exist so this is an attempt to pretend they exist
// by having a fake window view in gocui that appears with the dropdown
// items. by detecting where the user clicks, we should be
// able to set the text of the button to that value (and
// rezise it.
// the thing is this is so damned complicated because it
// is very hard to debug this. thanks to the floating on
// screen debugging output I might be able to figure it
// it out now. maybe. notsure.
func makeDropdownView(ddItems string) *guiWidget {
newNode := addDropdown()
tk := newNode.TK.(*guiWidget)
tk.labelN = ddItems
tk.SetText(ddItems)
tk.gocuiSize.w0 = 100
tk.gocuiSize.w1 = 120
tk.gocuiSize.h0 = 15
tk.gocuiSize.h1 = 18
tk.v, _ = me.baseGui.SetView("ddview",
tk.gocuiSize.w0,
tk.gocuiSize.h0,
tk.gocuiSize.w1,
tk.gocuiSize.h1, 0)
if tk.v == nil {
return tk
}
tk.v.Wrap = true
tk.v.Frame = true
tk.v.Clear()
fmt.Fprint(tk.v, ddItems)
tk.Show()
return tk
}
2025-02-02 23:36:33 -06:00
func addDropdownTK(wId int) *guiWidget {
n := addDropdownNew(wId)
return n.TK.(*guiWidget)
}
func addDropdownNew(wId int) *tree.Node {
n := new(tree.Node)
n.WidgetType = widget.Flag
2025-02-02 23:36:33 -06:00
n.WidgetId = wId
n.ParentId = 0
// store the internal toolkit information
tk := new(guiWidget)
tk.frame = true
tk.labelN = "DropBox text"
tk.node = n
2025-02-05 07:24:14 -06:00
if tk.node.Parent == nil {
tk.node.Parent = me.treeRoot
}
// copy the data from the action message
tk.node.State.Label = "DropBox"
// set the name used by gocui to the id
2025-02-02 23:36:33 -06:00
tk.cuiName = fmt.Sprintf("%d DR", wId)
tk.color = &colorFlag
// add this new widget on the binary tree
tk.parent = me.treeRoot.TK.(*guiWidget)
if tk.parent == nil {
panic("addDropdown() didn't get treeRoot guiWidget")
} else {
tk.parent.children = append(tk.parent.children, tk)
}
n.TK = tk
return n
}
func (tk *guiWidget) showDropdown() {
// todo: fix this after switching to protobuf
2025-02-06 05:41:51 -06:00
me.dropdown.items = []string{} // zero out whatever was there before
for i, s := range tk.node.Strings() {
log.Log(GOCUI, "showDropdown()", tk.String(), i, s)
me.dropdown.items = append(me.dropdown.items, s)
}
2025-02-06 05:41:51 -06:00
log.Log(GOCUI, "new dropdown items should be set to:", me.dropdown.items)
if me.dropdown.tk == nil {
me.dropdown.tk = addDropdownTK(-77)
}
2025-02-06 05:41:51 -06:00
if me.dropdown.tk == nil {
log.Log(GOCUI, "showDropdown() IS BROKEN")
return
}
2025-02-06 05:41:51 -06:00
startW, startH := tk.Position()
log.Log(GOCUI, "showDropdown() SHOWING AT W,H=", startW, startH)
me.dropdown.tk.MoveToOffset(startW+3, startH+2)
me.dropdown.tk.labelN = strings.Join(me.dropdown.items, "\n")
me.dropdown.tk.Show()
me.dropdown.active = true
me.dropdown.callerTK = tk
}
// 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 {
w.Hide()
2025-02-01 15:57:29 -06:00
// only need height to figure out what line in the dropdown menu the user clicked
_, startH := w.Position()
// startW, startH := w.Position()
// log.Log(GOCUI, "dropdownClicked() start (w,h) =", startW, startH)
// log.Log(GOCUI, "dropdownClicked() at (w,h) =", mouseW, mouseH)
itemNumber := mouseH - startH
2025-02-06 05:41:51 -06:00
items := me.dropdown.items
2025-02-01 15:57:29 -06:00
// log.Log(GOCUI, "dropdownClicked() look for item", itemNumber, "len(items) =", len(items))
if itemNumber < 1 {
return ""
}
if len(items) >= itemNumber {
2025-02-01 15:57:29 -06:00
// log.Log(GOCUI, "dropdownClicked() found", items[itemNumber-1])
if items[itemNumber-1] != "" {
2025-02-06 05:41:51 -06:00
if me.dropdown.tk != nil {
2025-02-01 15:57:29 -06:00
// log.Log(GOCUI, "dropdownClicked() send event for", me.dropdownW.cuiName, me.dropdownW.node.WidgetType)
2025-02-06 05:41:51 -06:00
me.dropdown.callerTK.SetText(items[itemNumber-1])
me.dropdown.callerTK.node.SetCurrentS(items[itemNumber-1])
me.myTree.SendUserEvent(me.dropdown.callerTK.node)
}
}
return items[itemNumber-1]
}
return ""
}
2025-01-31 16:05:34 -06:00
var dtoggle bool = false // temporarily tracking show & hide
var doffset int = 5 // how many spaces over the dropdown menu should be from the mouse
2025-01-31 10:03:56 -06:00
2025-01-31 12:36:46 -06:00
func dropdownUnclicked(w, h int) {
var d *guiWidget
2025-02-01 18:48:08 -06:00
/*
if me.dropdownV == nil {
log.Log(GOCUI, "mouseUp() dropdownV = nil")
return
}
*/
// examine everything under X & Y on the screen)
2025-01-31 12:36:46 -06:00
for _, tk := range findByXY(w, h) {
2025-02-01 13:58:53 -06:00
// tk.dumpWidget("dropdownUnclicked()")
if tk.node.WidgetType == widget.Dropdown {
2025-01-31 12:36:46 -06:00
d = tk
}
}
if d == nil {
2025-01-31 12:36:46 -06:00
// log.Log(GOCUI, fmt.Sprintf("dropdownUnclicked() there was no dropdown widget at (w=%d h=%d)", mouseW, mouseH))
return
}
2025-01-31 22:56:05 -06:00
// log.Log(GOCUI, "dropdownUnclicked()", d.node.Strings(), "end. now try to enable me.dropdownV")
2025-02-01 18:48:08 -06:00
/*
dtext := strings.Join(d.node.Strings(), "\n")
tk := me.dropdownV
if dtoggle {
// log.Log(GOCUI, "dropdownUnclicked() set visible=false")
tk.Hide()
dtoggle = false
tk.SetText("goodbye")
} else {
// log.Log(GOCUI, "dropdownUnclicked() set visible=true")
tk.MoveToOffset(w+doffset, h)
tk.SetText(dtext)
tk.Show()
dtoggle = true
}
*/
}