HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Modulebrick-3.0Haskell2010

Brick.Widgets.Menu

This module provides a menu widget that is similar to the ones commonly found in most graphical interface toolkits. Menus carry entries that can be activated with the mouse and keyboard and invoke event handlers that you specify when creating the menus and entries.

General Information

Menus carry a sequence of items, expressed by the MenuItem type. Items can be:

  • entries - named menu items that can be activated with the keyboard or mouse

  • submenus - entries that contain nested menus

  • separators - horizontal lines dividing up groups of other entries

  • gaps - vertical space between items

Menu entries can be either enabled or disabled; their status in this regard is determined by invoking a function of type s -> Bool at rendering and event-handling time.

Menus and submenus support both mouse and keyboard interaction. See handleMenuEvent for details.

Menus have an orientation that can be changed with setMenuOrientation to suit different writing systems. This affects how entries and submenus are rendered and how left/right arrow keys navigate submenus.

Use Cases

This module provides a fully general Menu type and a few specialized menu types for common menu use cases:

  • SimpleMenu: a menu with entries that have EventM handlers. Create one of these with simpleMenu. This is a good starting point.

  • DispatchingMenu: a menu whose entries correspond to abstract key events bound to keys by a KeyDispatcher. Create one of these with menuWithDispatcher. This is a good choice when you already have a KeyDispatcher set up and would like menu entries to be triggered by the rebindable keys that trigger the dispatcher's handlers.

  • Menu: the fully general type for menus. Create one of these with menu.

Depending on the type of menu you're creating, different item constructors may apply. See the MenuItem type aliases since their naming convention follows that of the menu types.

See the MenuDemo and MenuKeybindingsDemo demonstration programs for complete working examples of using this API.

Adding Menus to An Application

To use this module in an application:

  • Choose a menu type that you want to work with such as SimpleMenu.

  • For each menu that you want to host, add an application state field and lens for a value of the menu's type, and add a constructor to the application's resource name type, with an argument of type MenuRegion. Add lenses to the application state type with makeLenses.

  • Populate the application's initial state with the menus.

  • Render menus with renderMenu.

  • Handle incoming events first with handleMenuEvent, and when handleMenuEvent returns False, pass unhandled events on to the existing application event handler.

  • As desired, add entries to the application's AttrMap for the attributes used in this module.

Use MenuBar if you want to host more than one menu in a group.

Handling Events

Menu events are handled with handleMenuEvent, and any unhandled events should be deferred to the application's event handler.

To support mouse events, each menu must be identified by a unique resource name; this is done by providing a resource name constructor when creating each menu. The application's name type must provide a constructor of type MenuRegion -> n to uniquely identify the menu and its constituent parts. For example, if the application's resource name type is as follows,

data Name = Editor1 | Editor2

It would need to be modified so that a new data constructor (e.g. FileMenu) could be given to the menu constuctors:

data Name = Editor1 | Editor2 | FileMenu MenuRegion
  • 9 types
  • 34 values
  • Packagebrick-3.0
  • Exports43
  • LanguageHaskell2010
  • LicenceBSD-3-Clause
  • SourceMenu.hs
datadata Menu s n k
#

The general menu type.

Menus and their items are parameterized on three types:

  • s: the application state type used in the App type,

  • n: the application resource name type used in the application's Widget type, and

  • k: the type of data carried and handled by the menu's event handler when a menu entry has been activated.

Menus contain a sequence of items of type MenuItem. See the documentation above and the constructors for both menus and menu items to create menus.

A menu is either open, in which case its contents are being shown in a floating layer above the application's UI and it is responding to events that manipulate the menu's selected entry, or it is closed, in which case its contents are not shown and it is not responding to events other than mouse clicks on its title. The menu's open/closed state is affected by calls to openMenu, closeMenu, and mouse click events on the menu's title.

At any given time, a menu may or may not have a currently-selected entry. See handleMenuEvent for details on how keyboard and mouse events influence the choice and behavior of the selected entry. When an entry is selected, it can be activated by an Enter keypress or a mouse click. When activated, its event data is used to invoke the menu's event handler.

To support mouse events, each menu must be identified by a unique resource name; this is done by providing a resource name constructor when creating each menu. The application's name type must provide a constructor of type MenuRegion -> n to uniquely identify the menu and its constituent parts.

A menu carries an event handler that will be invoked by handleMenuEvent whenever a menu entry is selected.

valuemenuContentWidth :: Menu s n k -> Int
#

The width of the menu's items within the enclosing border. This is a record accessor so it can also be used to change the menu's width.

valuemenuTitleName :: Menu s n k -> n
#

The resource name for this menu's title for generating and detecting mouse click events

datadata MenuRegion
#

The type of menu regions for embedding in the application's resource name and reporting mouse click events.

Constructors

Instances3Eq, Ord, Show
datadata MenuOrientation
#

Orientation for menu contents.

Constructors

  • LeftToRight

    Menu entries are laid out with labels on the left and submenus opening to the right

  • RightToLeft

    Menu entries are laid out with labels on the right and submenus opening to the left

Instances3Eq, Ord, Show
valuecloseMenu :: Menu s n k -> Menu s n k
#

Close a menu and unselect any selected entry. Also closes any open submenus in the menu, recursively.

Constructing menus and items

6 declarations
valuemenu
  1. :: Text

    The menu's title

  2. -> (MenuRegion -> n)

    The menu's resource name constructor

  3. -> [MenuItem s n k]

    The items in this menu

  4. -> (k -> EventM n s ())

    The event handler to invoke when entries are activated

  5. -> Menu s n k
#

Create a Menu.

By default, menus use the LeftToRight content orientation. This can be changed with setMenuOrientation.

