use new trigger api for interactable

This commit is contained in:
griffi-gh 2024-03-23 15:50:44 +01:00
parent 32cf9dca29
commit 5bc048f911
2 changed files with 20 additions and 19 deletions

View file

@ -53,7 +53,7 @@ ui_main!(
.with_text_size(32) .with_text_size(32)
.add_child(ui); .add_child(ui);
}) })
.on_click(CounterSignal::Decrement) .on_click(|| CounterSignal::Decrement)
.add_child(ui); .add_child(ui);
Container::default() Container::default()
.with_size(size!(60, auto)) .with_size(size!(60, auto))
@ -72,7 +72,7 @@ ui_main!(
.with_text_size(32) .with_text_size(32)
.add_child(ui); .add_child(ui);
}) })
.on_click(CounterSignal::Increment) .on_click(|| CounterSignal::Increment)
.add_child(ui); .add_child(ui);
Br.add_child(ui); Br.add_child(ui);
for _ in 0..*counter { for _ in 0..*counter {

View file

@ -5,9 +5,8 @@
use crate::{ use crate::{
element::{MeasureContext, ProcessContext, UiElement}, element::{MeasureContext, ProcessContext, UiElement},
signal::Signal, signal::{trigger::SignalTrigger, Signal},
}; };
use std::cell::RefCell;
#[non_exhaustive] #[non_exhaustive]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
@ -18,7 +17,7 @@ pub enum InteractableEvent {
} }
/// Wrapper that allows adding click and hover events to any element /// Wrapper that allows adding click and hover events to any element
pub struct Interactable<C: Signal + 'static> { pub struct Interactable {
/// The wrapped element that will be interactable /// The wrapped element that will be interactable
pub element: Box<dyn UiElement>, pub element: Box<dyn UiElement>,
@ -26,20 +25,24 @@ pub struct Interactable<C: Signal + 'static> {
pub event: InteractableEvent, pub event: InteractableEvent,
/// Signal that will be called if the element was clicked in the current frame /// Signal that will be called if the element was clicked in the current frame
pub signal: RefCell<Option<C>>, pub signal: SignalTrigger,
} }
impl<C: Signal + 'static> Interactable<C> { impl Interactable {
pub fn new(element: Box<dyn UiElement>, event: InteractableEvent, signal: C) -> Self { pub fn new<S: Signal, F: Fn() -> S + 'static>(
element: Box<dyn UiElement>,
event: InteractableEvent,
signal: F
) -> Self {
Self { Self {
element, element,
event, event,
signal: RefCell::new(Some(signal)), signal: SignalTrigger::new(signal),
} }
} }
} }
impl<C: Signal + 'static> UiElement for Interactable<C> { impl UiElement for Interactable {
fn name(&self) -> &'static str { fn name(&self) -> &'static str {
"Interactable" "Interactable"
} }
@ -59,9 +62,7 @@ impl<C: Signal + 'static> UiElement for Interactable<C> {
}; };
if event_happened { if event_happened {
if let Some(sig) = self.signal.take() { self.signal.fire(ctx.signal);
ctx.signal.add(sig);
}
} }
self.element.process(ctx) self.element.process(ctx)
@ -71,25 +72,25 @@ impl<C: Signal + 'static> UiElement for Interactable<C> {
/// Extension trait for [`UiElement`] that adds methods to wrap the element in an [`Interactable`] /// Extension trait for [`UiElement`] that adds methods to wrap the element in an [`Interactable`]
pub trait ElementInteractableExt: UiElement { pub trait ElementInteractableExt: UiElement {
/// Wrap the element in an [`Interactable`] that will call the given signal when the specified event occurs /// Wrap the element in an [`Interactable`] that will call the given signal when the specified event occurs
fn into_interactable<C: Signal + 'static>(self, event: InteractableEvent, signal: C) -> Interactable<C>; fn into_interactable<S: Signal, F: Fn() -> S + 'static>(self, event: InteractableEvent, signal: F) -> Interactable;
/// Wrap the element in an [`Interactable`] that will call the given signal when clicked /// Wrap the element in an [`Interactable`] that will call the given signal when clicked
fn on_click<C: Signal + 'static>(self, signal: C) -> Interactable<C>; fn on_click<S: Signal, F: Fn() -> S + 'static>(self, signal: F) -> Interactable;
/// Wrap the element in an [`Interactable`] that will call the given signal while hovered /// Wrap the element in an [`Interactable`] that will call the given signal while hovered
fn on_hover<C: Signal + 'static>(self, signal: C) -> Interactable<C>; fn on_hover<S: Signal, F: Fn() -> S + 'static>(self, signal: F) -> Interactable;
} }
impl<T: UiElement + 'static> ElementInteractableExt for T { impl<T: UiElement + 'static> ElementInteractableExt for T {
fn into_interactable<C: Signal + 'static>(self, event: InteractableEvent, signal: C) -> Interactable<C> { fn into_interactable<S: Signal, F: Fn() -> S + 'static>(self, event: InteractableEvent, signal: F) -> Interactable {
Interactable::new(Box::new(self), event, signal) Interactable::new(Box::new(self), event, signal)
} }
fn on_click<C: Signal + 'static>(self, signal: C) -> Interactable<C> { fn on_click<S: Signal, F: Fn() -> S + 'static>(self, signal: F) -> Interactable {
self.into_interactable(InteractableEvent::Click, signal) self.into_interactable(InteractableEvent::Click, signal)
} }
fn on_hover<C: Signal + 'static>(self, signal: C) -> Interactable<C> { fn on_hover<S: Signal, F: Fn() -> S + 'static>(self, signal: F) -> Interactable {
self.into_interactable(InteractableEvent::Hover, signal) self.into_interactable(InteractableEvent::Hover, signal)
} }
} }