Added quick chars to MenuBar and Menus
This commit is contained in:
parent
83567c1341
commit
ffaad36c78
22
main.go
22
main.go
@ -70,12 +70,12 @@ func main() {
|
||||
|
||||
barFocused := false
|
||||
|
||||
fileMenu := ui.NewMenu("File", &theme)
|
||||
fileMenu := ui.NewMenu("_File", &theme)
|
||||
|
||||
fileMenu.AddItems([]ui.Item{&ui.ItemEntry{Name: "New File", Callback: func() {
|
||||
fileMenu.AddItems([]ui.Item{&ui.ItemEntry{Name: "_New File", Callback: func() {
|
||||
textEdit := ui.NewTextEdit(&s, "", "", &theme) // No file path, no contents
|
||||
tabContainer.AddTab("noname", textEdit)
|
||||
}}, &ui.ItemEntry{Name: "Open...", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "_Open...", Callback: func() {
|
||||
callback := func(filePaths []string) {
|
||||
for _, path := range filePaths {
|
||||
file, err := os.Open(path)
|
||||
@ -109,7 +109,7 @@ func main() {
|
||||
},
|
||||
)
|
||||
changeFocus(fileSelector)
|
||||
}}, &ui.ItemEntry{Name: "Save", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "_Save", Callback: func() {
|
||||
if tabContainer.GetTabCount() > 0 {
|
||||
tab := tabContainer.GetTab(tabContainer.GetSelectedTabIdx())
|
||||
te := tab.Child.(*ui.TextEdit)
|
||||
@ -124,7 +124,7 @@ func main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}}, &ui.ItemEntry{Name: "Save As...", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "Save _As...", Callback: func() {
|
||||
// TODO: implement a "Save as" dialog system, and show that when trying to save noname files
|
||||
callback := func(filePaths []string) {
|
||||
fileSelector = nil // Hide the file selector
|
||||
@ -142,14 +142,14 @@ func main() {
|
||||
},
|
||||
)
|
||||
changeFocus(fileSelector)
|
||||
}}, &ui.ItemSeparator{}, &ui.ItemEntry{Name: "Exit", Callback: func() {
|
||||
}}, &ui.ItemSeparator{}, &ui.ItemEntry{Name: "E_xit", Callback: func() {
|
||||
s.Fini()
|
||||
os.Exit(0)
|
||||
}}})
|
||||
|
||||
editMenu := ui.NewMenu("Edit", &theme)
|
||||
editMenu := ui.NewMenu("_Edit", &theme)
|
||||
|
||||
editMenu.AddItems([]ui.Item{&ui.ItemEntry{Name: "Cut", Callback: func() {
|
||||
editMenu.AddItems([]ui.Item{&ui.ItemEntry{Name: "_Cut", Callback: func() {
|
||||
if tabContainer.GetTabCount() > 0 {
|
||||
tab := tabContainer.GetTab(tabContainer.GetSelectedTabIdx())
|
||||
te := tab.Child.(*ui.TextEdit)
|
||||
@ -160,7 +160,7 @@ func main() {
|
||||
_ = ClipWrite(selectedStr) // Add the selectedStr to clipboard
|
||||
}
|
||||
}
|
||||
}}, &ui.ItemEntry{Name: "Copy", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "_Copy", Callback: func() {
|
||||
if tabContainer.GetTabCount() > 0 {
|
||||
tab := tabContainer.GetTab(tabContainer.GetSelectedTabIdx())
|
||||
te := tab.Child.(*ui.TextEdit)
|
||||
@ -169,7 +169,7 @@ func main() {
|
||||
_ = ClipWrite(selectedStr) // Add selectedStr to clipboard
|
||||
}
|
||||
}
|
||||
}}, &ui.ItemEntry{Name: "Paste", Callback: func() {
|
||||
}}, &ui.ItemEntry{Name: "_Paste", Callback: func() {
|
||||
if tabContainer.GetTabCount() > 0 {
|
||||
tab := tabContainer.GetTab(tabContainer.GetSelectedTabIdx())
|
||||
te := tab.Child.(*ui.TextEdit)
|
||||
@ -182,7 +182,7 @@ func main() {
|
||||
}
|
||||
}}})
|
||||
|
||||
searchMenu := ui.NewMenu("Search", &theme)
|
||||
searchMenu := ui.NewMenu("_Search", &theme)
|
||||
|
||||
searchMenu.AddItems([]ui.Item{&ui.ItemEntry{Name: "New", Callback: func() {
|
||||
s.Beep()
|
||||
|
@ -15,11 +15,33 @@ func DrawRect(s tcell.Screen, x, y, width, height int, char rune, style tcell.St
|
||||
// DrawStr will render each character of a string at `x` and `y`.
|
||||
func DrawStr(s tcell.Screen, x, y int, str string, style tcell.Style) {
|
||||
runes := []rune(str)
|
||||
for idx := 0; idx < len(runes); idx++ {
|
||||
s.SetContent(x+idx, y, runes[idx], nil, style)
|
||||
for idx, r := range runes {
|
||||
s.SetContent(x+idx, y, r, nil, style)
|
||||
}
|
||||
}
|
||||
|
||||
// DrawQuickCharStr renders a string very similar to how DrawStr works, but stylizes the
|
||||
// quick char (any rune after an underscore) with an underline. Returned is the number of
|
||||
// columns that were drawn to the screen. This is useful to know the length of the string
|
||||
// drawn, minus the underscore.
|
||||
func DrawQuickCharStr(s tcell.Screen, x, y int, str string, style tcell.Style) int {
|
||||
runes := []rune(str)
|
||||
col := 0
|
||||
for i := 0; i < len(runes); i++ {
|
||||
r := runes[i]
|
||||
if r == '_' && i+1 < len(runes) {
|
||||
i++
|
||||
sty := style.Underline(true)
|
||||
|
||||
s.SetContent(x+col, y, runes[i], nil, sty)
|
||||
} else {
|
||||
s.SetContent(x+col, y, r, nil, style)
|
||||
}
|
||||
col++
|
||||
}
|
||||
return col
|
||||
}
|
||||
|
||||
// DrawRectOutline draws only the outline of a rectangle, using `ul`, `ur`, `bl`, and `br`
|
||||
// for the corner runes, and `hor` and `vert` for the horizontal and vertical runes, respectively.
|
||||
func DrawRectOutline(s tcell.Screen, x, y, _width, _height int, ul, ur, bl, br, hor, vert rune, style tcell.Style) {
|
||||
|
30
ui/menu.go
30
ui/menu.go
@ -90,13 +90,14 @@ func (b *MenuBar) Draw(s tcell.Screen) {
|
||||
col := b.x + 1
|
||||
for i, item := range b.Menus {
|
||||
str := fmt.Sprintf(" %s ", item.Name) // Surround the name in spaces
|
||||
var sty tcell.Style
|
||||
if b.selected == i && b.focused { // If we are drawing the selected item ...
|
||||
sty = b.Theme.GetOrDefault("MenuBarSelected") // Use style for selected items
|
||||
} else {
|
||||
sty = normalStyle
|
||||
|
||||
sty := normalStyle
|
||||
if b.focused && b.selected == i {
|
||||
sty = b.Theme.GetOrDefault("MenuBarSelected") // Use special style for selected item
|
||||
}
|
||||
DrawStr(s, col, b.y, str, sty)
|
||||
|
||||
DrawQuickCharStr(s, col, b.y, str, sty)
|
||||
|
||||
col += len(str)
|
||||
}
|
||||
|
||||
@ -185,14 +186,16 @@ func (b *MenuBar) HandleEvent(event tcell.Event) bool {
|
||||
|
||||
case tcell.KeyRune: // Search for the matching quick char in menu names
|
||||
if !b.menusVisible { // If the selected Menu is not open/visible
|
||||
for _, m := range b.Menus {
|
||||
for i, m := range b.Menus {
|
||||
found, r := QuickCharInString(m.Name)
|
||||
if found && r == ev.Rune() {
|
||||
b.menusVisible = true
|
||||
|
||||
b.selected = i
|
||||
menu := &b.Menus[b.selected]
|
||||
(*menu).SetPos(b.GetMenuXPos(b.selected), b.y+1)
|
||||
(*menu).SetFocused(true)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -306,9 +309,11 @@ func (m *Menu) Draw(s tcell.Screen) {
|
||||
} else {
|
||||
sty = defaultStyle
|
||||
}
|
||||
itemName := item.GetName()
|
||||
str := fmt.Sprintf("%s%s", itemName, strings.Repeat(" ", m.width-2-len(itemName)))
|
||||
DrawStr(s, m.x+1, m.y+1+i, str, sty)
|
||||
|
||||
len := DrawQuickCharStr(s, m.x+1, m.y+1+i, item.GetName(), sty)
|
||||
|
||||
str := strings.Repeat(" ", m.width-2-len) // Fill space after menu names to border
|
||||
DrawStr(s, m.x+1+len, m.y+1+i, str, sty)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -368,10 +373,13 @@ func (m *Menu) HandleEvent(event tcell.Event) bool {
|
||||
case tcell.KeyRune:
|
||||
// TODO: support quick chars for sub-menus
|
||||
for i, item := range m.Items {
|
||||
if m.selected == i {
|
||||
continue // Skip the item we're on
|
||||
}
|
||||
found, r := QuickCharInString(item.GetName())
|
||||
if found && r == ev.Rune() {
|
||||
m.selected = i
|
||||
m.ActivateItemUnderCursor()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ var DefaultTheme = Theme{
|
||||
"MenuBarSelected": tcell.Style{}.Foreground(tcell.ColorSilver).Background(tcell.ColorBlack),
|
||||
"Menu": tcell.Style{}.Foreground(tcell.ColorBlack).Background(tcell.ColorSilver),
|
||||
"MenuSelected": tcell.Style{}.Foreground(tcell.ColorSilver).Background(tcell.ColorBlack),
|
||||
"QuickChar": tcell.Style{}.Foreground(tcell.ColorYellow).Background(tcell.ColorBlack),
|
||||
"Tab": tcell.Style{}.Foreground(tcell.ColorSilver).Background(tcell.ColorBlack),
|
||||
"TabContainer": tcell.Style{}.Foreground(tcell.ColorSilver).Background(tcell.ColorBlack),
|
||||
"TabSelected": tcell.Style{}.Foreground(tcell.ColorBlack).Background(tcell.ColorSilver),
|
||||
|
Loading…
x
Reference in New Issue
Block a user