1use makepad_widgets::*;
2
3live_design! {
4 use link::theme::*;
5 use link::shaders::*;
6 use link::widgets::*;
7
8 // Define a common button style
9 // Inherit from Button
10 MyButton = {{MyButton}} <Button> {
11 width: 200, // Button width
12 height: 50, // Button height
13 margin: {left: 20, right: 20}, // Button left and right margins
14
15 text: "My Button", // Button text
16 draw_text: {
17 color: #ffffff // Text color is white
18 },
19
20 draw_bg: {
21 // Here define at most 6 instances, otherwise will report subtract with overflow
22 instance background_color: #0000ff, // Background color
23 instance hover_color: #0055ff, // Mouse hover color
24 instance pressed_color: #00008B, // Mouse pressed color
25
26 instance border_width: 1.0, // Border width
27 instance border_color: #00f3ff, // Border color
28
29 instance glow: 0.0, // Glow effect control
30 instance hover: 0.0, // Control mouse hover effect
31 instance pressed: 0.0, // Control mouse pressed effect
32
33 fn pixel(self) -> vec4 {
34 let sdf = Sdf2d::viewport(self.pos * self.rect_size);
35
36 // Calculate scale and offset
37 let scale = 1.0 - self.pressed * 0.04; // Slightly shrink when pressed
38 let size = self.rect_size * scale;
39 let offset = (self.rect_size - size) * 0.5; // Center
40
41 // Draw outer glow
42 sdf.box(
43 offset.x,
44 offset.y,
45 size.x,
46 size.y,
47 9.0 // Slightly larger corner radius
48 );
49
50 // Glow effect - use semi-transparent border color
51 let glow_alpha = self.glow * 0.5; // Control glow intensity
52 sdf.fill_keep(vec4(self.border_color.xyz, glow_alpha));
53
54
55 // Simplify drawing, keep only the main body
56 sdf.box(
57 offset.x,
58 offset.y,
59 size.x,
60 size.y,
61 8.0
62 );
63
64 // Show shadow when not pressed, reduce shadow when pressed
65 let shadow_alpha = (1.0 - self.pressed) * 0.2;
66 sdf.fill_keep(vec4(0.,0.,0.,shadow_alpha));
67
68 // Base color
69 let base_color = self.background_color;
70
71 // Hover effect achieved by reducing opacity, not directly modifying color
72 let hover_alpha = self.hover * 0.2;
73 let color_with_hover = mix(
74 base_color,
75 vec4(1.0, 1.0, 1.0, 1.0),
76 hover_alpha
77 );
78
79 // Pressed effect
80 let final_color = mix(
81 color_with_hover,
82 self.pressed_color,
83 self.pressed
84 );
85
86 // Fill the main body color first
87 sdf.fill_keep(final_color);
88
89 // Border glow effect
90 let border_glow = max(self.hover * 0.5, self.glow);
91 let border_color = mix(
92 self.border_color,
93 vec4(1.0, 1.0, 1.0, 0.8),
94 border_glow
95 );
96 sdf.stroke(border_color, self.border_width);
97
98 return sdf.result
99 }
100 }
101 }
102}
103
104
105// Define component structure
106#[derive(Live,Widget)]
107pub struct MyButton {
108 // Inherit all Button functionality
109 #[deref]
110 button: Button,
111 #[rust]
112 initialized: bool, // Mark whether initialized
113}
114
115impl LiveHook for MyButton {
116 fn after_new_from_doc(&mut self, cx: &mut Cx) {
117 log!("MyButton: after_new_from_doc");
118 self.initialized = true; // Mark as initialized after creation
119 self.button.after_new_from_doc(cx);
120 log!("button text is empty? {:?}", self.button.text.as_ref())
121 }
122
123 fn before_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) {
124 log!("MyButton: before_apply");
125 self.button.before_apply(cx, apply, index, nodes);
126 }
127
128 fn after_apply(&mut self, cx: &mut Cx, apply: &mut Apply, index: usize, nodes: &[LiveNode]) {
129 log!("MyButton: after_apply");
130 self.button.after_apply(cx, apply, index, nodes);
131 }
132}
133
134
135impl Widget for MyButton {
136 fn handle_event(&mut self, cx: &mut Cx, event: &Event, scope: &mut Scope) {
137 log!("MyButton handle_event");
138 log!("MyButton not initialized!");
139 self.button.handle_event(cx, event, scope);
140 }
141
142 fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
143 log!("MyButton draw_walk");
144 self.initialized = true;
145 log!("MyButton initialized!");
146 self.button.draw_walk(cx, scope, walk)
147 }
148}
149
150impl MyButtonRef {
151 pub fn clicked(&self, actions: &Actions) -> bool {
152 self.borrow().map(|button| button.button.clicked(actions)).unwrap_or(false)
153 }
154
155 pub fn apply_over(&self, cx: &mut Cx, nodes: LiveNodeSlice) {
156 if let Some(mut inner) = self.borrow_mut() {
157 log!("Applying style to MyButton");
158 // Apply style to inner button
159 inner.button.apply_over(cx, nodes);
160 // Ensure redraw
161 inner.button.redraw(cx);
162 } else {
163 log!("Failed to borrow MyButton - this may indicate an initialization problem");
164 }
165 }
166
167 pub fn set_text_and_redraw(&self, cx: &mut Cx, text: &str) {
168 if let Some(mut inner) = self.borrow_mut() {
169 inner.button.set_text_and_redraw(cx, text);
170 inner.button.redraw(cx);
171 }
172 }
173
174 // Add check method
175 pub fn is_some(&self) -> bool {
176 self.borrow().is_some()
177 }
178}