pub struct Menu<'a> { /* private fields */ }Expand description
An anchored, scrollable, keyboard-navigable popup: the shared core of a dropdown, a combobox’s open list, and a command palette.
Draws whatever capacity = surface.height() of this menu’s own rows the current
MenuState::offset window covers, top-aligned. When more rows exist above/below that
window, the first/last drawn row becomes a ^/v overflow indicator instead of silently
truncating – call MenuState::ensure_visible before rendering (as Menu::show already
does) to keep the selection inside the window.
This is the “anchored-popup core” alone: it draws rows and resolves a click/scroll/keyboard
gesture against them, but has no opinion on where the popup sits relative to whatever
anchored it (a menu-bar label, a combobox field, …) – that placement is the caller’s job,
same as Modal leaves centering to centered_rect
rather than owning it itself.
Menu::show is the documented way to drive one open menu end-to-end each frame (drawing,
hover/click/scroll, and click-outside dismissal); StatefulWidget::render is the lower-level
draw-only half for a caller composing its own interaction (e.g. a menu bar switching which of
several menus is open).
item_style/selected_style/disabled_style/separator_style/label_style/
overflow_style default to Theme::DARK (as if Menu::theme had been called); set a
different Theme with Menu::theme/Menu::theme_on or override a single field with
the matching builder method.
§Examples
use retroglyph_core::grid::{Grid, Rect};
use retroglyph_ui::state::MenuState;
use retroglyph_ui::widget::{Marker, Menu, MenuRow, StatefulWidget};
use retroglyph_ui::Surface;
let rows = [
MenuRow::Item { label: "Cut", marker: Marker::None, enabled: false },
MenuRow::Separator,
MenuRow::Item { label: "Copy", marker: Marker::None, enabled: true },
MenuRow::Item { label: "Word Wrap", marker: Marker::Checkbox(true), enabled: true },
];
let mut state = MenuState::new();
state.open(rows.len(), |i| rows[i].is_selectable());
let area = Rect::new(0, 0, 16, 4);
let mut grid = Grid::new(16, 4);
Menu::new(&rows).render(&mut Surface::new(&mut grid, area, 0), &mut state);Implementations§
Source§impl<'a> Menu<'a>
impl<'a> Menu<'a>
Sourcepub fn new(rows: &'a [MenuRow<'a>]) -> Self
pub fn new(rows: &'a [MenuRow<'a>]) -> Self
A menu over rows, styled from Theme::DARK (as if Menu::theme had been called).
Sourcepub const fn item_style(self, style: Style) -> Self
pub const fn item_style(self, style: Style) -> Self
Set the style of a plain, enabled, unselected MenuRow::Item.
Sourcepub const fn selected_style(self, style: Style) -> Self
pub const fn selected_style(self, style: Style) -> Self
Set the style of the selected row, including its background fill.
Sourcepub const fn disabled_style(self, style: Style) -> Self
pub const fn disabled_style(self, style: Style) -> Self
Set the style of a disabled MenuRow::Item.
Sourcepub const fn separator_style(self, style: Style) -> Self
pub const fn separator_style(self, style: Style) -> Self
Set the style of a MenuRow::Separator line.
Sourcepub const fn label_style(self, style: Style) -> Self
pub const fn label_style(self, style: Style) -> Self
Set the style of a MenuRow::Label row.
Sourcepub const fn overflow_style(self, style: Style) -> Self
pub const fn overflow_style(self, style: Style) -> Self
Set the style of the ^/v overflow indicator rows.
Sourcepub fn theme(self, theme: Theme) -> Self
pub fn theme(self, theme: Theme) -> Self
Applies theme’s named roles: item_style/label_style become theme.fg on
theme.panel_bg, selected_style becomes theme.bg on theme.accent, disabled_style
becomes theme.dim on theme.panel_bg, and separator_style/overflow_style become
theme.border on theme.panel_bg.
Call before any manual per-field override you want to keep.
Sourcepub fn theme_on(self, theme: Theme, bg: Color) -> Self
pub fn theme_on(self, theme: Theme, bg: Color) -> Self
Same as Menu::theme, but every style is drawn on bg instead of theme.panel_bg.
Source§impl Menu<'_>
impl Menu<'_>
Sourcepub fn show<Id: Copy + PartialEq>(
&self,
ui: &mut Ui<'_, '_, Id>,
screen: Rect,
popup_area: Rect,
content_id: Id,
backdrop_id: Id,
state: &mut MenuState,
) -> Option<usize>
pub fn show<Id: Copy + PartialEq>( &self, ui: &mut Ui<'_, '_, Id>, screen: Rect, popup_area: Rect, content_id: Id, backdrop_id: Id, state: &mut MenuState, ) -> Option<usize>
Draw and interact with this menu for one frame: the documented way to drive an anchored popup end-to-end, exercising the same primitives a menu bar/combobox/command palette all need.
A no-op (returns None, draws nothing) while state.is_open() is false. Otherwise:
- Registers
screenforbackdrop_idbefore opening aUi::modalscoped topopup_area: because a modal’s barrier only blocks hit-testing insidepopup_area(seeUi::modal’s docs), a click landing anywhere inscreenbut outsidepopup_areastill reaches the backdrop and is treated as “outside every hitbox”, closing the menu without activating anything. A click insidepopup_areais claimed by the popup’s own rows instead, since those are registered after the barrier and always win inside it. - Draws the window of rows
state.offset()selects (callingMenuState::ensure_visiblefirst so the selection is never scrolled out of view), and applies a hover/click/wheel-scroll gesture the same wayMenu::renderalone would if driven throughUi::show_stateful. - Returns
Some(row_index)for the one frame a selectable row is clicked, closing the menu as a side effect (“checkbox items fire and close”). ReturnsNoneon every other frame, including the one where an outside click closes the menu.
content_id and backdrop_id must be distinct: sharing one Id between them would make
both resolve the same hit-test winner, breaking the inside/outside distinction above.
Keyboard navigation/activation (Up/Down/Enter/Escape) is not handled here: feed raw
events to MenuState::handle_event instead, in your event-handling loop, the same split
TextInputState::handle_event has from drawing.
Trait Implementations§
impl<'a> Copy for Menu<'a>
Source§impl StatefulWidget for Menu<'_>
impl StatefulWidget for Menu<'_>
Auto Trait Implementations§
impl<'a> Freeze for Menu<'a>
impl<'a> RefUnwindSafe for Menu<'a>
impl<'a> Send for Menu<'a>
impl<'a> Sync for Menu<'a>
impl<'a> Unpin for Menu<'a>
impl<'a> UnsafeUnpin for Menu<'a>
impl<'a> UnwindSafe for Menu<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<C> WithAlpha for Cwhere
C: Copy,
impl<C> WithAlpha for Cwhere
C: Copy,
§fn with_alpha_first<A>(self, alpha: A) -> AlphaFirst<A, Self>
fn with_alpha_first<A>(self, alpha: A) -> AlphaFirst<A, Self>
self with alpha, storing alpha before the color in memory
(see [AlphaFirst]).§fn with_alpha_last<A>(self, alpha: A) -> AlphaLast<A, Self>
fn with_alpha_last<A>(self, alpha: A) -> AlphaLast<A, Self>
self with alpha, storing alpha after the color in memory
(see [AlphaLast]).