oxygengine_user_interface/
resource.rs

1use raui_core::{
2    application::Application, interactive::default_interactions_engine::DefaultInteractionsEngine,
3    layout::CoordsMapping, signals::Signal,
4};
5use std::collections::HashMap;
6
7pub mod input_mappings {
8    pub const NAV_POINTER_AXES: &str = "nav-pointer";
9    pub const NAV_POINTER_ACTION_TRIGGER: &str = "nav-pointer-action";
10    pub const NAV_POINTER_CONTEXT_TRIGGER: &str = "nav-pointer-context";
11    pub const NAV_ACCEPT_TRIGGER: &str = "nav-accept";
12    pub const NAV_CANCEL_TRIGGER: &str = "nav-cancel";
13    pub const NAV_UP_TRIGGER: &str = "nav-up";
14    pub const NAV_DOWN_TRIGGER: &str = "nav-down";
15    pub const NAV_LEFT_TRIGGER: &str = "nav-left";
16    pub const NAV_RIGHT_TRIGGER: &str = "nav-right";
17    pub const NAV_PREV_TRIGGER: &str = "nav-prev";
18    pub const NAV_NEXT_TRIGGER: &str = "nav-next";
19    pub const NAV_TEXT_MOVE_CURSOR_LEFT_TRIGGER: &str = "nav-text-move-cursor-left";
20    pub const NAV_TEXT_MOVE_CURSOR_RIGHT_TRIGGER: &str = "nav-text-move-cursor-right";
21    pub const NAV_TEXT_MOVE_CURSOR_START_TRIGGER: &str = "nav-text-move-cursor-start";
22    pub const NAV_TEXT_MOVE_CURSOR_END_TRIGGER: &str = "nav-text-move-cursor-end";
23    pub const NAV_TEXT_DELETE_LEFT_TRIGGER: &str = "nav-text-delete-left";
24    pub const NAV_TEXT_DELETE_RIGHT_TRIGGER: &str = "nav-text-delete-right";
25}
26
27#[derive(Default)]
28pub struct ApplicationData {
29    pub application: Application,
30    pub interactions: DefaultInteractionsEngine,
31    pub coords_mapping: CoordsMapping,
32    pub(crate) signals_received: Vec<Signal>,
33}
34
35impl ApplicationData {
36    pub fn signals_received(&self) -> &[Signal] {
37        &self.signals_received
38    }
39}
40
41#[derive(Default)]
42pub struct UserInterface {
43    pub(crate) data: HashMap<String, ApplicationData>,
44    pub(crate) setup_application: Option<fn(&mut Application)>,
45}
46
47impl UserInterface {
48    pub fn new(setup_application: fn(&mut Application)) -> Self {
49        Self {
50            data: Default::default(),
51            setup_application: Some(setup_application),
52        }
53    }
54
55    #[inline]
56    pub fn iter(&self) -> impl Iterator<Item = (&str, &ApplicationData)> {
57        self.data.iter().map(|(n, d)| (n.as_str(), d))
58    }
59
60    #[inline]
61    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&str, &mut ApplicationData)> {
62        self.data.iter_mut().map(|(n, d)| (n.as_str(), d))
63    }
64
65    #[inline]
66    pub fn get(&self, app_id: &str) -> Option<&ApplicationData> {
67        self.data.get(app_id)
68    }
69
70    #[inline]
71    pub fn get_mut(&mut self, app_id: &str) -> Option<&mut ApplicationData> {
72        self.data.get_mut(app_id)
73    }
74
75    #[inline]
76    pub fn application(&self, app_id: &str) -> Option<&Application> {
77        self.data.get(app_id).map(|item| &item.application)
78    }
79
80    #[inline]
81    pub fn application_mut(&mut self, app_id: &str) -> Option<&mut Application> {
82        self.data.get_mut(app_id).map(|item| &mut item.application)
83    }
84
85    #[inline]
86    pub fn interactions(&self, app_id: &str) -> Option<&DefaultInteractionsEngine> {
87        self.data.get(app_id).map(|item| &item.interactions)
88    }
89
90    #[inline]
91    pub fn interactions_mut(&mut self, app_id: &str) -> Option<&mut DefaultInteractionsEngine> {
92        self.data.get_mut(app_id).map(|item| &mut item.interactions)
93    }
94
95    #[inline]
96    pub fn coords_mapping(&self, app_id: &str) -> Option<&CoordsMapping> {
97        self.data.get(app_id).map(|item| &item.coords_mapping)
98    }
99
100    #[inline]
101    pub fn coords_mapping_mut(&mut self, app_id: &str) -> Option<&mut CoordsMapping> {
102        self.data
103            .get_mut(app_id)
104            .map(|item| &mut item.coords_mapping)
105    }
106
107    #[inline]
108    pub fn signals_received(&self, app_id: &str) -> Option<&[Signal]> {
109        self.data.get(app_id).map(|item| item.signals_received())
110    }
111
112    #[inline]
113    pub fn all_signals_received(&self) -> impl Iterator<Item = (&str, &Signal)> {
114        self.data.iter().flat_map(|(id, item)| {
115            item.signals_received()
116                .iter()
117                .map(move |signal| (id.as_str(), signal))
118        })
119    }
120
121    pub fn has_layout_widget(&self, app_id: &str, id: &str) -> bool {
122        if let Some(item) = self.data.get(app_id) {
123            item.application
124                .layout_data()
125                .items
126                .keys()
127                .any(|k| k.as_ref() == id)
128        } else {
129            false
130        }
131    }
132}