Skip to main content

ferroui_remote_protocol/
input_messages.rs

1/*
2We are keeping copies of core events here, so they can be used
3without referencing the framework itself, e. g. from projects that
4are using WPF, GTK#, etc
5*/
6
7use std::ops::{Deref, DerefMut};
8
9use crate::key::Key;
10use crate::physical_key::PhysicalKey;
11use crate::{bson_class, bson_enum, ferro_remote_message_guid};
12
13/// Keep this in sync with InputModifiers in the main library
14// Deviation (DEVIATIONS.md, Remote protocol): the original marks the
15// enumeration `[Flags]`, but its members are the numbers zero to six, not
16// bits, and a message carries them as an array of members. It is a plain
17// enumeration here, not a set of flags.
18#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
19#[repr(i32)]
20pub enum InputModifiers {
21    #[default]
22    Alt = 0,
23    Control = 1,
24    Shift = 2,
25    Windows = 3,
26    LeftMouseButton = 4,
27    RightMouseButton = 5,
28    MiddleMouseButton = 6,
29}
30
31impl InputModifiers {
32    /// The member with the given numeric value, if one is defined.
33    pub fn from_value(value: i32) -> Option<InputModifiers> {
34        match value {
35            0 => Some(InputModifiers::Alt),
36            1 => Some(InputModifiers::Control),
37            2 => Some(InputModifiers::Shift),
38            3 => Some(InputModifiers::Windows),
39            4 => Some(InputModifiers::LeftMouseButton),
40            5 => Some(InputModifiers::RightMouseButton),
41            6 => Some(InputModifiers::MiddleMouseButton),
42            _ => None,
43        }
44    }
45}
46
47bson_enum!(InputModifiers);
48
49/// Keep this in sync with InputModifiers in the main library
50#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
51#[repr(i32)]
52pub enum MouseButton {
53    #[default]
54    None = 0,
55    Left = 1,
56    Right = 2,
57    Middle = 3,
58}
59
60impl MouseButton {
61    /// The member with the given numeric value, if one is defined.
62    pub fn from_value(value: i32) -> Option<MouseButton> {
63        match value {
64            0 => Some(MouseButton::None),
65            1 => Some(MouseButton::Left),
66            2 => Some(MouseButton::Right),
67            3 => Some(MouseButton::Middle),
68            _ => None,
69        }
70    }
71}
72
73bson_enum!(MouseButton);
74
75// The two key enumerations are compiled into this library from the sources
76// of the base library (`lib.rs`); what they are on the wire is stated here.
77bson_enum!(Key);
78bson_enum!(PhysicalKey);
79
80/// The base of the input messages. A class that derives from it embeds it as
81/// `base` and writes its properties after its own, which is the order in
82/// which reflection returns the properties of a derived class.
83#[derive(Clone, Debug, Default, PartialEq)]
84pub struct InputEventMessageBase {
85    pub modifiers: Option<Vec<InputModifiers>>,
86}
87
88#[derive(Clone, Debug, Default, PartialEq)]
89pub struct PointerEventMessageBase {
90    pub base: InputEventMessageBase,
91    pub x: f64,
92    pub y: f64,
93}
94
95impl Deref for PointerEventMessageBase {
96    type Target = InputEventMessageBase;
97
98    fn deref(&self) -> &InputEventMessageBase {
99        &self.base
100    }
101}
102
103impl DerefMut for PointerEventMessageBase {
104    fn deref_mut(&mut self) -> &mut InputEventMessageBase {
105        &mut self.base
106    }
107}
108
109/// `class X : Base`: the derived class reads and writes as its base.
110macro_rules! derives {
111    ($class:ident : $base:ident) => {
112        impl Deref for $class {
113            type Target = $base;
114
115            fn deref(&self) -> &$base {
116                &self.base
117            }
118        }
119
120        impl DerefMut for $class {
121            fn deref_mut(&mut self) -> &mut $base {
122                &mut self.base
123            }
124        }
125    };
126}
127
128#[derive(Clone, Debug, Default, PartialEq)]
129pub struct PointerMovedEventMessage {
130    pub base: PointerEventMessageBase,
131}
132
133derives!(PointerMovedEventMessage: PointerEventMessageBase);
134ferro_remote_message_guid!(PointerMovedEventMessage, "6228F0B9-99F2-4F62-A621-414DA2881648");
135bson_class!(PointerMovedEventMessage as "PointerMovedEventMessage" {
136    "X" => base.x: f64,
137    "Y" => base.y: f64,
138    "Modifiers" => base.base.modifiers: Option<Vec<InputModifiers>>,
139});
140
141#[derive(Clone, Debug, Default, PartialEq)]
142pub struct PointerPressedEventMessage {
143    pub base: PointerEventMessageBase,
144    pub button: MouseButton,
145}
146
147derives!(PointerPressedEventMessage: PointerEventMessageBase);
148ferro_remote_message_guid!(PointerPressedEventMessage, "7E9E2818-F93F-411A-800E-6B1AEB11DA46");
149bson_class!(PointerPressedEventMessage as "PointerPressedEventMessage" {
150    "Button" => button: MouseButton,
151    "X" => base.x: f64,
152    "Y" => base.y: f64,
153    "Modifiers" => base.base.modifiers: Option<Vec<InputModifiers>>,
154});
155
156#[derive(Clone, Debug, Default, PartialEq)]
157pub struct PointerReleasedEventMessage {
158    pub base: PointerEventMessageBase,
159    pub button: MouseButton,
160}
161
162derives!(PointerReleasedEventMessage: PointerEventMessageBase);
163ferro_remote_message_guid!(PointerReleasedEventMessage, "4ADC84EE-E7C8-4BCF-986C-DE3A2F78EDE4");
164bson_class!(PointerReleasedEventMessage as "PointerReleasedEventMessage" {
165    "Button" => button: MouseButton,
166    "X" => base.x: f64,
167    "Y" => base.y: f64,
168    "Modifiers" => base.base.modifiers: Option<Vec<InputModifiers>>,
169});
170
171#[derive(Clone, Debug, Default, PartialEq)]
172pub struct ScrollEventMessage {
173    pub base: PointerEventMessageBase,
174    pub delta_x: f64,
175    pub delta_y: f64,
176}
177
178derives!(ScrollEventMessage: PointerEventMessageBase);
179ferro_remote_message_guid!(ScrollEventMessage, "79301A05-F02D-4B90-BB39-472563B504AE");
180bson_class!(ScrollEventMessage as "ScrollEventMessage" {
181    "DeltaX" => delta_x: f64,
182    "DeltaY" => delta_y: f64,
183    "X" => base.x: f64,
184    "Y" => base.y: f64,
185    "Modifiers" => base.base.modifiers: Option<Vec<InputModifiers>>,
186});
187
188#[derive(Clone, Debug, Default, PartialEq)]
189pub struct KeyEventMessage {
190    pub base: InputEventMessageBase,
191    pub is_down: bool,
192    pub key: Key,
193    pub physical_key: PhysicalKey,
194    pub key_symbol: Option<String>,
195}
196
197derives!(KeyEventMessage: InputEventMessageBase);
198ferro_remote_message_guid!(KeyEventMessage, "1C3B691E-3D54-4237-BFB0-9FEA83BC1DB8");
199bson_class!(KeyEventMessage as "KeyEventMessage" {
200    "IsDown" => is_down: bool,
201    "Key" => key: Key,
202    "PhysicalKey" => physical_key: PhysicalKey,
203    "KeySymbol" => key_symbol: Option<String>,
204    "Modifiers" => base.modifiers: Option<Vec<InputModifiers>>,
205});
206
207#[derive(Clone, Debug, Default, PartialEq)]
208pub struct TextInputEventMessage {
209    pub base: InputEventMessageBase,
210    pub text: String,
211}
212
213derives!(TextInputEventMessage: InputEventMessageBase);
214ferro_remote_message_guid!(TextInputEventMessage, "C174102E-7405-4594-916F-B10B8248A17D");
215bson_class!(TextInputEventMessage as "TextInputEventMessage" {
216    "Text" => text: String,
217    "Modifiers" => base.modifiers: Option<Vec<InputModifiers>>,
218});