1use crate::{
2 makepad_derive_widget::*,
3 widget::*,
4 makepad_draw::*,
5 button::Button,
6};
7
8live_design!{
9 link widgets;
10
11 use link::theme::*;
12 use makepad_draw::shader::std::*;
13 use crate::button::ButtonBase
14
15 pub LinkLabelBase = {{LinkLabel}}<ButtonBase> {}
16 pub LinkLabel = <LinkLabelBase> {
17 width: Fit, height: Fit,
18 margin: <THEME_MSPACE_V_2> {}
19 padding: 0.,
20
21 label_walk: { width: Fit, height: Fit },
22
23 draw_icon: {
24 instance hover: 0.0
25 instance down: 0.0
26 instance focus: 0.0
27 instance disabled: 0.0
28
29 uniform color: (THEME_COLOR_LABEL_INNER)
30 uniform color_hover: (THEME_COLOR_LABEL_INNER_HOVER)
31 uniform color_down: (THEME_COLOR_LABEL_INNER_DOWN)
32 uniform color_focus: (THEME_COLOR_LABEL_INNER_FOCUS)
33 uniform color_disabled: (THEME_COLOR_LABEL_INNER_DISABLED)
34
35 fn get_color(self) -> vec4 {
36 return mix(
37 mix(
38 mix(
39 mix(self.color, self.color_focus, self.focus),
40 self.color_hover,
41 self.hover
42 ),
43 self.color_down,
44 self.down
45 ),
46 self.color_disabled,
47 self.disabled
48 )
49 }
50 }
51
52 draw_bg: {
53 instance down: 0.0
54 instance hover: 0.0
55 instance focus: 0.0
56 instance disabled: 0.0
57
58 uniform color: (THEME_COLOR_LABEL_INNER)
59 uniform color_hover: (THEME_COLOR_LABEL_INNER_HOVER)
60 uniform color_down: (THEME_COLOR_LABEL_INNER_DOWN)
61 uniform color_focus: (THEME_COLOR_LABEL_INNER_FOCUS)
62 uniform color_disabled: (THEME_COLOR_LABEL_INNER_DISABLED)
63
64 fn pixel(self) -> vec4 {
65 let sdf = Sdf2d::viewport(self.pos * self.rect_size);
66 let offset_y = 1.0
67 sdf.move_to(0., self.rect_size.y - offset_y);
68 sdf.line_to(self.rect_size.x, self.rect_size.y - offset_y);
69 return sdf.stroke(
70 mix(
71 mix(
72 mix(
73 mix(self.color, self.color_focus, self.focus),
74 self.color_hover,
75 self.hover
76 ),
77 self.color_down,
78 self.down
79 ),
80 self.color_disabled,
81 self.disabled
82 ), mix(.7, 1., self.hover)
83 );
84 }
85 }
86
87 draw_text: {
88 instance down: 0.0
89 instance hover: 0.0
90 instance focus: 0.0,
91 instance disabled: 0.0
92
93 uniform color: (THEME_COLOR_LABEL_INNER),
94 uniform color_hover: (THEME_COLOR_LABEL_INNER_HOVER),
95 uniform color_down: (THEME_COLOR_LABEL_INNER_DOWN),
96 uniform color_focus: (THEME_COLOR_LABEL_INNER_FOCUS)
97 uniform color_disabled: (THEME_COLOR_LABEL_INNER_DISABLED)
98
99 wrap: Word
100 text_style: <THEME_FONT_REGULAR>{
101 font_size: (THEME_FONT_SIZE_P)
102 }
103 fn get_color(self) -> vec4 {
104 return
105 mix(
106 mix(
107 mix(
108 mix(self.color, self.color_focus, self.focus),
109 self.color_hover,
110 self.hover
111 ),
112 self.color_down,
113 self.down
114 ),
115 self.color_disabled,
116 self.disabled
117 )
118 }
119 }
120
121 animator: {
122 disabled = {
123 default: off,
124 off = {
125 from: {all: Forward {duration: 0.}}
126 apply: {
127 draw_bg: {disabled: 0.0}
128 draw_text: {disabled: 0.0}
129 draw_icon: {disabled: 0.0}
130 }
131 }
132 on = {
133 from: {all: Forward {duration: 0.2}}
134 apply: {
135 draw_bg: {disabled: 1.0}
136 draw_text: {disabled: 1.0}
137 draw_icon: {disabled: 1.0}
138 }
139 }
140 }
141 time = {
142 default: off,
143 off = {
144 from: {all: Forward {duration: 0.}}
145 apply: {
146 }
148 }
149 on = {
150 from: {all: Loop {duration: 1.0, end:1000000000.0}}
151 apply: {
152 draw_bg: {anim_time: [{time: 0.0, value: 0.0},{time:1.0, value:1.0}]}
153 }
154 }
155 }
156 hover = {
157 default: off,
158 off = {
159 from: {all: Forward {duration: 0.1}}
160 apply: {
161 draw_bg: {down: 0.0, hover: 0.0}
162 draw_icon: {down: 0.0, hover: 0.0}
163 draw_text: {down: 0.0, hover: 0.0}
164 }
165 }
166
167 on = {
168 from: {
169 all: Forward {duration: 0.1}
170 down: Forward {duration: 0.01}
171 }
172 apply: {
173 draw_bg: {down: 0.0, hover: [{time: 0.0, value: 1.0}],}
174 draw_icon: {down: 0.0, hover: [{time: 0.0, value: 1.0}],}
175 draw_text: {down: 0.0, hover: [{time: 0.0, value: 1.0}],}
176 }
177 }
178
179 down = {
180 from: {all: Forward {duration: 0.2}}
181 apply: {
182 draw_bg: {down: [{time: 0.0, value: 1.0}], hover: 1.0,}
183 draw_icon: {down: [{time: 0.0, value: 1.0}], hover: 1.0,}
184 draw_text: {down: [{time: 0.0, value: 1.0}], hover: 1.0,}
185 }
186 }
187 }
188 focus = {
189 default: off
190 off = {
191 from: {all: Forward {duration: 0.2}}
192 apply: {
193 draw_bg: {focus: 0.0}
194 draw_icon: {focus: 0.0}
195 draw_text: {focus: 0.0}
196 }
197 }
198 on = {
199 cursor: Arrow,
200 from: {all: Forward {duration: 0.0}}
201 apply: {
202 draw_bg: {focus: 1.0}
203 draw_icon: {focus: 1.0}
204 draw_text: {focus: 1.0}
205 }
206 }
207 }
208 }
209
210 }
211
212 pub LinkLabelGradientY = <LinkLabel> {
213 draw_bg: {
214 instance down: 0.0
215 instance hover: 0.0
216 instance focus: 0.0
217 instance disabled: 0.0
218
219 uniform color_1: #0ff,
220 uniform color_1_hover: #0ff,
221 uniform color_1_down: #0ff,
222 uniform color_1_focus: #0ff,
223 uniform color_1_disabled: (THEME_COLOR_TEXT_DISABLED)
224
225 uniform color_2: #A00
226 uniform color_2_hover: #F00
227 uniform color_2_down: #000
228 uniform color_2_focus: #f00
229 uniform color_2_disabled: (THEME_COLOR_TEXT_DISABLED)
230
231 fn pixel(self) -> vec4 {
232 let sdf = Sdf2d::viewport(self.pos * self.rect_size);
233 let offset_y = 1.0
234 sdf.move_to(0., self.rect_size.y - offset_y);
235 sdf.line_to(self.rect_size.x, self.rect_size.y - offset_y);
236 return sdf.stroke(
237 mix(
238 mix(
239 mix(
240 mix(
241 mix(self.color_1, self.color_2, self.pos.y),
242 mix(self.color_1_focus, self.color_2_focus, self.pos.y),
243 self.focus
244 ),
245 mix(self.color_1_hover, self.color_2_hover, self.pos.y),
246 self.hover
247 ),
248 mix(self.color_1_down, self.color_2_down, self.pos.y),
249 self.down
250 ),
251 mix(self.color_1_disabled, self.color_2_disabled, self.pos.y),
252 self.disabled
253 ), mix(.7, 1., self.hover));
254 }
255 }
256
257 draw_text: {
258 instance down: 0.0
259 instance hover: 0.0
260 instance focus: 0.0
261 instance disabled: 0.0
262
263 uniform color_1: #0ff,
264 uniform color_1_hover: #0ff,
265 uniform color_1_down: #0ff,
266 uniform color_1_focus: #f00,
267 uniform color_1_disabled: (THEME_COLOR_TEXT_DISABLED)
268
269 uniform color_2: #A40
270 uniform color_2_hover: #FA0
271 uniform color_2_down: #0A0
272 uniform color_2_focus: #0F0
273 uniform color_2_disabled: (THEME_COLOR_TEXT_DISABLED)
274
275 wrap: Word
276 text_style: <THEME_FONT_REGULAR>{
277 font_size: (THEME_FONT_SIZE_P)
278 }
279 fn get_color(self) -> vec4 {
280 return
281 mix(
282 mix(
283 mix(
284 mix(
285 mix(self.color_1, self.color_2, self.pos.y),
286 mix(self.color_1_focus, self.color_2_focus, self.pos.y),
287 self.focus
288 ),
289 mix(self.color_1_hover, self.color_2_hover, self.pos.y),
290 self.hover
291 ),
292 mix(self.color_1_down, self.color_2_down, self.pos.y),
293 self.down
294 ),
295 mix(self.color_1_disabled, self.color_2_disabled, self.pos.y),
296 self.disabled
297 );
298 }
299 }
300 }
301
302 pub LinkLabelGradientX = <LinkLabelGradientY> {
303 draw_text: {
304 fn get_color(self) -> vec4 {
305 return
306 mix(
307 mix(
308 mix(
309 mix(
310 mix(self.color_1, self.color_2, self.pos.x),
311 mix(self.color_1_focus, self.color_2_focus, self.pos.x),
312 self.focus
313 ),
314 mix(self.color_1_hover, self.color_2_hover, self.pos.x),
315 self.hover
316 ),
317 mix(self.color_1_down, self.color_2_down, self.pos.x),
318 self.down
319 ),
320 mix(self.color_1_disabled, self.color_2_disabled, self.pos.x),
321 self.disabled
322 );
323 }
324 }
325 }
326
327
328 pub LinkLabelIcon = <LinkLabel> {
329 padding: { bottom: 2. }
330 align: {x: 0.0, y: 0.0 }
331 label_walk: { margin: { left: (THEME_SPACE_2) } }
332 }
333
334}
335
336#[derive(Live, LiveHook, Widget)]
340pub struct LinkLabel {
341 #[deref] button: Button,
342 #[live] pub url: String,
343 #[live] pub open_in_place: bool,
344}
345
346impl Widget for LinkLabel {
347 fn handle_event(
348 &mut self,
349 cx: &mut Cx,
350 event: &Event,
351 scope: &mut Scope,
352 ) {
353 let actions = cx.capture_actions(|cx|{
354 self.button.handle_event(cx, event, scope);
355 });
356 if self.url.len()>0 && self.clicked(&actions){
357 cx.open_url(&self.url, if self.open_in_place{OpenUrlInPlace::Yes}else{OpenUrlInPlace::No});
358 }
359 cx.extend_actions(actions);
360 }
361
362 fn draw_walk(&mut self, cx: &mut Cx2d, scope: &mut Scope, walk: Walk) -> DrawStep {
363 self.button.draw_walk(cx, scope, walk)
364 }
365
366 fn text(&self)->String{
367 self.button.text()
368 }
369
370 fn set_text(&mut self, cx:&mut Cx, v:&str){
371 self.button.set_text(cx, v);
372 }
373}
374
375impl LinkLabelRef {
376 pub fn clicked(&self, actions: &Actions) -> bool {
378 self.borrow().map_or(false, |b| b.clicked(actions))
379 }
380
381 pub fn pressed(&self, actions: &Actions) -> bool {
383 self.borrow().map_or(false, |b| b.pressed(actions))
384 }
385
386 pub fn released(&self, actions: &Actions) -> bool {
388 self.borrow().map_or(false, |b| b.released(actions))
389 }
390
391 pub fn clicked_modifiers(&self, actions: &Actions) -> Option<KeyModifiers> {
393 self.borrow().and_then(|b| b.clicked_modifiers(actions))
394 }
395
396 pub fn pressed_modifiers(&self, actions: &Actions) -> Option<KeyModifiers> {
398 self.borrow().and_then(|b| b.pressed_modifiers(actions))
399 }
400
401 pub fn released_modifiers(&self, actions: &Actions) -> Option<KeyModifiers> {
403 self.borrow().and_then(|b| b.released_modifiers(actions))
404 }
405}