use bevy::prelude::*;
use bevy_cobweb::prelude::*;
use crate::prelude::*;
use crate::sickle::*;
fn flux_ui_events(
mut c: Commands,
fluxes: Query<(Entity, &FluxInteraction, Option<&PseudoStates>), Changed<FluxInteraction>>,
)
{
for (entity, flux, maybe_pseudo_states) in fluxes.iter() {
if let Some(pseudo_states) = maybe_pseudo_states {
if pseudo_states.has(&PseudoState::Disabled) {
continue;
}
}
match *flux {
FluxInteraction::None => (),
FluxInteraction::PointerEnter => {
c.react().entity_event(entity, PointerEnter);
}
FluxInteraction::PointerLeave => {
c.react().entity_event(entity, PointerLeave);
}
FluxInteraction::Pressed => {
c.react().entity_event(entity, PointerPressed);
}
FluxInteraction::Released => {
c.react().entity_event(entity, PointerReleased);
}
FluxInteraction::PressCanceled => {
c.react().entity_event(entity, PressCanceled);
}
FluxInteraction::Disabled => {
}
}
}
}
pub struct PointerEnter;
pub struct PointerLeave;
pub struct PointerPressed;
pub struct PointerReleased;
pub struct PressCanceled;
pub trait UiInteractionExt
{
fn on_pointer_enter<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self;
fn on_pointer_leave<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self;
fn on_pressed<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self;
fn on_released<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self;
fn on_press_canceled<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self;
}
impl UiInteractionExt for UiBuilder<'_, Entity>
{
fn on_pointer_enter<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self
{
self.apply(Interactive);
self.on_event::<PointerEnter>().r(callback);
self
}
fn on_pointer_leave<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self
{
self.apply(Interactive);
self.on_event::<PointerLeave>().r(callback);
self
}
fn on_pressed<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self
{
self.apply(Interactive);
self.on_event::<PointerPressed>().r(callback);
self
}
fn on_released<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self
{
self.apply(Interactive);
self.on_event::<PointerReleased>().r(callback);
self
}
fn on_press_canceled<R: CobwebResult, M>(
&mut self,
callback: impl IntoSystem<(), R, M> + Send + Sync + 'static,
) -> &mut Self
{
self.apply(Interactive);
self.on_event::<PressCanceled>().r(callback);
self
}
}
#[derive(Reflect, Default, Debug, Clone, PartialEq)]
pub struct Interactive;
impl Instruction for Interactive
{
fn apply(self, entity: Entity, world: &mut World)
{
let _ = world.get_entity_mut(entity).map(|mut e| {
e.insert((Interaction::default(), TrackedInteraction::default()));
});
}
fn revert(entity: Entity, world: &mut World)
{
let _ = world.get_entity_mut(entity).map(|mut e| {
e.remove::<(Interaction, TrackedInteraction)>();
});
}
}
pub(crate) struct UiInteractionExtPlugin;
impl Plugin for UiInteractionExtPlugin
{
fn build(&self, app: &mut App)
{
app.register_instruction_type::<Interactive>().add_systems(
Update,
flux_ui_events
.after(FluxInteractionUpdate)
.before(ApplyFluxChanges),
);
}
}