nuit_core/compose/view/widget/
button.rs1use nuit_derive::Bind;
2
3use crate::{View, Node, Context, Event, IdPath, Id, IdentifyExt};
4
5use super::Text;
6
7#[derive(Debug, Clone, PartialEq, Eq, Bind)]
9pub struct Button<T, F> {
10 label: T,
11 action: Option<F>,
12}
13
14impl<T, F> Button<T, F> {
15 pub fn new(label: T, action: F) -> Self {
16 Self {
17 label,
18 action: Some(action),
19 }
20 }
21}
22
23impl<F> Button<Text, F> {
24 pub fn with_text(label: impl Into<String>, action: F) -> Self {
25 Self {
26 label: Text::new(label),
27 action: Some(action),
28 }
29 }
30}
31
32impl<T, F> View for Button<T, F> where T: View, F: Fn() + 'static {
33 fn fire(&self, event: &Event, event_path: &IdPath, context: &Context) {
34 if let Some(head) = event_path.head() {
35 match head {
36 Id::Index(0) => self.label.fire(event, &event_path.tail(), &context.child(0)),
37 i => panic!("Cannot fire event for child id {} on Button which only has one child", i)
38 }
39 } else if let Event::ButtonTap {} = event {
40 if let Some(ref action) = self.action {
41 action();
42 }
43 }
44 }
45
46 fn render(&self, context: &Context) -> Node {
47 Node::Button { label: Box::new(self.label.render(&context.child(0)).identify(0)) }
48 }
49}