1use makepad_render::*;
2use crate::buttonlogic::*;
3use crate::widgetstyle::*;
4
5#[derive(Clone)]
6pub struct DesktopButton {
7 pub button: ButtonLogic,
8 pub bg: Quad,
9 pub animator: Animator,
10 pub _bg_area: Area,
11}
12
13pub enum DesktopButtonType {
14 WindowsMin,
15 WindowsMax,
16 WindowsMaxToggled,
17 WindowsClose,
18 VRMode,
19}
20
21impl DesktopButtonType {
22 fn shader_float(&self) -> f32 {
23 match self {
24 DesktopButtonType::WindowsMin => 1.,
25 DesktopButtonType::WindowsMax => 2.,
26 DesktopButtonType::WindowsMaxToggled => 3.,
27 DesktopButtonType::WindowsClose => 4.,
28 DesktopButtonType::VRMode => 5.,
29 }
30 }
31}
32
33impl DesktopButton {
34 pub fn proto(cx: &mut Cx) -> Self {
35 Self {
36 button: ButtonLogic::default(),
37 bg: Quad::proto(cx),
38 animator: Animator::default(),
39 _bg_area: Area::Empty,
40 }
41 }
42
43 pub fn instance_hover()->InstanceFloat{uid!()}
44 pub fn instance_down()->InstanceFloat{uid!()}
45 pub fn instance_type()->InstanceFloat{uid!()}
46
47 pub fn anim_default() -> AnimId {uid!()}
48 pub fn anim_over() -> AnimId {uid!()}
49 pub fn anim_down() -> AnimId {uid!()}
50 pub fn shader_bg() -> ShaderId {uid!()}
51
52 pub fn style(cx: &mut Cx, _opt: &StyleOptions) {
53
54 Self::anim_default().set(cx,Anim::new(Play::Cut {duration: 0.2}, vec![
55 Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 0.)]),
56 Track::float(Self::instance_down(), Ease::Lin, vec![(1.0, 0.)]),
57 ]));
58
59 Self::anim_over().set(cx, Anim::new(Play::Cut {duration: 0.2}, vec![
60 Track::float(Self::instance_down(), Ease::Lin, vec![(1.0, 0.)]),
61 Track::float(Self::instance_hover(), Ease::Lin, vec![(0.0, 1.0), (1.0, 1.0)]),
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, 0.0), (1.0, 3.1415 * 0.5)]),
66 Track::float(Self::instance_hover(), Ease::Lin, vec![(1.0, 1.0)]),
67 ]));
68
69 Self::shader_bg().set(cx,Quad::def_quad_shader().compose(shader_ast!({
70
71 let hover: Self::instance_hover();
72 let down: Self::instance_down();
73 let button_type: Self::instance_type();
74
75 fn pixel() -> vec4 {
76 df_viewport(pos * vec2(w, h)); df_aa *= 3.0;
78 let sz = 4.5;
79 let c = vec2(w, h) * vec2(0.5, 0.5);
80 if abs(button_type - 1.) < 0.1 {
82 df_clear(mix(color("#3"), mix(color("#6"), color("#9"), down), hover));
83 df_move_to(c.x - sz, c.y);
84 df_line_to(c.x + sz, c.y);
85 df_stroke(color("white"), 0.5 + 0.5 * dpi_dilate);
86 return df_result;
87 }
88 if abs(button_type - 2.) < 0.1 {
90 df_clear(mix(color("#3"), mix(color("#6"), color("#9"), down), hover));
91 df_rect(c.x - sz, c.y - sz, 2. * sz, 2. * sz);
92 df_stroke(color("white"), 0.5 + 0.5 * dpi_dilate);
93 return df_result;
94 }
95 if abs(button_type - 3.) < 0.1 {
97 let clear = mix(color("#3"), mix(color("#6"), color("#9"), down), hover);
98 df_clear(clear);
99 let sz = 3.5;
100 df_rect(c.x - sz + 1., c.y - sz - 1., 2. * sz, 2. * sz);
101 df_stroke(color("white"), 0.5 + 0.5 * dpi_dilate);
102 df_rect(c.x - sz - 1., c.y - sz + 1., 2. * sz, 2. * sz);
103 df_fill_keep(clear);
104 df_stroke(color("white"), 0.5 + 0.5 * dpi_dilate);
105
106 return df_result;
107 }
108 if abs(button_type - 4.) < 0.1 {
110 df_clear(mix(color("#3"), mix(color("#e00"), color("#c00"), down), hover));
111 df_move_to(c.x - sz, c.y - sz);
112 df_line_to(c.x + sz, c.y + sz);
113 df_move_to(c.x - sz, c.y + sz);
114 df_line_to(c.x + sz, c.y - sz);
115 df_stroke(color("white"), 0.5 + 0.5 * dpi_dilate);
116 return df_result;
117 }
118 if abs(button_type - 5.) < 0.1 {
120 df_clear(mix(color("#3"), mix(color("#0aa"), color("#077"), down), hover));
121 let w = 12.;
122 let h = 8.;
123 df_box(c.x - w, c.y - h, 2. * w, 2. * h, 2.);
124 df_circle(c.x - 5.5,c.y,3.5);
126 df_subtract();
127 df_circle(c.x + 5.5,c.y,3.5);
128 df_subtract();
129 df_circle(c.x, c.y + h-0.75,2.5);
130 df_subtract();
131 df_fill(color("#8"));
132
133 return df_result;
134 }
135 return color("red")}
144 })));
145 }
146
147 pub fn handle_button(&mut self, cx: &mut Cx, event: &mut Event) -> ButtonEvent {
148 let animator = &mut self.animator;
150 self.button.handle_button_logic(cx, event, self._bg_area, | cx, logic_event, area | match logic_event {
151 ButtonLogicEvent::Animate(ae) => animator.calc_area(cx, area, ae.time),
152 ButtonLogicEvent::AnimEnded(_)=> animator.end(),
153 ButtonLogicEvent::Down => animator.play_anim(cx, Self::anim_down().get(cx)),
154 ButtonLogicEvent::Default=> animator.play_anim(cx, Self::anim_default().get(cx)),
155 ButtonLogicEvent::Over=>animator.play_anim(cx, Self::anim_over().get(cx))
156 })
157 }
158
159 pub fn draw_desktop_button(&mut self, cx: &mut Cx, ty: DesktopButtonType) {
160 self.animator.init(cx, |cx| Self::anim_default().get(cx));
162 let (w,h) = match ty {
163 DesktopButtonType::WindowsMin
164 | DesktopButtonType::WindowsMax
165 | DesktopButtonType::WindowsMaxToggled
166 | DesktopButtonType::WindowsClose => (46.,29.),
167 DesktopButtonType::VRMode => (50.,36.),
168 };
169 self.bg.shader = Self::shader_bg().get(cx);
170 let bg_inst = self.bg.draw_quad(cx, Walk::wh(Width::Fix(w), Height::Fix(h)));
171 bg_inst.push_last_float(cx, &self.animator, Self::instance_down());
172 bg_inst.push_last_float(cx, &self.animator, Self::instance_hover());
173 bg_inst.push_float(cx, ty.shader_float());
174 self._bg_area = bg_inst.into();
175 self.animator.set_area(cx, self._bg_area); }
177}