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        menu_id: MenuId,
36        menu_item_id: MenuItemId,
37    },
38}
39
40/// A top-level menu in the header (e.g. "File", "View").
41#[derive(Debug, Clone)]
42pub struct Menu<MenuId, MenuItemId>
43where
44    MenuId: Clone + Debug + PartialEq,
45    MenuItemId: Clone + Debug,
46{
47    pub id: MenuId,
48    pub label: String,
49    pub icon: Option<Icon>,
50    pub items: Vec<MenuItem<MenuId, MenuItemId>>,
51}
52
53/// A single entry in a menu's dropdown.
54#[derive(Debug, Clone)]
55pub struct MenuItem<MenuId, MenuItemId>
56where
57    MenuId: Clone + Debug + PartialEq,
58    MenuItemId: Clone + Debug,
59{
60    /// The id of the parent menu. Stored on each item so that
61    /// [`MenuAction::MenuItemPressed`] can carry it without a second lookup.
62    pub menu_id: MenuId,
63    pub id: MenuItemId,
64    pub label: String,
65    pub icon: Option<Icon>,
66}