Newer
Older
use bevy::prelude::{Entity, World};
use crate::{
cursor::{CursorEvent, ScrollEvent},
keyboard_event::KeyboardEvent,
prelude::{KayakWidgetContext, OnChange},
#[derive(Clone)]
/// Indicates whether this event should propagate or not
/// Indicates whether the default action of this event (if any) has been prevented
pub(crate) default_prevented: bool,
/// OnChange systems to call afterwards
pub(crate) on_change_systems: Vec<OnChange>,
impl PartialEq for Event {
fn eq(&self, other: &Self) -> bool {
self.target == other.target
&& self.current_target == other.current_target
&& self.event_type == other.event_type
&& self.should_propagate == other.should_propagate
&& self.default_prevented == other.default_prevented
}
}
impl Default for Event {
fn default() -> Self {
Self {
target: Entity::from_raw(0),
current_target: Entity::from_raw(0),
impl Event {
/// Create a new event
///
/// This is the preferred method for creating an event as it automatically sets up
/// propagation and other event metadata in a standardized manner
pub fn new(target: Entity, event_type: EventType) -> Self {
Self {
target,
current_target: target,
event_type,
should_propagate: event_type.propagates(),
}
}
/// Returns whether this event is currently set to propagate
pub fn propagates(&self) -> bool {
self.should_propagate
}
/// If called, prevents this event from propagating up the hierarchy
pub fn stop_propagation(&mut self) {
if matches!(
self.event_type,
EventType::Click(..)
| EventType::MouseIn(..)
| EventType::MouseDown(..)
| EventType::Scroll(..)
| EventType::Focus
| EventType::Hover(..)
) {
self.should_propagate = false;
}
/// Returns whether this event's default action has been prevented or not
pub fn is_default_prevented(&self) -> bool {
self.default_prevented
}
/// Prevents this event's default action (if any) from being executed
pub fn prevent_default(&mut self) {
self.default_prevented = true;
}
pub fn add_system(&mut self, system: OnChange) {
self.on_change_systems.push(system);
}
pub(crate) fn run_on_change(&mut self, world: &mut World, widget_context: KayakWidgetContext) {
for system in self.on_change_systems.drain(..) {
system.try_call(self.current_target, world, widget_context.clone());
}
}
/// The type of event
///
/// __Note:__ This type implements `PartialEq` and `Hash` in a way that only considers the variant itself,
/// not the underlying data. If full comparisons are needed, they should be done with the inner data or
/// with a custom wrapper.
/// An event that occurs when the user hovers the cursor over a widget
/// An event that occurs when the user moves the cursor into a widget
/// An event that occurs when the user moves the cursor out of a widget
/// An event that occurs when the user presses down on the cursor over a widget
/// An event that occurs when the user releases the cursor over a widget
/// An event that occurs when the user scrolls over a widget
Scroll(ScrollEvent),

StarArawn
committed
Focus,

StarArawn
committed
Blur,
/// An event that occurs when the user types in a character within a _focused_ widget
/// An event that occurs when the user releases a key within a _focused_ widget
/// An event that occurs when the user presses a key down within a _focused_ widget
KeyDown(KeyboardEvent),
}
impl Eq for EventType {}
/// __Note:__ Only checks if the two event types are the same discriminant
fn eq(&self, other: &Self) -> bool {
std::mem::discriminant(self) == std::mem::discriminant(other)
impl std::hash::Hash for EventType {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
std::hash::Hash::hash(&std::mem::discriminant(self), state);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EventCategory {
Focus,
}
impl EventType {
/// Returns whether this event type should propagate by default
///
/// For more details on what should and shouldn't propagate, check out the
/// [W3 specifications](https://www.w3.org/TR/uievents/#event-types), upon which this is based.
pub fn propagates(&self) -> bool {
match self {
// Propagates
Self::Hover(..) => true,
Self::Click(..) => true,
Self::MouseDown(..) => true,
Self::MouseUp(..) => true,
Self::KeyUp(..) => true,
Self::KeyDown(..) => true,
Self::Focus => false,
Self::Blur => false,
}
}
/// Get the category of this event
pub fn event_category(&self) -> EventCategory {
match self {
// Mouse
Self::Hover(..) => EventCategory::Mouse,
Self::Click(..) => EventCategory::Mouse,
Self::MouseDown(..) => EventCategory::Mouse,
Self::MouseUp(..) => EventCategory::Mouse,
Self::MouseIn(..) => EventCategory::Mouse,
Self::MouseOut(..) => EventCategory::Mouse,
// Keyboard
Self::CharInput { .. } => EventCategory::Keyboard,
Self::KeyUp(..) => EventCategory::Keyboard,
Self::KeyDown(..) => EventCategory::Keyboard,
// Focus
Self::Focus => EventCategory::Focus,
Self::Blur => EventCategory::Focus,
}
}