1use makepad_render::*;
2use crate::buttonlogic::*;
3use crate::widgetstyle::*;
4
5#[derive(Clone)]
6pub struct NormalButton {
7 pub button: ButtonLogic,
8 pub bg: Quad,
9 pub text: Text,
10 pub animator: Animator,
11 pub _bg_area: Area,
12 pub _text_area: Area
13}
14
15impl NormalButton {
16 pub fn proto(cx: &mut Cx) -> Self {
17 Self {
18 button: ButtonLogic::default(),
19 bg: Quad::proto(cx),
20 text: Text::proto(cx),
21 animator: Animator::default(),
22 _bg_area: Area::Empty,
23 _text_area: Area::Empty,
24 }
25 }
26
27 pub fn layout_bg() -> LayoutId {uid!()}
28 pub fn text_style_label() -> TextStyleId {uid!()}
29 pub fn anim_default() -> AnimId {uid!()}
30 pub fn anim_over() -> AnimId {uid!()}
31 pub fn anim_down() -> AnimId {uid!()}
32 pub fn shader_bg() -> ShaderId {uid!()}
33 pub fn instance_hover() -> InstanceFloat {uid!()}
34 pub fn instance_down() -> InstanceFloat {uid!()}
35
36 pub fn style(cx: &mut Cx, _opt: &StyleOptions) {
37 Self::layout_bg().set(cx, Layout {
38 align: Align::center(),
39 walk: Walk {
40 width: Width::Compute,
41 height: Height::Compute,
42 margin: Margin::all(1.0),
43 },
44 padding: Padding {l: 16.0, t: 12.0, r: 16.0, b: 12.0},
45 ..Default::default()
46 });
47
48 Self::text_style_label().set(cx, TextStyle {
49 ..Theme::text_style_normal().get(cx)
50 });
51
52 Self::anim_default().set(cx,Anim::new(Play::Cut {duration: 0.1}, vec![
53 Track::float(Self::instance_hover(), Ease::Lin, vec![(1., 0.)]),
54 Track::float(Self::instance_down(), Ease::Lin, vec![(1.0, 0.)]),
55 Track::color(Text::instance_color(), Ease::Lin, vec![(1., color("#9"))]),
56 ]));
57
58 Self::anim_over().set(cx, Anim::new(Play::Cut {duration: 0.1}, vec![
59 Track::float(Self::instance_down(), Ease::Lin, vec![(0., 0.)]),
60 Track::float(Self::instance_hover(), Ease::Lin, vec![(0.0, 1.0), (1.0, 1.0)]),
61 Track::color(Text::instance_color(), Ease::Lin, vec![(0., color("#f"))]),
62 ]));
63
64 Self::anim_down().set(cx,Anim::new(Play::Cut {duration: 0.2}, vec![
65 Track::float(Self::instance_down(), Ease::OutExp, vec![(0.0, 1.0), (1.0, 1.0)]),
66 Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 1.0)]),
67 Track::color(Text::instance_color(), Ease::Lin, vec![(0., color("#c"))]),
68 ]));
69
70 Self::shader_bg().set(cx, Quad::def_quad_shader().compose(shader_ast!({
72
73 let hover: Self::instance_hover();
74 let down: Self::instance_down();
75 const shadow: float = 3.0;
76 const border_radius: float = 2.5;
77 fn pixel() -> vec4 {
78 df_viewport(pos * vec2(w, h));
79 df_box(shadow, shadow, w - shadow*(1.+down), h- shadow*(1.+down), border_radius);
80 df_blur = 6.0;
81 df_fill(mix(color("#0007"), color("#0"), hover));
82 df_blur = 0.001;
83 df_box(shadow, shadow, w - shadow*2., h - shadow*2., border_radius);
84 return df_fill(mix(mix(color("#3"),color("#4"),hover), color("#2a2a2a"), down));
85 }
86 })));
87 }
88
89 pub fn handle_normal_button(&mut self, cx: &mut Cx, event: &mut Event) -> ButtonEvent {
90 let animator = &mut self.animator;
92 let text_area = self._text_area;
93 self.button.handle_button_logic(cx, event, self._bg_area, | cx, logic_event, area | match logic_event {
94 ButtonLogicEvent::Animate(ae) => {
95 animator.calc_area(cx, area, ae.time);
96 animator.calc_area(cx, text_area, ae.time);
97 },
98 ButtonLogicEvent::AnimEnded(_) => animator.end(),
99 ButtonLogicEvent::Down => animator.play_anim(cx, Self::anim_down().get(cx)),
100 ButtonLogicEvent::Default => animator.play_anim(cx, Self::anim_default().get(cx)),
101 ButtonLogicEvent::Over => animator.play_anim(cx, Self::anim_over().get(cx))
102 })
103 }
104
105 pub fn draw_normal_button(&mut self, cx: &mut Cx, label: &str) {
106 self.bg.shader = Self::shader_bg().get(cx);
107
108 self.animator.init(cx, | cx | Self::anim_default().get(cx));
109
110 self.bg.color = self.animator.last_color(cx, Quad::instance_color());
111
112 let bg_inst = self.bg.begin_quad(cx, Self::layout_bg().get(cx));
113
114 bg_inst.push_last_float(cx, &self.animator, Self::instance_hover());
115 bg_inst.push_last_float(cx, &self.animator, Self::instance_down());
116
117 self.text.text_style = Self::text_style_label().get(cx);
118 self.text.color = self.animator.last_color(cx, Text::instance_color());
119
120 self._text_area = self.text.draw_text(cx, label);
121
122 self._bg_area = self.bg.end_quad(cx, &bg_inst);
123 self.animator.set_area(cx, self._bg_area);
124 }
125}