diff --git a/hui-examples/examples/ui_test_5_input.rs b/hui-examples/examples/ui_test_5_input.rs index 1ae6d37..f714a50 100644 --- a/hui-examples/examples/ui_test_5_input.rs +++ b/hui-examples/examples/ui_test_5_input.rs @@ -41,10 +41,7 @@ ui_main!( Text::new("-") .add_child(ui); }) - .into_interactable() - .on_click(|| { - println!("clicked"); - }) + .on_click(CounterSignal::Increment) .add_child(ui); Text::new(counter.to_string()) .with_color(color::BLACK) @@ -58,10 +55,7 @@ ui_main!( Text::new("+") .add_child(ui); }) - .into_interactable() - .on_click(|| { - println!("clicked"); - }) + .on_click(CounterSignal::Decrement) .add_child(ui); }) .add_root(ui, size); diff --git a/hui/src/element/builtin/interactable.rs b/hui/src/element/builtin/interactable.rs index 0f681a5..5addcbe 100644 --- a/hui/src/element/builtin/interactable.rs +++ b/hui/src/element/builtin/interactable.rs @@ -5,51 +5,43 @@ use crate::{ element::{MeasureContext, ProcessContext, UiElement}, - signal::{DummySignal, UiSignal}, + signal::UiSignal, }; use std::cell::RefCell; +#[non_exhaustive] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +pub enum InteractableEvent { + #[default] + Click, + Hover, +} + /// Wrapper that allows adding click and hover events to any element -pub struct Interactable { +pub struct Interactable { /// The wrapped element that will be interactable pub element: Box, - /// Signal that will be called if the element is hovered in the current frame - /// - /// Will be consumed after the first time it's called - pub hovered: RefCell>, + /// Event to listen for + pub event: InteractableEvent, /// Signal that will be called if the element was clicked in the current frame /// /// Will be consumed after the first time it's called - pub clicked: RefCell>, + pub signal: RefCell>, } -impl Interactable { - pub fn new(element: Box) -> Self { +impl Interactable { + pub fn new(element: Box, event: InteractableEvent, signal: C) -> Self { Self { element, - hovered: RefCell::new(None), - clicked: RefCell::new(None), - } - } - - pub fn on_hover(self, hover: H) -> Self { - Self { - hovered: RefCell::new(Some(hover)), - ..self - } - } - - pub fn on_click(self, clicked: C) -> Self { - Self { - clicked: RefCell::new(Some(clicked)), - ..self + event: InteractableEvent::Click, + signal: RefCell::new(Some(signal)), } } } -impl UiElement for Interactable { +impl UiElement for Interactable { fn name(&self) -> &'static str { "Interactable" } @@ -62,9 +54,8 @@ impl UiElement for Interactable { let rect = ctx.measure.rect(ctx.layout.position); //XXX: should we do this AFTER normal process call of wrapped element? - //TODO other events... if ctx.input.check_click(rect) { - if let Some(sig) = self.clicked.take() { + if let Some(sig) = self.signal.take() { //ctx.signal.push(sig); } } @@ -74,11 +65,21 @@ impl UiElement for Interactable { } pub trait ElementInteractableExt: UiElement { - fn into_interactable(self) -> Interactable; + fn into_interactable(self, event: InteractableEvent, signal: C) -> Interactable; + fn on_click(self, signal: C) -> Interactable; + fn on_hover(self, signal: C) -> Interactable; } impl ElementInteractableExt for T { - fn into_interactable(self) -> Interactable { - Interactable::new(Box::new(self)) + fn into_interactable(self, event: InteractableEvent, signal: C) -> Interactable { + Interactable::new(Box::new(self), event, signal) + } + + fn on_click(self, signal: C) -> Interactable { + self.into_interactable(InteractableEvent::Click, signal) + } + + fn on_hover(self, signal: C) -> Interactable { + self.into_interactable(InteractableEvent::Hover, signal) } }