Skip to main content

ferroui_diagnostics/diagnostics/view_models/
hot_key_page_view_model.rs

1//! Port of `Diagnostics/ViewModels/HotKeyPageViewModel.cs`.
2
3use super::ViewModelBase;
4use crate::diagnostics::DevToolsOptions;
5use ferroui_base::collections::FerroList;
6use ferroui_base::data::model::{Event, INotifyPropertyChanged};
7use ferroui_base::ferro_markup_type;
8use ferroui_base::input::{Key, KeyGesture, KeyModifiers};
9use std::cell::RefCell;
10use std::rc::Rc;
11
12/// A hot key of the developer tools, as the hot keys page lists it: the
13/// gesture, what it does and a longer description.
14///
15/// A record upstream: equal when the members are equal.
16#[derive(Clone, Debug, PartialEq, Eq)]
17pub struct HotKeyDescription {
18    gesture: String,
19    brief_description: String,
20    detailed_description: Option<String>,
21}
22
23impl HotKeyDescription {
24    /// C# `new HotKeyDescription(string Gesture, string BriefDescription, string? DetailedDescription = null)`.
25    pub fn new(
26        gesture: impl Into<String>,
27        brief_description: impl Into<String>,
28        detailed_description: Option<String>,
29    ) -> Self {
30        Self { gesture: gesture.into(), brief_description: brief_description.into(), detailed_description }
31    }
32
33    pub fn gesture(&self) -> String {
34        self.gesture.clone()
35    }
36
37    pub fn brief_description(&self) -> String {
38        self.brief_description.clone()
39    }
40
41    pub fn detailed_description(&self) -> Option<String> {
42        self.detailed_description.clone()
43    }
44}
45
46/// The view model of the hot keys page: the hot keys of the options the
47/// developer tools were opened with.
48pub struct HotKeyPageViewModel {
49    base: ViewModelBase,
50    hot_key_descriptions: RefCell<Option<FerroList<Rc<HotKeyDescription>>>>,
51}
52
53/// Reference equality, as the class of the original.
54impl PartialEq for HotKeyPageViewModel {
55    fn eq(&self, other: &Self) -> bool {
56        std::ptr::eq(self, other)
57    }
58}
59
60impl INotifyPropertyChanged for HotKeyPageViewModel {
61    fn property_changed(&self) -> &Event<str> {
62        self.base.property_changed()
63    }
64}
65
66impl HotKeyPageViewModel {
67    /// C# `new HotKeyPageViewModel()`.
68    pub fn new() -> Rc<Self> {
69        Rc::new(Self { base: ViewModelBase::new(), hot_key_descriptions: RefCell::new(None) })
70    }
71
72    /// The hot keys; `None` until the options are set.
73    pub fn hot_key_descriptions(&self) -> Option<FerroList<Rc<HotKeyDescription>>> {
74        self.hot_key_descriptions.borrow().clone()
75    }
76
77    fn set_hot_key_descriptions(&self, value: Option<FerroList<Rc<HotKeyDescription>>>) {
78        self.base.raise_and_set_if_changed(&self.hot_key_descriptions, value, "HotKeyDescriptions");
79    }
80
81    /// Lists the hot keys of `options`.
82    pub fn set_options(&self, options: &DevToolsOptions) {
83        let hot_keys = options.hot_keys();
84
85        let descriptions = [
86            HotKeyDescription::new(
87                Self::create_description(&options.gesture()),
88                "Launch DevTools",
89                Some("Launches DevTools to inspect the TopLevel that received the hotkey input".to_string()),
90            ),
91            HotKeyDescription::new(
92                Self::create_description(&hot_keys.value_frames_freeze()),
93                "Freeze Value Frames",
94                Some("Pauses refreshing the Value Frames inspector for the selected Control".to_string()),
95            ),
96            HotKeyDescription::new(
97                Self::create_description(&hot_keys.value_frames_unfreeze()),
98                "Unfreeze Value Frames",
99                Some("Resumes refreshing the Value Frames inspector for the selected Control".to_string()),
100            ),
101            HotKeyDescription::new(
102                Self::create_description(&hot_keys.inspect_hovered_control()),
103                "Inspect Control Under Pointer",
104                Some("Inspects the hovered Control in the Logical or Visual Tree Page".to_string()),
105            ),
106            HotKeyDescription::new(
107                Self::create_description(&hot_keys.toggle_popup_freeze()),
108                "Toggle Popup Freeze",
109                Some("Prevents visible Popups from closing so they can be inspected".to_string()),
110            ),
111            HotKeyDescription::new(
112                Self::create_description(&hot_keys.screenshot_selected_control()),
113                "Screenshot Selected Control",
114                Some("Saves a Screenshot of the Selected Control in the Logical or Visual Tree Page".to_string()),
115            ),
116        ];
117
118        self.set_hot_key_descriptions(Some(FerroList::from_items(descriptions.into_iter().map(Rc::new))));
119    }
120
121    /// The text of a gesture; a gesture of modifiers only leaves out the key.
122    fn create_description(gesture: &KeyGesture) -> String {
123        if gesture.key() == Key::None && gesture.key_modifiers() != KeyModifiers::NONE {
124            gesture.to_string().replace("+None", "")
125        } else {
126            gesture.to_string()
127        }
128    }
129}
130
131// The list of the hot keys, which the hot keys page shows.
132ferroui_controls::ferro_markup_list!(pub HotKeyDescriptionList: Rc<HotKeyDescription>);
133
134ferro_markup_type!(class HotKeyDescription {
135    this: Rc<HotKeyDescription>,
136    handles: [HotKeyDescription, Rc<HotKeyDescription>, Option<Rc<HotKeyDescription>>],
137    properties: [
138        Gesture: String { get: HotKeyDescription::gesture },
139        BriefDescription: String { get: HotKeyDescription::brief_description },
140        DetailedDescription: Option<String> { get: HotKeyDescription::detailed_description },
141    ],
142});
143
144ferro_markup_type!(class HotKeyPageViewModel {
145    this: Rc<HotKeyPageViewModel>,
146    handles: [HotKeyPageViewModel, Rc<HotKeyPageViewModel>, Option<Rc<HotKeyPageViewModel>>],
147    base: ViewModelBase,
148    constructors: [() => HotKeyPageViewModel::new],
149    properties: [
150        HotKeyDescriptions: Option<FerroList<Rc<HotKeyDescription>>> {
151            get: HotKeyPageViewModel::hot_key_descriptions
152        },
153    ],
154    notify_property_changed: HotKeyPageViewModel,
155});