1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use freya_core::{
integration::ScopeId,
prelude::*,
};
use torin::prelude::CursorPoint;
use crate::menu::Menu;
/// Context for managing a global context menu.
///
/// # Example
///
/// ```rust
/// # use freya::prelude::*;
/// fn app() -> impl IntoElement {
/// let mut show_menu = use_state(|| false);
///
/// rect()
/// .on_secondary_press(move |_| {
/// ContextMenu::open(Menu::new().child(MenuButton::new().child("Option 1")));
/// show_menu.set(true);
/// })
/// .child("Right click to open menu")
/// }
/// ```
#[derive(Clone, Copy, PartialEq)]
pub struct ContextMenu {
pub(crate) location: State<CursorPoint>,
pub(crate) menu: State<Option<(CursorPoint, Menu)>>,
}
impl ContextMenu {
pub fn get() -> Self {
match try_consume_root_context() {
Some(rt) => rt,
None => {
let context_menu_state = ContextMenu {
location: State::create_in_scope(CursorPoint::default(), ScopeId::ROOT),
menu: State::create_in_scope(None, ScopeId::ROOT),
};
provide_context_for_scope_id(context_menu_state, ScopeId::ROOT);
context_menu_state
}
}
}
pub fn is_open() -> bool {
Self::get().menu.read().is_some()
}
pub fn open(menu: Menu) {
let mut this = Self::get();
this.menu.set(Some(((this.location)(), menu)));
}
pub fn close() {
Self::get().menu.set(None);
}
}