Skip to main content

snora_core/
menu.rs

1//! Header menus (File / Edit / View / ... drop-downs).
2//!
3//! A menu is a **pure data contract**. The application supplies a list of
4//! [`Menu`] values, the engine renders them into a header bar, and
5//! interaction is reported back via [`MenuAction`] messages. snora-core
6//! has no opinion on how the menu is rendered.
7//!
8//! `MenuId` and `MenuItemId` are application-defined types. They must
9//! implement `Clone` for message dispatch and `PartialEq` for tracking
10//! which menu is currently open.
11//!
12//! The recommended pattern is a pair of application-owned enums:
13//!
14//! ```rust
15//! #[derive(Clone, Debug, PartialEq, Eq)]
16//! enum MyMenuId { File, View, Help }
17//!
18//! #[derive(Clone, Debug, PartialEq, Eq)]
19//! enum MyMenuItemId { New, Open, Quit, ToggleLogs, About }
20//! ```
21
22use std::fmt::Debug;
23
24use crate::icon::Icon;
25
26/// An event emitted by a header menu.
27#[derive(Debug, Clone, PartialEq, Eq)]
28pub enum MenuAction<MenuId, MenuItemId> {
29    /// The menu header (not an item) was pressed. Convention: toggle open /
30    /// closed, or switch the currently-open menu.
31    MenuPressed(MenuId),
32
33    /// An item within a menu was chosen.
34    MenuItemPressed {
35        /// Id of the parent menu.
36        menu_id: MenuId,
37        /// Id of the chosen item.
38        menu_item_id: MenuItemId,
39    },
40}
41
42/// A top-level menu in the header (e.g. "File", "View").
43#[derive(Debug, Clone)]
44pub struct Menu<MenuId, MenuItemId>
45where
46    MenuId: Clone + Debug + PartialEq,
47    MenuItemId: Clone + Debug,
48{
49    /// Application-defined identity of this menu.
50    pub id: MenuId,
51    /// Visible label (e.g. "File", "View").
52    pub label: String,
53    /// Optional icon shown next to the label.
54    pub icon: Option<Icon>,
55    /// Items shown in the dropdown when this menu is active.
56    pub items: Vec<MenuItem<MenuId, MenuItemId>>,
57}
58
59/// A single entry in a menu's dropdown.
60#[derive(Debug, Clone)]
61pub struct MenuItem<MenuId, MenuItemId>
62where
63    MenuId: Clone + Debug + PartialEq,
64    MenuItemId: Clone + Debug,
65{
66    /// The id of the parent menu. Stored on each item so that
67    /// [`MenuAction::MenuItemPressed`] can carry it without a second lookup.
68    pub menu_id: MenuId,
69    /// Application-defined identity of this item.
70    pub id: MenuItemId,
71    /// Visible label.
72    pub label: String,
73    /// Optional icon shown before the label.
74    pub icon: Option<Icon>,
75}