#[non_exhaustive]pub enum Event {
Show 16 variants
Command(Command, Option<PhysicalKey>),
Key(KeyEvent, bool),
Scroll(ScrollDelta),
Pan {
alpha: DVec2,
delta: DVec2,
},
CursorMove {
press: Press,
},
PressStart {
press: Press,
},
PressMove {
press: Press,
delta: Offset,
},
PressEnd {
press: Press,
success: bool,
},
Timer(u64),
NavFocus(FocusSource),
LostNavFocus,
SelFocus(FocusSource),
LostSelFocus,
KeyFocus,
LostKeyFocus,
MouseHover(bool),
}
Expand description
Events addressed to a widget
Note that a few events are received by disabled widgets; see
Event::pass_when_disabled
.
Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
Command(Command, Option<PhysicalKey>)
Command input
A generic “command”. The source is often but not always a key press. In many cases (but not all) the target widget has navigation focus.
A PhysicalKey
is attached when the command is caused by a key press.
The recipient may use this to call EventState::depress_with_key
.
If a widget has keyboard input focus (see
EventState::request_key_focus
) it will instead receive
Event::Key
for key presses (but may still receive Event::Command
from other sources).
Key(KeyEvent, bool)
Keyboard input: event, is_synthetic
This is only received by a widget with character focus (see
EventState::request_key_focus
).
On some platforms, synthetic key events are generated when a window
gains or loses focus with a key held (see documentation of
[winit::event::WindowEvent::KeyboardInput
]). This is indicated by the
second parameter, is_synthetic
. Unless you need to track key states
it is advised only to match Event::Key(event, false)
.
Some key presses can be mapped to a Command
. To do this (normally
only when event.state == ElementState::Pressed && !is_synthetic
), use
cx.config().shortcuts(|s| s.try_match(cx.modifiers(), &event.logical_key)
or (omitting shortcut matching) Command::new(event.logical_key)
.
Note that if the handler returns Unused
the widget might
then receive Event::Command
for the same key press, but this is not
guaranteed (behaviour may change in future versions).
For standard text input, simply consume event.text
when
event.state == ElementState::Pressed && !is_synthetic
.
NOTE: unlike Winit, we force text = None
for control chars and when
Ctrl, Alt or Super modifier keys are
pressed. This is subject to change.
Scroll(ScrollDelta)
A mouse or touchpad scroll event
Pan
A mouse or touch-screen move/zoom/rotate event
This event is sent for certain types of grab (Press::grab
),
enabling two-finger scale/rotate gestures as well as translation.
Mouse-grabs generate translation (delta
component) only. Touch grabs
optionally also generate rotation and scaling components, depending on
the GrabMode
.
In general, a point p
on the screen should be transformed as follows:
let mut p = Coord::ZERO; // or whatever
p = (alpha.complex_mul(p.cast()) + delta).cast_nearest();
When it is known that there is no rotational component, one can use a
simpler transformation: alpha.0 * p + delta
. When there is also no
scaling component, we just have a translation: p + delta
.
Note however that if events are generated with rotation and/or scaling
components, these simplifications are invalid.
Two such transforms may be combined as follows:
let alpha = alpha2.complex_mul(alpha1);
let delta = alpha2.complex_mul(delta1) + delta2;
If instead one uses a transform to map screen-space to world-space, this transform should be adjusted as follows:
world_alpha = world_alpha.complex_div(alpha.into());
world_delta = world_delta - world_alpha.complex_mul(delta.into());
Those familiar with complex numbers may recognise that
alpha = a * e^{i*t}
where a
is the scale component and t
is the
angle of rotation. Calculate these components as follows:
let a = (alpha.0 * alpha.0 + alpha.1 * alpha.1).sqrt();
let t = (alpha.1).atan2(alpha.0);
CursorMove
Movement of mouse cursor without press
This event is sent only when:
- No
Press::grab
is active - A
Popup
is open
The parent (or an ancestor) of a Popup
should handle or explicitly
ignore this event.
PressStart
A mouse button was pressed or touch event started
Call Press::grab
in order to “grab” corresponding motion
and release events.
This event is sent in exactly two cases, in this order:
- When a
Popup
is open. APopup
will close itself ifpress.id
is not a descendant of itself, but will still returnUnused
. The parent (or an ancestor) of thePopup
should handle this event. - If a widget is found under the mouse when pressed or where a touch event starts, this event is sent to the widget.
If start_id
is None
, then no widget was found at the coordinate and
the event will only be delivered to pop-up layer owners.
PressMove
Movement of mouse or a touch press
This event is only sent when a (Press::grab
) is active.
Motion events for the grabbed mouse pointer or touched finger are sent.
If cur_id
is None
, no widget was found at the coordinate (either
outside the window or crate::Layout::find_id
failed).
PressEnd
End of a click/touch press
If success
, this is a button-release or touch finish; otherwise this
is a cancelled/interrupted grab. “Activation events” (e.g. clicking of a
button or menu item) should only happen on success
. “Movement events”
such as panning, moving a slider or opening a menu should not be undone
when cancelling: the panned item or slider should be released as is, or
the menu should remain open.
This event is only sent when a (Press::grab
) is active.
Release/cancel events for the same mouse button or touched finger are
sent.
If cur_id
is None
, no widget was found at the coordinate (either
outside the window or crate::Layout::find_id
failed).
Timer(u64)
Update from a timer
This event is received after requesting timed wake-up(s)
(see EventState::request_timer
).
The u64
payload is copied from EventState::request_timer
.
Notification that a widget has gained navigation focus
Navigation focus implies that the widget is highlighted and will be the
primary target of Event::Command
, and is thus able to receive basic
keyboard input (e.g. arrow keys). To receive full keyboard input
(Event::Key
), call EventState::request_key_focus
.
With FocusSource::Pointer
the widget should already have received
Event::PressStart
.
With FocusSource::Key
, EventCx::set_scroll
is
called automatically (to ensure that the widget is visible) and the
response will be forced to Used
.
Notification that a widget has lost navigation focus
SelFocus(FocusSource)
Notification that a widget has gained selection focus
This focus must be requested by calling
EventState::request_sel_focus
or EventState::request_key_focus
.
LostSelFocus
Notification that a widget has lost selection focus
In the case the widget also had character focus, Event::LostKeyFocus
is
received first.
KeyFocus
Notification that a widget has gained keyboard input focus
This focus must be requested by calling
EventState::request_key_focus
.
This is always preceeded by Event::SelFocus
and is received prior to
Event::Key
events.
LostKeyFocus
Notification that a widget has lost keyboard input focus
MouseHover(bool)
Notification that a widget gains or loses mouse hover
The payload is true
when focus is gained, false
when lost.
Implementations§
source§impl Event
impl Event
sourcepub fn on_activate<F>(self, cx: &mut EventCx<'_>, id: Id, f: F) -> IsUsed
pub fn on_activate<F>(self, cx: &mut EventCx<'_>, id: Id, f: F) -> IsUsed
Call f
on any “activation” event
Activation is considered:
- Mouse click and release on the same widget
- Touchscreen press and release on the same widget
Event::Command(cmd, _)
wherecmd.is_activate()
The method calls EventState::depress_with_key
on activation.
sourcepub fn pass_when_disabled(&self) -> bool
pub fn pass_when_disabled(&self) -> bool
Pass to disabled widgets?
Disabled status should disable input handling but not prevent other notifications.
sourcepub fn is_reusable(&self) -> bool
pub fn is_reusable(&self) -> bool
Can the event be received by Events::handle_event
during unwinding?
Events which may be sent to the widget under the mouse or to the
keyboard navigation target may be acted on by an ancestor if unused.
Other events may not be; e.g. Event::PressMove
and
Event::PressEnd
are only received by the widget requesting them
while Event::LostKeyFocus
(and similar events) are only sent to a
specific widget.
Trait Implementations§
source§impl AddAssign<Offset> for Event
impl AddAssign<Offset> for Event
source§fn add_assign(&mut self, offset: Offset)
fn add_assign(&mut self, offset: Offset)
+=
operation. Read moresource§impl PartialEq for Event
impl PartialEq for Event
impl StructuralPartialEq for Event
Auto Trait Implementations§
impl RefUnwindSafe for Event
impl !Send for Event
impl !Sync for Event
impl Unpin for Event
impl UnwindSafe for Event
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<S, T> CastApprox<T> for Swhere
T: ConvApprox<S>,
impl<S, T> CastApprox<T> for Swhere
T: ConvApprox<S>,
§fn try_cast_approx(self) -> Result<T, Error>
fn try_cast_approx(self) -> Result<T, Error>
§fn cast_approx(self) -> T
fn cast_approx(self) -> T
§impl<S, T> CastFloat<T> for Swhere
T: ConvFloat<S>,
impl<S, T> CastFloat<T> for Swhere
T: ConvFloat<S>,
§fn cast_trunc(self) -> T
fn cast_trunc(self) -> T
§fn cast_nearest(self) -> T
fn cast_nearest(self) -> T
§fn cast_floor(self) -> T
fn cast_floor(self) -> T
§fn try_cast_trunc(self) -> Result<T, Error>
fn try_cast_trunc(self) -> Result<T, Error>
§fn try_cast_nearest(self) -> Result<T, Error>
fn try_cast_nearest(self) -> Result<T, Error>
§fn try_cast_floor(self) -> Result<T, Error>
fn try_cast_floor(self) -> Result<T, Error>
§fn try_cast_ceil(self) -> Result<T, Error>
fn try_cast_ceil(self) -> Result<T, Error>
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.