Added shortcut keys possibility to Menus
This commit is contained in:
parent
fefa34c2b6
commit
ce66bc4bc6
9
main.go
9
main.go
@ -128,7 +128,7 @@ func main() {
|
||||
},
|
||||
)
|
||||
changeFocus(fileSelector)
|
||||
}}, &ui.ItemEntry{Name: "_Save", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "_Save", Shortcut: 's', Callback: func() {
|
||||
if tabContainer.GetTabCount() > 0 {
|
||||
tab := tabContainer.GetTab(tabContainer.GetSelectedTabIdx())
|
||||
te := tab.Child.(*ui.TextEdit)
|
||||
@ -287,6 +287,13 @@ main_loop:
|
||||
if ev.Key() == tcell.KeyCtrlQ { // TODO: replace with shortcut keys in menus
|
||||
break main_loop
|
||||
}
|
||||
|
||||
if ev.Modifiers() & tcell.ModCtrl != 0 {
|
||||
handled := bar.HandleEvent(ev)
|
||||
if handled {
|
||||
continue // Avoid passing the event to the focusedComponent
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
focusedComponent.HandleEvent(ev)
|
||||
|
1
testfile.txt
Executable file
1
testfile.txt
Executable file
@ -0,0 +1 @@
|
||||
wtf thisis a test
|
57
ui/menu.go
57
ui/menu.go
@ -3,6 +3,7 @@ package ui
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/gdamore/tcell/v2"
|
||||
)
|
||||
@ -10,11 +11,6 @@ import (
|
||||
// Item is an interface implemented by ItemEntry and ItemMenu to be listed in Menus.
|
||||
type Item interface {
|
||||
GetName() string
|
||||
// GetShortcut returns the shortcut character to activate the Item without opening
|
||||
// the Menu. For example, if the shortcut were 'a', then the user would have to press
|
||||
// `Ctrl + a`. If the shortcut were 'A', then the user would press `Ctrl + Shift + a`.
|
||||
// The zero value means "no shortcut".
|
||||
GetShortcut() rune
|
||||
}
|
||||
|
||||
// An ItemSeparator is like a blank Item that cannot actually be selected. It is useful
|
||||
@ -26,15 +22,11 @@ func (i *ItemSeparator) GetName() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (i *ItemSeparator) GetShortcut() rune {
|
||||
return 0
|
||||
}
|
||||
|
||||
// ItemEntry is a listing in a Menu with a name and callback.
|
||||
type ItemEntry struct {
|
||||
Name string
|
||||
Callback func()
|
||||
Shortcut rune
|
||||
Callback func()
|
||||
}
|
||||
|
||||
// GetName returns the name of the ItemEntry.
|
||||
@ -42,19 +34,11 @@ func (i *ItemEntry) GetName() string {
|
||||
return i.Name
|
||||
}
|
||||
|
||||
func (i *ItemEntry) GetShortcut() rune {
|
||||
return i.Shortcut
|
||||
}
|
||||
|
||||
// GetName returns the name of the Menu.
|
||||
func (m *Menu) GetName() string {
|
||||
return m.Name
|
||||
}
|
||||
|
||||
func (m *Menu) GetShortcut() rune {
|
||||
return 0 // Menus don't have shortcuts
|
||||
}
|
||||
|
||||
// A MenuBar is a horizontal list of menus.
|
||||
type MenuBar struct {
|
||||
ItemSelectedCallback func()
|
||||
@ -211,6 +195,24 @@ func (b *MenuBar) SetSize(width, height int) {
|
||||
func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
||||
switch ev := event.(type) {
|
||||
case *tcell.EventKey:
|
||||
// Shortcuts (Ctrl + s or Ctrl + (Shift) A, for example)
|
||||
if ev.Modifiers() & tcell.ModCtrl != 0 {
|
||||
// tcell calls Ctrl + rune keys "Ctrl-(RUNE)" so we want to remove the "Ctrl-"
|
||||
// prefix, and turn the remaining part of the string into a rune.
|
||||
keyRune := []rune(tcell.KeyNames[ev.Key()][5:])[0]
|
||||
|
||||
keyRune = unicode.ToLower(keyRune) // Make the rune lowercase.
|
||||
|
||||
// Find who the shortcut key belongs to
|
||||
for i := range b.menus {
|
||||
handled := b.menus[i].handleShortcut(keyRune)
|
||||
if handled {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false // The shortcut key was not handled by any menus
|
||||
}
|
||||
|
||||
switch ev.Key() {
|
||||
case tcell.KeyEnter:
|
||||
if !b.menusVisible { // If menus are not visible...
|
||||
@ -229,6 +231,7 @@ func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
||||
b.CursorRight()
|
||||
}
|
||||
|
||||
// Quick char
|
||||
case tcell.KeyRune: // Search for the matching quick char in menu names
|
||||
if !b.menusVisible { // If the selected Menu is not open/visible
|
||||
for i, m := range b.menus {
|
||||
@ -397,6 +400,24 @@ func (m *Menu) SetSize(width, height int) {
|
||||
// Cannot set the size of a Menu
|
||||
}
|
||||
|
||||
func (m *Menu) handleShortcut(r rune) bool {
|
||||
for i := range m.Items {
|
||||
switch typ := m.Items[i].(type) {
|
||||
case *ItemSeparator:
|
||||
continue
|
||||
case *Menu:
|
||||
return typ.handleShortcut(r) // Have the sub-menu handle the shortcut
|
||||
case *ItemEntry:
|
||||
if typ.Shortcut == r { // If this item matches the shortcut we're finding...
|
||||
m.selected = i
|
||||
m.ActivateItemUnderCursor() // Activate it
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// HandleEvent will handle events for a Menu and may propogate them
|
||||
// to sub-menus. Returns true if the event was handled.
|
||||
func (m *Menu) HandleEvent(event tcell.Event) bool {
|
||||
|
Loading…
x
Reference in New Issue
Block a user