From 6d4df573936e16fa3366f670269538aebef35276 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Tue, 8 Aug 2023 13:26:26 +0200 Subject: [PATCH] Add option to add sections to menus --- pkg/gui/context/menu_context.go | 35 +++++++++++++++++++++++++++++++++ pkg/gui/types/common.go | 13 ++++++++++++ 2 files changed, 48 insertions(+) diff --git a/pkg/gui/context/menu_context.go b/pkg/gui/context/menu_context.go index 30fe8a4b4..287ed92ec 100644 --- a/pkg/gui/context/menu_context.go +++ b/pkg/gui/context/menu_context.go @@ -38,6 +38,7 @@ func NewMenuContext( list: viewModel, getDisplayStrings: viewModel.GetDisplayStrings, getColumnAlignments: func() []utils.Alignment { return viewModel.columnAlignment }, + getNonModelItems: viewModel.GetNonModelItems, }, c: c, }, @@ -113,6 +114,40 @@ func (self *MenuViewModel) GetDisplayStrings(_ int, _ int) [][]string { }) } +func (self *MenuViewModel) GetNonModelItems() []*NonModelItem { + // Don't display section headers when we are filtering. The reason is that + // filtering changes the order of the items (they are sorted by best match), + // so all the sections would be messed up. + if self.FilteredListViewModel.IsFiltering() { + return []*NonModelItem{} + } + + result := []*NonModelItem{} + menuItems := self.FilteredListViewModel.GetItems() + var prevSection *types.MenuSection = nil + for i, menuItem := range menuItems { + menuItem := menuItem + if menuItem.Section != nil && menuItem.Section != prevSection { + if prevSection != nil { + result = append(result, &NonModelItem{ + Index: i, + Column: 1, + Content: "", + }) + } + + result = append(result, &NonModelItem{ + Index: i, + Column: 1, + Content: style.FgGreen.SetBold().Sprintf("--- %s ---", menuItem.Section.Title), + }) + prevSection = menuItem.Section + } + } + + return result +} + func (self *MenuContext) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding { basicBindings := self.ListContextTrait.GetKeybindings(opts) menuItemsWithKeys := lo.Filter(self.menuItems, func(item *types.MenuItem, _ int) bool { diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 919c15b0e..0b6a8e430 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -177,6 +177,11 @@ type PromptOpts struct { Mask bool } +type MenuSection struct { + Title string + Column int // The column that this section title should be aligned with +} + type MenuItem struct { Label string @@ -194,6 +199,14 @@ type MenuItem struct { // The tooltip will be displayed upon highlighting the menu item Tooltip string + + // Can be used to group menu items into sections with headers. MenuItems + // with the same Section should be contiguous, and will automatically get a + // section header. If nil, the item is not part of a section. + // Note that pointer comparison is used to determine whether two menu items + // belong to the same section, so make sure all your items in a given + // section point to the same MenuSection instance. + Section *MenuSection } type Model struct {