fyrox_ui/message.rs
1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Message and events module contains all possible widget messages and OS events. See [`UiMessage`] docs for more info and
22//! examples.
23
24#![warn(missing_docs)]
25
26use crate::{
27 core::{algebra::Vector2, pool::Handle, reflect::prelude::*, visitor::prelude::*},
28 UiNode, UserInterface,
29};
30use fyrox_core::uuid_provider;
31use serde::{Deserialize, Serialize};
32use std::{any::Any, cell::Cell, fmt::Debug};
33use strum_macros::{AsRefStr, EnumString, VariantNames};
34
35/// Defines a new message constructor for a enum variant. It is widely used in this crate to create shortcuts to create
36/// messages. Why is it needed anyway? Just to reduce boilerplate code as much as possible.
37///
38/// ## Examples
39///
40/// The following example shows how to create message constructors for various kinds of enum variants:
41///
42/// ```rust
43/// # use fyrox_ui::{
44/// # core::pool::Handle, define_constructor, message::MessageDirection, message::UiMessage, UiNode,
45/// # UserInterface,
46/// # };
47/// #
48/// // Message must be debuggable, comparable, cloneable.
49/// #[derive(Debug, PartialEq, Clone)]
50/// enum MyWidgetMessage {
51/// DoSomething,
52/// Foo(u32),
53/// Bar { foo: u32, baz: u8 },
54/// }
55///
56/// impl MyWidgetMessage {
57/// // The first option is used to create constructors plain enum variants:
58/// //
59/// // enum name variant name perform layout?
60/// // v v v v
61/// define_constructor!(MyWidgetMessage:DoSomething => fn do_something(), layout: false);
62///
63/// // The second option is used to create constructors for single-arg tuple enum variants:
64/// //
65/// // enum name variant name arg perform layout?
66/// // v v v v v
67/// define_constructor!(MyWidgetMessage:Foo => fn foo(u32), layout: false);
68///
69/// // The third option is used to create constructors for enum variants with fields:
70/// //
71/// // enum name variant name arg type arg type perform layout?
72/// // v v v v v v v v
73/// define_constructor!(MyWidgetMessage:Bar => fn bar(foo: u32, baz: u8), layout: false);
74/// }
75///
76/// fn using_messages(my_widget: Handle<UiNode>, ui: &UserInterface) {
77/// // Send MyWidgetMessage::DoSomething
78/// ui.send_message(MyWidgetMessage::do_something(
79/// my_widget,
80/// MessageDirection::ToWidget,
81/// ));
82///
83/// // Send MyWidgetMessage::Foo
84/// ui.send_message(MyWidgetMessage::foo(
85/// my_widget,
86/// MessageDirection::ToWidget,
87/// 5,
88/// ));
89///
90/// // Send MyWidgetMessage::Bar
91/// ui.send_message(MyWidgetMessage::bar(
92/// my_widget,
93/// MessageDirection::ToWidget,
94/// 1,
95/// 2,
96/// ));
97/// }
98/// ```
99#[macro_export]
100macro_rules! define_constructor {
101 ($(#[$meta:meta])* $inner:ident : $inner_var:tt => fn $name:ident(), layout: $perform_layout:expr) => {
102 $(#[$meta])*
103 #[must_use = "message does nothing until sent to ui"]
104 pub fn $name(destination: Handle<UiNode>, direction: MessageDirection) -> UiMessage {
105 UiMessage {
106 handled: std::cell::Cell::new(false),
107 data: Box::new($inner::$inner_var),
108 destination,
109 direction,
110 routing_strategy: Default::default(),
111 perform_layout: std::cell::Cell::new($perform_layout),
112 flags: 0
113 }
114 }
115 };
116
117 ($(#[$meta:meta])* $inner:ident : $inner_var:tt => fn $name:ident($typ:ty), layout: $perform_layout:expr) => {
118 $(#[$meta])*
119 #[must_use = "message does nothing until sent to ui"]
120 pub fn $name(destination: Handle<UiNode>, direction: MessageDirection, value:$typ) -> UiMessage {
121 UiMessage {
122 handled: std::cell::Cell::new(false),
123 data: Box::new($inner::$inner_var(value)),
124 destination,
125 direction,
126 routing_strategy: Default::default(),
127 perform_layout: std::cell::Cell::new($perform_layout),
128 flags: 0
129 }
130 }
131 };
132
133 ($(#[$meta:meta])* $inner:ident : $inner_var:tt => fn $name:ident( $($params:ident : $types:ty),+ ), layout: $perform_layout:expr) => {
134 $(#[$meta])*
135 #[must_use = "message does nothing until sent to ui"]
136 pub fn $name(destination: Handle<UiNode>, direction: MessageDirection, $($params : $types),+) -> UiMessage {
137 UiMessage {
138 handled: std::cell::Cell::new(false),
139 data: Box::new($inner::$inner_var { $($params),+ }),
140 destination,
141 direction,
142 routing_strategy: Default::default(),
143 perform_layout: std::cell::Cell::new($perform_layout),
144 flags: 0
145 }
146 }
147 }
148}
149
150/// Message direction allows you to distinguish from where message has came from. Often there is a need to find out who
151/// created a message to respond properly. Imagine that we have a NumericUpDown input field for a property and we using
152/// some data source to feed data into input field. When we change something in the input field by typing, it creates a
153/// message with new value. On other hand we often need to put new value in the input field from some code, in this case
154/// we again creating a message. But how to understand from which "side" message has came from? Was it filled in by user
155/// and we should create a command to change value in the data source, or it was created from syncing code just to pass
156/// new value to UI? This problem solved by setting a direction to a message. Also it solves another problem: often we
157/// need to respond to a message only if it did some changes. In this case at first we fire a message with ToWidget direction,
158/// widget catches it and checks if changes are needed and if so, it "rethrows" message with direction FromWidget. Listeners
159/// are "subscribed" to FromWidget messages only and won't respond to ToWidget messages.
160#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Hash, Eq)]
161pub enum MessageDirection {
162 /// Used to indicate a request for changes in a widget.
163 ToWidget,
164
165 /// Used to indicate response from widget if anything has actually changed.
166 FromWidget,
167}
168
169impl MessageDirection {
170 /// Reverses direction.
171 pub fn reverse(self) -> Self {
172 match self {
173 Self::ToWidget => Self::FromWidget,
174 Self::FromWidget => Self::ToWidget,
175 }
176 }
177}
178
179/// A trait, that is used by every messages used in the user interface. It contains utility methods, that are used
180/// for downcasting and equality comparison.
181pub trait MessageData: 'static + Debug + Any + Send {
182 /// Casts `self` as [`Any`] reference.
183 fn as_any(&self) -> &dyn Any;
184
185 /// Compares this message data with some other.
186 fn compare(&self, other: &dyn MessageData) -> bool;
187
188 /// Clones self as boxed value.
189 fn clone_box(&self) -> Box<dyn MessageData>;
190}
191
192impl<T> MessageData for T
193where
194 T: 'static + Debug + PartialEq + Any + Send + Clone,
195{
196 fn as_any(&self) -> &dyn Any {
197 self
198 }
199
200 fn compare(&self, other: &dyn MessageData) -> bool {
201 other
202 .as_any()
203 .downcast_ref::<T>()
204 .map(|other| other == self)
205 .unwrap_or_default()
206 }
207
208 fn clone_box(&self) -> Box<dyn MessageData> {
209 Box::new(self.clone())
210 }
211}
212
213/// Defines a way of how the message will behave in the widget tree after it was delivered to
214/// the destination node.
215#[derive(Default, Copy, Clone, Debug, PartialEq)]
216pub enum RoutingStrategy {
217 /// A message will be passed to every ancestor widget in the hierarchy until the root.
218 #[default]
219 BubbleUp,
220 /// A message will be passed directly to a widget directly and won't be passed to any other
221 /// widget (message preview mechanism will still be used).
222 Direct,
223}
224
225/// Message is basic communication element that is used to deliver information to widget or to user code.
226///
227/// ## Motivation
228///
229/// This UI library uses message passing mechanism to communicate with widgets. This is very simple and reliable mechanism that
230/// effectively decouples widgets from each other. There is no direct way of modify something during runtime, you have to use
231/// messages to change state of ui elements.
232///
233/// ## Direction
234///
235/// Each message marked with "Direction" field, which means supported routes for message. For example [`crate::button::ButtonMessage::Click`]
236/// has "Direction: To/From UI" which means that it can be sent either from internals of library or from user code. However
237/// [`crate::widget::WidgetMessage::Focus`] has "Direction: From UI" which means that only internal library code can send such messages without
238/// a risk of breaking anything.
239///
240/// ## Threading
241///
242/// UiMessage is nor Send or Sync. User interface is a single-thread thing, as well as its messages.
243///
244/// ## Examples
245///
246/// ```rust
247/// use fyrox_ui::{
248/// core::pool::Handle, define_constructor, message::MessageDirection, message::UiMessage, UiNode,
249/// UserInterface,
250/// };
251///
252/// // Message must be debuggable and comparable.
253/// #[derive(Debug, PartialEq, Clone)]
254/// enum MyWidgetMessage {
255/// DoSomething,
256/// Foo(u32),
257/// Bar { foo: u32, baz: u8 },
258/// }
259///
260/// impl MyWidgetMessage {
261/// define_constructor!(MyWidgetMessage:DoSomething => fn do_something(), layout: false);
262/// define_constructor!(MyWidgetMessage:Foo => fn foo(u32), layout: false);
263/// define_constructor!(MyWidgetMessage:Bar => fn bar(foo: u32, baz: u8), layout: false);
264/// }
265///
266/// fn using_messages(my_widget: Handle<UiNode>, ui: &UserInterface) {
267/// // Send MyWidgetMessage::DoSomething
268/// ui.send_message(MyWidgetMessage::do_something(
269/// my_widget,
270/// MessageDirection::ToWidget,
271/// ));
272/// // Send MyWidgetMessage::Foo
273/// ui.send_message(MyWidgetMessage::foo(
274/// my_widget,
275/// MessageDirection::ToWidget,
276/// 5,
277/// ));
278/// // Send MyWidgetMessage::Bar
279/// ui.send_message(MyWidgetMessage::bar(
280/// my_widget,
281/// MessageDirection::ToWidget,
282/// 1,
283/// 2,
284/// ));
285/// }
286/// ```
287///
288///
289pub struct UiMessage {
290 /// Useful flag to check if a message was already handled. It could be used to mark messages as "handled" to prevent
291 /// any further responses to them. It is especially useful in bubble message routing, when a message is passed through
292 /// the entire chain of parent nodes starting from current. In this, you can mark a message as "handled" and also check
293 /// if it is handled or not. For example, this is used in [`crate::tree::Tree`] implementation, to prevent double-click
294 /// to close all the parent trees from current.
295 pub handled: Cell<bool>,
296
297 /// Actual message data. Use [`UiMessage::data`] method to try to downcast the internal data to a specific type.
298 pub data: Box<dyn MessageData>,
299
300 /// Handle of node that will receive message. Please note that **all** nodes in hierarchy will also receive this message,
301 /// order is "up-on-tree" (so called "bubble" message routing). T
302 pub destination: Handle<UiNode>,
303
304 /// Indicates the direction of the message. See [`MessageDirection`] docs for more info.
305 pub direction: MessageDirection,
306
307 /// Defines a way of how the message will behave in the widget tree after it was delivered to
308 /// the destination node. Default is bubble routing. See [`RoutingStrategy`] for more info.
309 pub routing_strategy: RoutingStrategy,
310
311 /// Whether or not message requires layout to be calculated first.
312 ///
313 /// ## Motivation
314 ///
315 /// Some of message handling routines uses layout info, but message loop performed right after layout pass, but some of messages
316 /// may change layout and this flag tells UI to perform layout before passing message further. In ideal case we'd perform layout
317 /// after **each** message, but since layout pass is super heavy we should do it **only** when it is actually needed.
318 pub perform_layout: Cell<bool>,
319
320 /// A custom user flags. Use it if `handled` flag is not enough.
321 pub flags: u64,
322}
323
324/// Compares the new value with the existing one, and if they do not match, sets the new value to it
325/// and sends the given message back to the message queue with the opposite direction. This function
326/// is useful to reduce boilerplate code when reacting to widget messages.
327pub fn compare_and_set<T>(
328 value: &mut T,
329 new_value: &T,
330 message: &UiMessage,
331 ui: &UserInterface,
332) -> bool
333where
334 T: PartialEq + Clone,
335{
336 if value != new_value {
337 *value = new_value.clone();
338 ui.send_message(message.reverse());
339 true
340 } else {
341 false
342 }
343}
344
345impl Debug for UiMessage {
346 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
347 write!(
348 f,
349 "UiMessage({}:({})",
350 match self.direction {
351 MessageDirection::ToWidget => "To",
352 MessageDirection::FromWidget => "From",
353 },
354 self.destination
355 )?;
356 if self.handled.get() {
357 write!(f, ",handled")?;
358 }
359 if self.perform_layout.get() {
360 write!(f, ",layout")?;
361 }
362 if self.flags != 0 {
363 write!(f, ",flags:{}", self.flags)?;
364 }
365 write!(f, "):{:?}", self.data)
366 }
367}
368
369impl Clone for UiMessage {
370 fn clone(&self) -> Self {
371 Self {
372 handled: self.handled.clone(),
373 data: self.data.clone_box(),
374 destination: self.destination,
375 direction: self.direction,
376 routing_strategy: self.routing_strategy,
377 perform_layout: self.perform_layout.clone(),
378 flags: self.flags,
379 }
380 }
381}
382
383impl PartialEq for UiMessage {
384 fn eq(&self, other: &Self) -> bool {
385 self.handled == other.handled
386 && self.data.compare(&*other.data)
387 && self.destination == other.destination
388 && self.routing_strategy == other.routing_strategy
389 && self.direction == other.direction
390 && self.perform_layout == other.perform_layout
391 && self.flags == other.flags
392 }
393}
394
395impl UiMessage {
396 /// Creates new UI message with desired data.
397 pub fn with_data<T: MessageData>(data: T) -> Self {
398 Self {
399 handled: Cell::new(false),
400 data: Box::new(data),
401 destination: Default::default(),
402 direction: MessageDirection::ToWidget,
403 routing_strategy: Default::default(),
404 perform_layout: Cell::new(false),
405 flags: 0,
406 }
407 }
408
409 /// Sets the desired destination of the message.
410 pub fn with_destination(mut self, destination: Handle<UiNode>) -> Self {
411 self.destination = destination;
412 self
413 }
414
415 /// Sets the desired direction of the message.
416 pub fn with_direction(mut self, direction: MessageDirection) -> Self {
417 self.direction = direction;
418 self
419 }
420
421 /// Sets the desired handled flag of the message.
422 pub fn with_handled(self, handled: bool) -> Self {
423 self.handled.set(handled);
424 self
425 }
426
427 /// Sets the desired perform layout flag of the message.
428 pub fn with_perform_layout(self, perform_layout: bool) -> Self {
429 self.perform_layout.set(perform_layout);
430 self
431 }
432
433 /// Sets the desired routing strategy.
434 pub fn with_routing_strategy(mut self, routing_strategy: RoutingStrategy) -> Self {
435 self.routing_strategy = routing_strategy;
436 self
437 }
438
439 /// Sets the desired flags of the message.
440 pub fn with_flags(mut self, flags: u64) -> Self {
441 self.flags = flags;
442 self
443 }
444
445 /// Creates a new copy of the message with reversed direction. Typical use case is to re-send messages to create "response"
446 /// in a widget. For example you have a float input field and it has Value message. When the input field receives Value message
447 /// with [`MessageDirection::ToWidget`] it checks if value needs to be changed and if it does, it re-sends same message, but with
448 /// reversed direction back to message queue so every "listener" can reach properly. The input field won't react at
449 /// [`MessageDirection::FromWidget`] message so there will be no infinite message loop.
450 #[must_use = "method creates new value which must be used"]
451 pub fn reverse(&self) -> Self {
452 Self {
453 handled: self.handled.clone(),
454 data: self.data.clone_box(),
455 destination: self.destination,
456 direction: self.direction.reverse(),
457 routing_strategy: self.routing_strategy,
458 perform_layout: self.perform_layout.clone(),
459 flags: self.flags,
460 }
461 }
462
463 /// Returns destination widget handle of the message.
464 pub fn destination(&self) -> Handle<UiNode> {
465 self.destination
466 }
467
468 /// Tries to downcast current data of the message to a particular type.
469 pub fn data<T: MessageData>(&self) -> Option<&T> {
470 (*self.data).as_any().downcast_ref::<T>()
471 }
472
473 /// Sets handled flag.
474 pub fn set_handled(&self, handled: bool) {
475 self.handled.set(handled);
476 }
477
478 /// Returns handled flag.
479 pub fn handled(&self) -> bool {
480 self.handled.get()
481 }
482
483 /// Returns direction of the message.
484 pub fn direction(&self) -> MessageDirection {
485 self.direction
486 }
487
488 /// Sets perform layout flag.
489 pub fn set_perform_layout(&self, value: bool) {
490 self.perform_layout.set(value);
491 }
492
493 /// Returns perform layout flag.
494 pub fn need_perform_layout(&self) -> bool {
495 self.perform_layout.get()
496 }
497
498 /// Checks if the message has particular flags.
499 pub fn has_flags(&self, flags: u64) -> bool {
500 self.flags & flags != 0
501 }
502}
503
504/// Mouse button state.
505#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Visit, Reflect)]
506pub enum ButtonState {
507 /// Pressed state.
508 Pressed,
509 /// Released state.
510 Released,
511}
512
513/// A set of possible mouse buttons.
514#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Default, Visit, Reflect)]
515pub enum MouseButton {
516 /// Left mouse button.
517 #[default]
518 Left,
519 /// Right mouse button.
520 Right,
521 /// Middle mouse button.
522 Middle,
523 /// Back mouse button.
524 Back,
525 /// Forward mouse button.
526 Forward,
527 /// Any other mouse button.
528 Other(u16),
529}
530
531/// A set of possible touch phases
532#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Visit, Reflect)]
533pub enum TouchPhase {
534 /// Touch started
535 Started,
536 /// Touch and drag
537 Moved,
538 /// Touch ended
539 Ended,
540 /// Touch cancelled
541 Cancelled,
542}
543
544/// Describes the force of a touch event
545#[derive(Debug, Hash, Ord, PartialOrd, PartialEq, Eq, Clone, Copy, Visit, Reflect)]
546pub enum Force {
547 /// On iOS, the force is calibrated so that the same number corresponds to
548 /// roughly the same amount of pressure on the screen regardless of the
549 /// device.
550 Calibrated {
551 /// The force of the touch, where a value of 1.0 represents the force of
552 /// an average touch (predetermined by the system, not user-specific).
553 ///
554 /// The force reported by Apple Pencil is measured along the axis of the
555 /// pencil. If you want a force perpendicular to the device, you need to
556 /// calculate this value using the `altitude_angle` value.
557 force: [u8; 8],
558 /// The maximum possible force for a touch.
559 ///
560 /// The value of this field is sufficiently high to provide a wide
561 /// dynamic range for values of the `force` field.
562 max_possible_force: [u8; 8],
563 /// The altitude (in radians) of the stylus.
564 ///
565 /// A value of 0 radians indicates that the stylus is parallel to the
566 /// surface. The value of this property is Pi/2 when the stylus is
567 /// perpendicular to the surface.
568 altitude_angle: Option<[u8; 8]>,
569 },
570 /// If the platform reports the force as normalized, we have no way of
571 /// knowing how much pressure 1.0 corresponds to – we know it's the maximum
572 /// amount of force, but as to how much force, you might either have to
573 /// press really really hard, or not hard at all, depending on the device.
574 Normalized([u8; 8]),
575}
576
577impl Force {
578 /// Returns the force normalized to the range between 0.0 and 1.0 inclusive.
579 ///
580 /// Instead of normalizing the force, you should prefer to handle
581 /// [`Force::Calibrated`] so that the amount of force the user has to apply is
582 /// consistent across devices.
583 pub fn normalized(&self) -> f64 {
584 match self {
585 Force::Calibrated {
586 force,
587 max_possible_force,
588 altitude_angle,
589 } => {
590 let force = match altitude_angle {
591 Some(altitude_angle) => {
592 f64::from_be_bytes(*force) / f64::from_be_bytes(*altitude_angle).sin()
593 }
594 None => f64::from_be_bytes(*force),
595 };
596 force / f64::from_be_bytes(*max_possible_force)
597 }
598 Force::Normalized(force) => f64::from_be_bytes(*force),
599 }
600 }
601}
602
603/// An event that an OS sends to a window, that is then can be used to "feed" the user interface so it can do some actions.
604#[derive(Debug)]
605pub enum OsEvent {
606 /// Mouse input event.
607 MouseInput {
608 /// Mouse button.
609 button: MouseButton,
610 /// Mouse button state.
611 state: ButtonState,
612 },
613 /// Cursor event.
614 CursorMoved {
615 /// New position of the cursor.
616 position: Vector2<f32>,
617 },
618 /// Keyboard input event.
619 KeyboardInput {
620 /// Code of a key.
621 button: KeyCode,
622 /// Key state.
623 state: ButtonState,
624 /// Text of the key.
625 text: String,
626 },
627 /// Keyboard modifier event (used for key combinations such as Ctrl+A, Ctrl+C, etc).
628 KeyboardModifiers(KeyboardModifiers),
629 /// Mouse wheel event, with a tuple that stores the (x, y) offsets.
630 MouseWheel(f32, f32),
631 /// Touch event.
632 Touch {
633 /// Phase of the touch event
634 phase: TouchPhase,
635 /// Screen location of touch event
636 location: Vector2<f32>,
637 /// Pressure exerted during force event
638 force: Option<Force>,
639 /// Unique touch event identifier to distinguish between fingers, for example
640 id: u64,
641 },
642}
643
644/// A set of possible keyboard modifiers.
645#[derive(
646 Debug,
647 Hash,
648 Ord,
649 PartialOrd,
650 PartialEq,
651 Eq,
652 Clone,
653 Copy,
654 Default,
655 Serialize,
656 Deserialize,
657 Reflect,
658 Visit,
659)]
660pub struct KeyboardModifiers {
661 /// `Alt` key is pressed.
662 pub alt: bool,
663 /// `Shift` key is pressed.
664 pub shift: bool,
665 /// `Ctrl` key is pressed.
666 pub control: bool,
667 /// `System` key is pressed.
668 pub system: bool,
669}
670
671impl KeyboardModifiers {
672 /// Checks if the modifiers is empty (nothing is pressed).
673 pub fn is_none(self) -> bool {
674 !self.shift && !self.control && !self.alt && !self.system
675 }
676}
677
678/// Code of a key on keyboard. Shamelessly taken from `winit` source code to match their key codes with
679/// `fyrox-ui`'s.
680#[derive(
681 Debug,
682 Hash,
683 Ord,
684 PartialOrd,
685 PartialEq,
686 Eq,
687 Clone,
688 Copy,
689 AsRefStr,
690 EnumString,
691 VariantNames,
692 Serialize,
693 Deserialize,
694 Reflect,
695 Visit,
696 Default,
697)]
698#[repr(u32)]
699#[allow(missing_docs)]
700pub enum KeyCode {
701 /// This variant is used when the key cannot be translated to any other variant.
702 #[default]
703 Unknown,
704 /// <kbd>`</kbd> on a US keyboard. This is also called a backtick or grave.
705 /// This is the <kbd>半角</kbd>/<kbd>全角</kbd>/<kbd>漢字</kbd>
706 /// (hankaku/zenkaku/kanji) key on Japanese keyboards
707 Backquote,
708 /// Used for both the US <kbd>\\</kbd> (on the 101-key layout) and also for the key
709 /// located between the <kbd>"</kbd> and <kbd>Enter</kbd> keys on row C of the 102-,
710 /// 104- and 106-key layouts.
711 /// Labeled <kbd>#</kbd> on a UK (102) keyboard.
712 Backslash,
713 /// <kbd>[</kbd> on a US keyboard.
714 BracketLeft,
715 /// <kbd>]</kbd> on a US keyboard.
716 BracketRight,
717 /// <kbd>,</kbd> on a US keyboard.
718 Comma,
719 /// <kbd>0</kbd> on a US keyboard.
720 Digit0,
721 /// <kbd>1</kbd> on a US keyboard.
722 Digit1,
723 /// <kbd>2</kbd> on a US keyboard.
724 Digit2,
725 /// <kbd>3</kbd> on a US keyboard.
726 Digit3,
727 /// <kbd>4</kbd> on a US keyboard.
728 Digit4,
729 /// <kbd>5</kbd> on a US keyboard.
730 Digit5,
731 /// <kbd>6</kbd> on a US keyboard.
732 Digit6,
733 /// <kbd>7</kbd> on a US keyboard.
734 Digit7,
735 /// <kbd>8</kbd> on a US keyboard.
736 Digit8,
737 /// <kbd>9</kbd> on a US keyboard.
738 Digit9,
739 /// <kbd>=</kbd> on a US keyboard.
740 Equal,
741 /// Located between the left <kbd>Shift</kbd> and <kbd>Z</kbd> keys.
742 /// Labeled <kbd>\\</kbd> on a UK keyboard.
743 IntlBackslash,
744 /// Located between the <kbd>/</kbd> and right <kbd>Shift</kbd> keys.
745 /// Labeled <kbd>\\</kbd> (ro) on a Japanese keyboard.
746 IntlRo,
747 /// Located between the <kbd>=</kbd> and <kbd>Backspace</kbd> keys.
748 /// Labeled <kbd>¥</kbd> (yen) on a Japanese keyboard. <kbd>\\</kbd> on a
749 /// Russian keyboard.
750 IntlYen,
751 /// <kbd>a</kbd> on a US keyboard.
752 /// Labeled <kbd>q</kbd> on an AZERTY (e.g., French) keyboard.
753 KeyA,
754 /// <kbd>b</kbd> on a US keyboard.
755 KeyB,
756 /// <kbd>c</kbd> on a US keyboard.
757 KeyC,
758 /// <kbd>d</kbd> on a US keyboard.
759 KeyD,
760 /// <kbd>e</kbd> on a US keyboard.
761 KeyE,
762 /// <kbd>f</kbd> on a US keyboard.
763 KeyF,
764 /// <kbd>g</kbd> on a US keyboard.
765 KeyG,
766 /// <kbd>h</kbd> on a US keyboard.
767 KeyH,
768 /// <kbd>i</kbd> on a US keyboard.
769 KeyI,
770 /// <kbd>j</kbd> on a US keyboard.
771 KeyJ,
772 /// <kbd>k</kbd> on a US keyboard.
773 KeyK,
774 /// <kbd>l</kbd> on a US keyboard.
775 KeyL,
776 /// <kbd>m</kbd> on a US keyboard.
777 KeyM,
778 /// <kbd>n</kbd> on a US keyboard.
779 KeyN,
780 /// <kbd>o</kbd> on a US keyboard.
781 KeyO,
782 /// <kbd>p</kbd> on a US keyboard.
783 KeyP,
784 /// <kbd>q</kbd> on a US keyboard.
785 /// Labeled <kbd>a</kbd> on an AZERTY (e.g., French) keyboard.
786 KeyQ,
787 /// <kbd>r</kbd> on a US keyboard.
788 KeyR,
789 /// <kbd>s</kbd> on a US keyboard.
790 KeyS,
791 /// <kbd>t</kbd> on a US keyboard.
792 KeyT,
793 /// <kbd>u</kbd> on a US keyboard.
794 KeyU,
795 /// <kbd>v</kbd> on a US keyboard.
796 KeyV,
797 /// <kbd>w</kbd> on a US keyboard.
798 /// Labeled <kbd>z</kbd> on an AZERTY (e.g., French) keyboard.
799 KeyW,
800 /// <kbd>x</kbd> on a US keyboard.
801 KeyX,
802 /// <kbd>y</kbd> on a US keyboard.
803 /// Labeled <kbd>z</kbd> on a QWERTZ (e.g., German) keyboard.
804 KeyY,
805 /// <kbd>z</kbd> on a US keyboard.
806 /// Labeled <kbd>w</kbd> on an AZERTY (e.g., French) keyboard, and <kbd>y</kbd> on a
807 /// QWERTZ (e.g., German) keyboard.
808 KeyZ,
809 /// <kbd>-</kbd> on a US keyboard.
810 Minus,
811 /// <kbd>.</kbd> on a US keyboard.
812 Period,
813 /// <kbd>'</kbd> on a US keyboard.
814 Quote,
815 /// <kbd>;</kbd> on a US keyboard.
816 Semicolon,
817 /// <kbd>/</kbd> on a US keyboard.
818 Slash,
819 /// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
820 AltLeft,
821 /// <kbd>Alt</kbd>, <kbd>Option</kbd>, or <kbd>⌥</kbd>.
822 /// This is labeled <kbd>AltGr</kbd> on many keyboard layouts.
823 AltRight,
824 /// <kbd>Backspace</kbd> or <kbd>⌫</kbd>.
825 /// Labeled <kbd>Delete</kbd> on Apple keyboards.
826 Backspace,
827 /// <kbd>CapsLock</kbd> or <kbd>⇪</kbd>
828 CapsLock,
829 /// The application context menu key, which is typically found between the right
830 /// <kbd>Super</kbd> key and the right <kbd>Control</kbd> key.
831 ContextMenu,
832 /// <kbd>Control</kbd> or <kbd>⌃</kbd>
833 ControlLeft,
834 /// <kbd>Control</kbd> or <kbd>⌃</kbd>
835 ControlRight,
836 /// <kbd>Enter</kbd> or <kbd>↵</kbd>. Labeled <kbd>Return</kbd> on Apple keyboards.
837 Enter,
838 /// The Windows, <kbd>⌘</kbd>, <kbd>Command</kbd>, or other OS symbol key.
839 SuperLeft,
840 /// The Windows, <kbd>⌘</kbd>, <kbd>Command</kbd>, or other OS symbol key.
841 SuperRight,
842 /// <kbd>Shift</kbd> or <kbd>⇧</kbd>
843 ShiftLeft,
844 /// <kbd>Shift</kbd> or <kbd>⇧</kbd>
845 ShiftRight,
846 /// <kbd> </kbd> (space)
847 Space,
848 /// <kbd>Tab</kbd> or <kbd>⇥</kbd>
849 Tab,
850 /// Japanese: <kbd>変</kbd> (henkan)
851 Convert,
852 /// Japanese: <kbd>カタカナ</kbd>/<kbd>ひらがな</kbd>/<kbd>ローマ字</kbd> (katakana/hiragana/romaji)
853 KanaMode,
854 /// Korean: HangulMode <kbd>한/영</kbd> (han/yeong)
855 ///
856 /// Japanese (Mac keyboard): <kbd>か</kbd> (kana)
857 Lang1,
858 /// Korean: Hanja <kbd>한</kbd> (hanja)
859 ///
860 /// Japanese (Mac keyboard): <kbd>英</kbd> (eisu)
861 Lang2,
862 /// Japanese (word-processing keyboard): Katakana
863 Lang3,
864 /// Japanese (word-processing keyboard): Hiragana
865 Lang4,
866 /// Japanese (word-processing keyboard): Zenkaku/Hankaku
867 Lang5,
868 /// Japanese: <kbd>無変換</kbd> (muhenkan)
869 NonConvert,
870 /// <kbd>⌦</kbd>. The forward delete key.
871 /// Note that on Apple keyboards, the key labelled <kbd>Delete</kbd> on the main part of
872 /// the keyboard is encoded as [`Backspace`].
873 ///
874 /// [`Backspace`]: Self::Backspace
875 Delete,
876 /// <kbd>Page Down</kbd>, <kbd>End</kbd>, or <kbd>↘</kbd>
877 End,
878 /// <kbd>Help</kbd>. Not present on standard PC keyboards.
879 Help,
880 /// <kbd>Home</kbd> or <kbd>↖</kbd>
881 Home,
882 /// <kbd>Insert</kbd> or <kbd>Ins</kbd>. Not present on Apple keyboards.
883 Insert,
884 /// <kbd>Page Down</kbd>, <kbd>PgDn</kbd>, or <kbd>⇟</kbd>
885 PageDown,
886 /// <kbd>Page Up</kbd>, <kbd>PgUp</kbd>, or <kbd>⇞</kbd>
887 PageUp,
888 /// <kbd>↓</kbd>
889 ArrowDown,
890 /// <kbd>←</kbd>
891 ArrowLeft,
892 /// <kbd>→</kbd>
893 ArrowRight,
894 /// <kbd>↑</kbd>
895 ArrowUp,
896 /// On the Mac, this is used for the numpad <kbd>Clear</kbd> key.
897 NumLock,
898 /// <kbd>0 Ins</kbd> on a keyboard. <kbd>0</kbd> on a phone or remote control
899 Numpad0,
900 /// <kbd>1 End</kbd> on a keyboard. <kbd>1</kbd> or <kbd>1 QZ</kbd> on a phone or remote control
901 Numpad1,
902 /// <kbd>2 ↓</kbd> on a keyboard. <kbd>2 ABC</kbd> on a phone or remote control
903 Numpad2,
904 /// <kbd>3 PgDn</kbd> on a keyboard. <kbd>3 DEF</kbd> on a phone or remote control
905 Numpad3,
906 /// <kbd>4 ←</kbd> on a keyboard. <kbd>4 GHI</kbd> on a phone or remote control
907 Numpad4,
908 /// <kbd>5</kbd> on a keyboard. <kbd>5 JKL</kbd> on a phone or remote control
909 Numpad5,
910 /// <kbd>6 →</kbd> on a keyboard. <kbd>6 MNO</kbd> on a phone or remote control
911 Numpad6,
912 /// <kbd>7 Home</kbd> on a keyboard. <kbd>7 PQRS</kbd> or <kbd>7 PRS</kbd> on a phone
913 /// or remote control
914 Numpad7,
915 /// <kbd>8 ↑</kbd> on a keyboard. <kbd>8 TUV</kbd> on a phone or remote control
916 Numpad8,
917 /// <kbd>9 PgUp</kbd> on a keyboard. <kbd>9 WXYZ</kbd> or <kbd>9 WXY</kbd> on a phone
918 /// or remote control
919 Numpad9,
920 /// <kbd>+</kbd>
921 NumpadAdd,
922 /// Found on the Microsoft Natural Keyboard.
923 NumpadBackspace,
924 /// <kbd>C</kbd> or <kbd>A</kbd> (All Clear). Also for use with numpads that have a
925 /// <kbd>Clear</kbd> key that is separate from the <kbd>NumLock</kbd> key. On the Mac, the
926 /// numpad <kbd>Clear</kbd> key is encoded as [`NumLock`].
927 ///
928 /// [`NumLock`]: Self::NumLock
929 NumpadClear,
930 /// <kbd>C</kbd> (Clear Entry)
931 NumpadClearEntry,
932 /// <kbd>,</kbd> (thousands separator). For locales where the thousands separator
933 /// is a "." (e.g., Brazil), this key may generate a <kbd>.</kbd>.
934 NumpadComma,
935 /// <kbd>. Del</kbd>. For locales where the decimal separator is "," (e.g.,
936 /// Brazil), this key may generate a <kbd>,</kbd>.
937 NumpadDecimal,
938 /// <kbd>/</kbd>
939 NumpadDivide,
940 NumpadEnter,
941 /// <kbd>=</kbd>
942 NumpadEqual,
943 /// <kbd>#</kbd> on a phone or remote control device. This key is typically found
944 /// below the <kbd>9</kbd> key and to the right of the <kbd>0</kbd> key.
945 NumpadHash,
946 /// <kbd>M</kbd> Add current entry to the value stored in memory.
947 NumpadMemoryAdd,
948 /// <kbd>M</kbd> Clear the value stored in memory.
949 NumpadMemoryClear,
950 /// <kbd>M</kbd> Replace the current entry with the value stored in memory.
951 NumpadMemoryRecall,
952 /// <kbd>M</kbd> Replace the value stored in memory with the current entry.
953 NumpadMemoryStore,
954 /// <kbd>M</kbd> Subtract current entry from the value stored in memory.
955 NumpadMemorySubtract,
956 /// <kbd>*</kbd> on a keyboard. For use with numpads that provide mathematical
957 /// operations (<kbd>+</kbd>, <kbd>-</kbd> <kbd>*</kbd> and <kbd>/</kbd>).
958 ///
959 /// Use `NumpadStar` for the <kbd>*</kbd> key on phones and remote controls.
960 NumpadMultiply,
961 /// <kbd>(</kbd> Found on the Microsoft Natural Keyboard.
962 NumpadParenLeft,
963 /// <kbd>)</kbd> Found on the Microsoft Natural Keyboard.
964 NumpadParenRight,
965 /// <kbd>*</kbd> on a phone or remote control device.
966 ///
967 /// This key is typically found below the <kbd>7</kbd> key and to the left of
968 /// the <kbd>0</kbd> key.
969 ///
970 /// Use <kbd>"NumpadMultiply"</kbd> for the <kbd>*</kbd> key on
971 /// numeric keypads.
972 NumpadStar,
973 /// <kbd>-</kbd>
974 NumpadSubtract,
975 /// <kbd>Esc</kbd> or <kbd>⎋</kbd>
976 Escape,
977 /// <kbd>Fn</kbd> This is typically a hardware key that does not generate a separate code.
978 Fn,
979 /// <kbd>FLock</kbd> or <kbd>FnLock</kbd>. Function Lock key. Found on the Microsoft
980 /// Natural Keyboard.
981 FnLock,
982 /// <kbd>PrtScr SysRq</kbd> or <kbd>Print Screen</kbd>
983 PrintScreen,
984 /// <kbd>Scroll Lock</kbd>
985 ScrollLock,
986 /// <kbd>Pause Break</kbd>
987 Pause,
988 /// Some laptops place this key to the left of the <kbd>↑</kbd> key.
989 ///
990 /// This also the "back" button (triangle) on Android.
991 BrowserBack,
992 BrowserFavorites,
993 /// Some laptops place this key to the right of the <kbd>↑</kbd> key.
994 BrowserForward,
995 /// The "home" button on Android.
996 BrowserHome,
997 BrowserRefresh,
998 BrowserSearch,
999 BrowserStop,
1000 /// <kbd>Eject</kbd> or <kbd>⏏</kbd>. This key is placed in the function section on some Apple
1001 /// keyboards.
1002 Eject,
1003 /// Sometimes labelled <kbd>My Computer</kbd> on the keyboard
1004 LaunchApp1,
1005 /// Sometimes labelled <kbd>Calculator</kbd> on the keyboard
1006 LaunchApp2,
1007 LaunchMail,
1008 MediaPlayPause,
1009 MediaSelect,
1010 MediaStop,
1011 MediaTrackNext,
1012 MediaTrackPrevious,
1013 /// This key is placed in the function section on some Apple keyboards, replacing the
1014 /// <kbd>Eject</kbd> key.
1015 Power,
1016 Sleep,
1017 AudioVolumeDown,
1018 AudioVolumeMute,
1019 AudioVolumeUp,
1020 WakeUp,
1021 // Legacy modifier key. Also called "Super" in certain places.
1022 Meta,
1023 // Legacy modifier key.
1024 Hyper,
1025 Turbo,
1026 Abort,
1027 Resume,
1028 Suspend,
1029 /// Found on Sun’s USB keyboard.
1030 Again,
1031 /// Found on Sun’s USB keyboard.
1032 Copy,
1033 /// Found on Sun’s USB keyboard.
1034 Cut,
1035 /// Found on Sun’s USB keyboard.
1036 Find,
1037 /// Found on Sun’s USB keyboard.
1038 Open,
1039 /// Found on Sun’s USB keyboard.
1040 Paste,
1041 /// Found on Sun’s USB keyboard.
1042 Props,
1043 /// Found on Sun’s USB keyboard.
1044 Select,
1045 /// Found on Sun’s USB keyboard.
1046 Undo,
1047 /// Use for dedicated <kbd>ひらがな</kbd> key found on some Japanese word processing keyboards.
1048 Hiragana,
1049 /// Use for dedicated <kbd>カタカナ</kbd> key found on some Japanese word processing keyboards.
1050 Katakana,
1051 /// General-purpose function key.
1052 /// Usually found at the top of the keyboard.
1053 F1,
1054 /// General-purpose function key.
1055 /// Usually found at the top of the keyboard.
1056 F2,
1057 /// General-purpose function key.
1058 /// Usually found at the top of the keyboard.
1059 F3,
1060 /// General-purpose function key.
1061 /// Usually found at the top of the keyboard.
1062 F4,
1063 /// General-purpose function key.
1064 /// Usually found at the top of the keyboard.
1065 F5,
1066 /// General-purpose function key.
1067 /// Usually found at the top of the keyboard.
1068 F6,
1069 /// General-purpose function key.
1070 /// Usually found at the top of the keyboard.
1071 F7,
1072 /// General-purpose function key.
1073 /// Usually found at the top of the keyboard.
1074 F8,
1075 /// General-purpose function key.
1076 /// Usually found at the top of the keyboard.
1077 F9,
1078 /// General-purpose function key.
1079 /// Usually found at the top of the keyboard.
1080 F10,
1081 /// General-purpose function key.
1082 /// Usually found at the top of the keyboard.
1083 F11,
1084 /// General-purpose function key.
1085 /// Usually found at the top of the keyboard.
1086 F12,
1087 /// General-purpose function key.
1088 /// Usually found at the top of the keyboard.
1089 F13,
1090 /// General-purpose function key.
1091 /// Usually found at the top of the keyboard.
1092 F14,
1093 /// General-purpose function key.
1094 /// Usually found at the top of the keyboard.
1095 F15,
1096 /// General-purpose function key.
1097 /// Usually found at the top of the keyboard.
1098 F16,
1099 /// General-purpose function key.
1100 /// Usually found at the top of the keyboard.
1101 F17,
1102 /// General-purpose function key.
1103 /// Usually found at the top of the keyboard.
1104 F18,
1105 /// General-purpose function key.
1106 /// Usually found at the top of the keyboard.
1107 F19,
1108 /// General-purpose function key.
1109 /// Usually found at the top of the keyboard.
1110 F20,
1111 /// General-purpose function key.
1112 /// Usually found at the top of the keyboard.
1113 F21,
1114 /// General-purpose function key.
1115 /// Usually found at the top of the keyboard.
1116 F22,
1117 /// General-purpose function key.
1118 /// Usually found at the top of the keyboard.
1119 F23,
1120 /// General-purpose function key.
1121 /// Usually found at the top of the keyboard.
1122 F24,
1123 /// General-purpose function key.
1124 F25,
1125 /// General-purpose function key.
1126 F26,
1127 /// General-purpose function key.
1128 F27,
1129 /// General-purpose function key.
1130 F28,
1131 /// General-purpose function key.
1132 F29,
1133 /// General-purpose function key.
1134 F30,
1135 /// General-purpose function key.
1136 F31,
1137 /// General-purpose function key.
1138 F32,
1139 /// General-purpose function key.
1140 F33,
1141 /// General-purpose function key.
1142 F34,
1143 /// General-purpose function key.
1144 F35,
1145}
1146
1147/// A fixed set of cursor icons that available on most OSes.
1148#[derive(
1149 Debug,
1150 Copy,
1151 Clone,
1152 PartialEq,
1153 Eq,
1154 Hash,
1155 Default,
1156 Visit,
1157 Reflect,
1158 AsRefStr,
1159 EnumString,
1160 VariantNames,
1161)]
1162pub enum CursorIcon {
1163 /// The platform-dependent default cursor. Often rendered as arrow.
1164 #[default]
1165 Default,
1166
1167 /// A context menu is available for the object under the cursor. Often
1168 /// rendered as an arrow with a small menu-like graphic next to it.
1169 ContextMenu,
1170
1171 /// Help is available for the object under the cursor. Often rendered as a
1172 /// question mark or a balloon.
1173 Help,
1174
1175 /// The cursor is a pointer that indicates a link. Often rendered as the
1176 /// backside of a hand with the index finger extended.
1177 Pointer,
1178
1179 /// A progress indicator. The program is performing some processing, but is
1180 /// different from [`CursorIcon::Wait`] in that the user may still interact
1181 /// with the program.
1182 Progress,
1183
1184 /// Indicates that the program is busy and the user should wait. Often
1185 /// rendered as a watch or hourglass.
1186 Wait,
1187
1188 /// Indicates that a cell or set of cells may be selected. Often rendered as
1189 /// a thick plus-sign with a dot in the middle.
1190 Cell,
1191
1192 /// A simple crosshair (e.g., short line segments resembling a "+" sign).
1193 /// Often used to indicate a two dimensional bitmap selection mode.
1194 Crosshair,
1195
1196 /// Indicates text that may be selected. Often rendered as an I-beam.
1197 Text,
1198
1199 /// Indicates vertical-text that may be selected. Often rendered as a
1200 /// horizontal I-beam.
1201 VerticalText,
1202
1203 /// Indicates an alias of/shortcut to something is to be created. Often
1204 /// rendered as an arrow with a small curved arrow next to it.
1205 Alias,
1206
1207 /// Indicates something is to be copied. Often rendered as an arrow with a
1208 /// small plus sign next to it.
1209 Copy,
1210
1211 /// Indicates something is to be moved.
1212 Move,
1213
1214 /// Indicates that the dragged item cannot be dropped at the current cursor
1215 /// location. Often rendered as a hand or pointer with a small circle with a
1216 /// line through it.
1217 NoDrop,
1218
1219 /// Indicates that the requested action will not be carried out. Often
1220 /// rendered as a circle with a line through it.
1221 NotAllowed,
1222
1223 /// Indicates that something can be grabbed (dragged to be moved). Often
1224 /// rendered as the backside of an open hand.
1225 Grab,
1226
1227 /// Indicates that something is being grabbed (dragged to be moved). Often
1228 /// rendered as the backside of a hand with fingers closed mostly out of
1229 /// view.
1230 Grabbing,
1231
1232 /// The east border to be moved.
1233 EResize,
1234
1235 /// The north border to be moved.
1236 NResize,
1237
1238 /// The north-east corner to be moved.
1239 NeResize,
1240
1241 /// The north-west corner to be moved.
1242 NwResize,
1243
1244 /// The south border to be moved.
1245 SResize,
1246
1247 /// The south-east corner to be moved.
1248 SeResize,
1249
1250 /// The south-west corner to be moved.
1251 SwResize,
1252
1253 /// The west border to be moved.
1254 WResize,
1255
1256 /// The east and west borders to be moved.
1257 EwResize,
1258
1259 /// The south and north borders to be moved.
1260 NsResize,
1261
1262 /// The north-east and south-west corners to be moved.
1263 NeswResize,
1264
1265 /// The north-west and south-east corners to be moved.
1266 NwseResize,
1267
1268 /// Indicates that the item/column can be resized horizontally. Often
1269 /// rendered as arrows pointing left and right with a vertical bar
1270 /// separating them.
1271 ColResize,
1272
1273 /// Indicates that the item/row can be resized vertically. Often rendered as
1274 /// arrows pointing up and down with a horizontal bar separating them.
1275 RowResize,
1276
1277 /// Indicates that the something can be scrolled in any direction. Often
1278 /// rendered as arrows pointing up, down, left, and right with a dot in the
1279 /// middle.
1280 AllScroll,
1281
1282 /// Indicates that something can be zoomed in. Often rendered as a
1283 /// magnifying glass with a "+" in the center of the glass.
1284 ZoomIn,
1285
1286 /// Indicates that something can be zoomed in. Often rendered as a
1287 /// magnifying glass with a "-" in the center of the glass.
1288 ZoomOut,
1289}
1290
1291uuid_provider!(CursorIcon = "da7f3a5f-9d26-460a-8e46-38da25f8a8db");