By default, entries are rendered using txt. Change this with setDefaultEntryRenderer or setEntryRenderer.

By default, the menu title is rendered using txt. Change this with setTitleRenderer.

datadata MenuItem s n k
#

The type of menu items.

valuemenuEntry
  1. :: Text

    The menu entry's label

  2. -> k

    The event data carried by the menu entry that will be passed to the enclosing menu's event handler when this entry is activated

  3. -> MenuItem s n k
#

Create a menu entry with the specified label and event data. When the entry is activated, its event data will be passed to the event handler of the enclosing menu.

By default, this entry has no custom renderer so its appearance is determined by the default entry renderer of the enclosing menu. To change either of these behaviors, use setEntryRenderer or setDefaultEntryRenderer.

By default, this entry is always enabled regardless of the application state. To change this, use setEnabledWith.

This is the fully general entry constructor. For more specific use cases, see the other MenuItem constructors in this module.

valuesubmenu :: Menu s n k -> MenuItem s n k
#

A submenu. The menu's title will be used as the submenu's label in its parent menu.

Configuring menus

4 declarations

Configuring menu items

2 declarations
valuesetEnabledWith :: (s -> Bool) -> MenuItem s n k -> MenuItem s n k
#

Set this menu entry's function used to check for its enabled state. This is equivalent to id for non-entry items.

Menus with EventM handlers

3 declarations
typetype SimpleMenu s n = Menu s n (EventM n s ())
#

A specialization of Menu that has EventM handlers in each menu entry that are evaluated whenever the entries are activated. Create one of these with simpleMenu.

Menus with custom keybindings

8 declarations
valuemenuWithDispatcher
  1. :: Eq k
  2. => KeyDispatcher k (EventM n s)

    The key dispatcher to use to build the menu, and whose handlers should be invoked by the menu's entries when activated

  3. -> Text

    The menu's title

  4. -> (MenuRegion -> n)

    The menu's resource name constructor

  5. -> [DispatchingMenuItem s n k]

    The items in this menu

  6. -> DispatchingMenu s n k
#

Create a Menu whose entries are activated by specific triggers, including specified key bindings or abstract key events associated with a KeyDispatcher. This uses entryWithKeybinding as its default entry renderer to show available keybindings for entries associated with key events.

To create entries in this menu, use menuEntryForKey, menuEntryForEvent, and menuEntryForAction.

valuemenuEntryForKey
  1. :: Text

    The menu entry's label

  2. -> Binding

    The specific key binding to trigger this menu entry

  3. -> DispatchingMenuItem s n k
#

Create a menu entry that is activated by the specified key binding, irrespective of the enclosing menu's KeyDispatcher configuration. This entry will show the specified keybinding in its text.

valuemenuEntryForEvent
  1. :: Text

    The menu entry's label

  2. -> k

    The abstract key event to generate when this entry is activated

  3. -> DispatchingMenuItem s n k
#

Create a menu entry that generates the specified abstract key event when activated, thus triggering the enclosing menu's KeyDispatcher handler for that event. This entry will show the first known keybinding for the specified abstract key event, if any.

valuemenuEntryForAction
  1. :: Text

    The menu entry's label

  2. -> EventM n s ()

    The action to evaluate when this entry is activated

  3. -> DispatchingMenuItem s n k
#

Create a menu entry that invokes the specified EventM action when activated. Use this for entries that are not invoked by specific keys or associated with abstract key events.

Handling events

1 declaration
valuehandleMenuEvent
  1. :: Eq n
  2. => Traversal' s (Menu s n k)

    The traversal into the application state where the menu state can be found

  3. -> BrickEvent n e

    The event to handle

  4. -> EventM n s Bool
#

Handle an event for this menu and return True, or return False if the event was not handled (e.g. because the event was not a menu title mouse click or because the menu was not open to receive the event).

Events handled include:

  • Mouse clicks on the menu title will toggle whether the menu is open.

  • If a submenu entry is selected, arrow keys will open and close it depending on the menu orientation.

  • Mouse clicks on submenu entries will open their submenus.

  • Esc will close the menu if no submenus are open; otherwise it will close the last open submenu.

  • If no entry is selected, the Down arrow key will select the first entry and the Up arrow key will select the last entry.

  • If an entry is selected, the Down arrow key will select the next entry and the Up arrow key will select the previous entry.

  • If the selected entry is a submenu and the submenu is open, events will be delegated to the submenu until it closes.

In all other cases, this will attempt to defer to the menu's selected entry or submenu to handle the event. This returns True if the event was one of the above and was handled, True if the event was not one of the above but was handled by the menu's selected entry, or False otherwise.

A return value of True indicates that the event should not be handled by the application because it was destined for the menu; a return value of False indicates that the event should be handled by the application because it did not affect the menu or its entries in their current state for any reason. Consequently, a common pattern when using this function will look something like this:

myApplicationEventHandler :: BrickEvent n e -> EventM n s ()
myApplicationEventHandler e = do
    handled <- handleMenuEvent myMenuLens e
    when (not handled) $ do
        -- Go on to handle the event in the rest of the application

Rendering menus

1 declaration
valuerenderMenu :: Ord n => s -> Menu s n k -> Widget n
#

Render a menu.

If the menu is closed, only its title is rendered. If the menu is open, its title is rendered with its contents shown as a floating layer vertically positioned below the title.

When menu contents are shown, they are rendered in a border, and separators are rendered with hBorder. Use withBorderStyle to change how such borders are drawn, e.g.,

drawUi :: s -> Widget n
drawUi s =
    withBorderStyle unicodeRounded $
    renderMenu s (s^.myMenu)

Attributes

9 declarations