Skip to main content

azul_layout/widgets/
progressbar.rs

1use azul_core::{
2    callbacks::{CoreCallbackData, Update},
3    dom::{Dom, IdOrClass, IdOrClass::Class, IdOrClassVec},
4};
5use azul_css::{
6    dynamic_selector::{CssPropertyWithConditions, CssPropertyWithConditionsVec},
7    props::{
8        basic::*,
9        layout::*,
10        property::{CssProperty, *},
11        style::*,
12    },
13    *,
14};
15
16use crate::callbacks::Callback;
17
18const STYLE_BACKGROUND_CONTENT_2688422633177340412_ITEMS: &[StyleBackgroundContent] =
19    &[StyleBackgroundContent::LinearGradient(LinearGradient {
20        direction: Direction::FromTo(DirectionCorners {
21            dir_from: DirectionCorner::Top,
22            dir_to: DirectionCorner::Bottom,
23        }),
24        extend_mode: ExtendMode::Clamp,
25        stops: NormalizedLinearColorStopVec::from_const_slice(
26            LINEAR_COLOR_STOP_12009347504665939_ITEMS,
27        ),
28    })];
29const STYLE_BACKGROUND_CONTENT_11062356617965867290_ITEMS: &[StyleBackgroundContent] =
30    &[StyleBackgroundContent::Color(ColorU {
31        r: 240,
32        g: 240,
33        b: 240,
34        a: 255,
35    })];
36const STYLE_BACKGROUND_CONTENT_14586281004485141058_ITEMS: &[StyleBackgroundContent] =
37    &[StyleBackgroundContent::LinearGradient(LinearGradient {
38        direction: Direction::FromTo(DirectionCorners {
39            dir_from: DirectionCorner::Top,
40            dir_to: DirectionCorner::Bottom,
41        }),
42        extend_mode: ExtendMode::Clamp,
43        stops: NormalizedLinearColorStopVec::from_const_slice(
44            LINEAR_COLOR_STOP_3104396762583413726_ITEMS,
45        ),
46    })];
47const LINEAR_COLOR_STOP_12009347504665939_ITEMS: &[NormalizedLinearColorStop] = &[
48    NormalizedLinearColorStop {
49        offset: PercentageValue::const_new(0),
50        color: ColorU {
51            r: 193,
52            g: 255,
53            b: 187,
54            a: 255,
55        },
56    },
57    NormalizedLinearColorStop {
58        offset: PercentageValue::const_new(10),
59        color: ColorU {
60            r: 205,
61            g: 255,
62            b: 205,
63            a: 255,
64        },
65    },
66    NormalizedLinearColorStop {
67        offset: PercentageValue::const_new(15),
68        color: ColorU {
69            r: 156,
70            g: 238,
71            b: 172,
72            a: 255,
73        },
74    },
75    NormalizedLinearColorStop {
76        offset: PercentageValue::const_new(20),
77        color: ColorU {
78            r: 0,
79            g: 211,
80            b: 40,
81            a: 255,
82        },
83    },
84    NormalizedLinearColorStop {
85        offset: PercentageValue::const_new(30),
86        color: ColorU {
87            r: 0,
88            g: 211,
89            b: 40,
90            a: 255,
91        },
92    },
93    NormalizedLinearColorStop {
94        offset: PercentageValue::const_new(70),
95        color: ColorU {
96            r: 32,
97            g: 219,
98            b: 65,
99            a: 255,
100        },
101    },
102    NormalizedLinearColorStop {
103        offset: PercentageValue::const_new(100),
104        color: ColorU {
105            r: 32,
106            g: 219,
107            b: 65,
108            a: 255,
109        },
110    },
111];
112const LINEAR_COLOR_STOP_3104396762583413726_ITEMS: &[NormalizedLinearColorStop] = &[
113    NormalizedLinearColorStop {
114        offset: PercentageValue::const_new(0),
115        color: ColorU {
116            r: 243,
117            g: 243,
118            b: 243,
119            a: 255,
120        },
121    },
122    NormalizedLinearColorStop {
123        offset: PercentageValue::const_new(10),
124        color: ColorU {
125            r: 252,
126            g: 252,
127            b: 252,
128            a: 255,
129        },
130    },
131    NormalizedLinearColorStop {
132        offset: PercentageValue::const_new(15),
133        color: ColorU {
134            r: 218,
135            g: 218,
136            b: 218,
137            a: 255,
138        },
139    },
140    NormalizedLinearColorStop {
141        offset: PercentageValue::const_new(20),
142        color: ColorU {
143            r: 201,
144            g: 201,
145            b: 201,
146            a: 255,
147        },
148    },
149    NormalizedLinearColorStop {
150        offset: PercentageValue::const_new(30),
151        color: ColorU {
152            r: 218,
153            g: 218,
154            b: 218,
155            a: 255,
156        },
157    },
158    NormalizedLinearColorStop {
159        offset: PercentageValue::const_new(70),
160        color: ColorU {
161            r: 203,
162            g: 203,
163            b: 203,
164            a: 255,
165        },
166    },
167    NormalizedLinearColorStop {
168        offset: PercentageValue::const_new(100),
169        color: ColorU {
170            r: 203,
171            g: 203,
172            b: 203,
173            a: 255,
174        },
175    },
176];
177
178#[derive(Debug, Clone)]
179#[repr(C)]
180pub struct ProgressBar {
181    pub progressbar_state: ProgressBarState,
182    pub height: PixelValue,
183    pub bar_background: StyleBackgroundContentVec,
184    pub container_background: StyleBackgroundContentVec,
185}
186
187#[derive(Debug, Clone)]
188#[repr(C)]
189pub struct ProgressBarState {
190    pub percent_done: f32,
191    pub display_percentage: bool,
192}
193
194impl ProgressBar {
195    #[inline]
196    pub fn create(percent_done: f32) -> Self {
197        Self {
198            progressbar_state: ProgressBarState {
199                percent_done,
200                display_percentage: false,
201            },
202            height: PixelValue::const_px(15),
203            bar_background: StyleBackgroundContentVec::from_const_slice(
204                STYLE_BACKGROUND_CONTENT_2688422633177340412_ITEMS,
205            ),
206            container_background: StyleBackgroundContentVec::from_const_slice(
207                STYLE_BACKGROUND_CONTENT_14586281004485141058_ITEMS,
208            ),
209        }
210    }
211
212    #[inline]
213    pub fn swap_with_default(&mut self) -> Self {
214        let mut s = Self::create(0.0);
215        core::mem::swap(&mut s, self);
216        s
217    }
218
219    pub fn set_container_background(&mut self, background: StyleBackgroundContentVec) {
220        self.container_background = background;
221    }
222
223    pub fn with_container_background(mut self, background: StyleBackgroundContentVec) -> Self {
224        self.set_container_background(background);
225        self
226    }
227
228    pub fn set_bar_background(&mut self, background: StyleBackgroundContentVec) {
229        self.bar_background = background;
230    }
231
232    pub fn with_bar_background(mut self, background: StyleBackgroundContentVec) -> Self {
233        self.set_bar_background(background);
234        self
235    }
236
237    pub fn set_height(&mut self, height: PixelValue) {
238        self.height = height;
239    }
240
241    pub fn with_height(mut self, height: PixelValue) -> Self {
242        self.set_height(height);
243        self
244    }
245
246    pub fn dom(self) -> Dom {
247        use azul_core::dom::DomVec;
248
249        // Use percentage widths for the progress bar and remaining space.
250        // The container uses flex-direction: row, and we set explicit widths
251        // on the children using CSS percentages.
252        let percent_done = self.progressbar_state.percent_done.max(0.0).min(100.0);
253
254        Dom::create_div()
255            .with_css_props(CssPropertyWithConditionsVec::from_vec(vec![
256                // .__azul-native-progress-bar-container
257                CssPropertyWithConditions::simple(CssProperty::Height(LayoutHeightValue::Exact(
258                    LayoutHeight::Px(self.height.clone()),
259                ))),
260                CssPropertyWithConditions::simple(CssProperty::FlexDirection(
261                    LayoutFlexDirectionValue::Exact(LayoutFlexDirection::Row),
262                )),
263                CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(
264                    StyleBoxShadowValue::Exact(StyleBoxShadow {
265                        offset_x: PixelValueNoPercent {
266                            inner: PixelValue::const_px(0),
267                        },
268                        offset_y: PixelValueNoPercent {
269                            inner: PixelValue::const_px(0),
270                        },
271                        color: ColorU {
272                            r: 0,
273                            g: 0,
274                            b: 0,
275                            a: 9,
276                        },
277                        blur_radius: PixelValueNoPercent {
278                            inner: PixelValue::const_px(15),
279                        },
280                        spread_radius: PixelValueNoPercent {
281                            inner: PixelValue::const_px(2),
282                        },
283                        clip_mode: BoxShadowClipMode::Inset,
284                    }),
285                )),
286                CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(
287                    StyleBoxShadowValue::Exact(StyleBoxShadow {
288                        offset_x: PixelValueNoPercent {
289                            inner: PixelValue::const_px(0),
290                        },
291                        offset_y: PixelValueNoPercent {
292                            inner: PixelValue::const_px(0),
293                        },
294                        color: ColorU {
295                            r: 0,
296                            g: 0,
297                            b: 0,
298                            a: 9,
299                        },
300                        blur_radius: PixelValueNoPercent {
301                            inner: PixelValue::const_px(15),
302                        },
303                        spread_radius: PixelValueNoPercent {
304                            inner: PixelValue::const_px(2),
305                        },
306                        clip_mode: BoxShadowClipMode::Inset,
307                    }),
308                )),
309                CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(
310                    StyleBoxShadowValue::Exact(StyleBoxShadow {
311                        offset_x: PixelValueNoPercent {
312                            inner: PixelValue::const_px(0),
313                        },
314                        offset_y: PixelValueNoPercent {
315                            inner: PixelValue::const_px(0),
316                        },
317                        color: ColorU {
318                            r: 0,
319                            g: 0,
320                            b: 0,
321                            a: 9,
322                        },
323                        blur_radius: PixelValueNoPercent {
324                            inner: PixelValue::const_px(15),
325                        },
326                        spread_radius: PixelValueNoPercent {
327                            inner: PixelValue::const_px(2),
328                        },
329                        clip_mode: BoxShadowClipMode::Inset,
330                    }),
331                )),
332                CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(
333                    StyleBoxShadowValue::Exact(StyleBoxShadow {
334                        offset_x: PixelValueNoPercent {
335                            inner: PixelValue::const_px(0),
336                        },
337                        offset_y: PixelValueNoPercent {
338                            inner: PixelValue::const_px(0),
339                        },
340                        color: ColorU {
341                            r: 0,
342                            g: 0,
343                            b: 0,
344                            a: 9,
345                        },
346                        blur_radius: PixelValueNoPercent {
347                            inner: PixelValue::const_px(15),
348                        },
349                        spread_radius: PixelValueNoPercent {
350                            inner: PixelValue::const_px(2),
351                        },
352                        clip_mode: BoxShadowClipMode::Inset,
353                    }),
354                )),
355                CssPropertyWithConditions::simple(CssProperty::BorderBottomRightRadius(
356                    StyleBorderBottomRightRadiusValue::Exact(StyleBorderBottomRightRadius {
357                        inner: PixelValue::const_px(3),
358                    }),
359                )),
360                CssPropertyWithConditions::simple(CssProperty::BorderBottomLeftRadius(
361                    StyleBorderBottomLeftRadiusValue::Exact(StyleBorderBottomLeftRadius {
362                        inner: PixelValue::const_px(3),
363                    }),
364                )),
365                CssPropertyWithConditions::simple(CssProperty::BorderTopRightRadius(
366                    StyleBorderTopRightRadiusValue::Exact(StyleBorderTopRightRadius {
367                        inner: PixelValue::const_px(3),
368                    }),
369                )),
370                CssPropertyWithConditions::simple(CssProperty::BorderTopLeftRadius(
371                    StyleBorderTopLeftRadiusValue::Exact(StyleBorderTopLeftRadius {
372                        inner: PixelValue::const_px(3),
373                    }),
374                )),
375                CssPropertyWithConditions::simple(CssProperty::BorderBottomWidth(
376                    LayoutBorderBottomWidthValue::Exact(LayoutBorderBottomWidth {
377                        inner: PixelValue::const_px(1),
378                    }),
379                )),
380                CssPropertyWithConditions::simple(CssProperty::BorderLeftWidth(
381                    LayoutBorderLeftWidthValue::Exact(LayoutBorderLeftWidth {
382                        inner: PixelValue::const_px(1),
383                    }),
384                )),
385                CssPropertyWithConditions::simple(CssProperty::BorderRightWidth(
386                    LayoutBorderRightWidthValue::Exact(LayoutBorderRightWidth {
387                        inner: PixelValue::const_px(1),
388                    }),
389                )),
390                CssPropertyWithConditions::simple(CssProperty::BorderTopWidth(
391                    LayoutBorderTopWidthValue::Exact(LayoutBorderTopWidth {
392                        inner: PixelValue::const_px(1),
393                    }),
394                )),
395                CssPropertyWithConditions::simple(CssProperty::BorderBottomStyle(
396                    StyleBorderBottomStyleValue::Exact(StyleBorderBottomStyle {
397                        inner: BorderStyle::Solid,
398                    }),
399                )),
400                CssPropertyWithConditions::simple(CssProperty::BorderLeftStyle(
401                    StyleBorderLeftStyleValue::Exact(StyleBorderLeftStyle {
402                        inner: BorderStyle::Solid,
403                    }),
404                )),
405                CssPropertyWithConditions::simple(CssProperty::BorderRightStyle(
406                    StyleBorderRightStyleValue::Exact(StyleBorderRightStyle {
407                        inner: BorderStyle::Solid,
408                    }),
409                )),
410                CssPropertyWithConditions::simple(CssProperty::BorderTopStyle(
411                    StyleBorderTopStyleValue::Exact(StyleBorderTopStyle {
412                        inner: BorderStyle::Solid,
413                    }),
414                )),
415                CssPropertyWithConditions::simple(CssProperty::BorderBottomColor(
416                    StyleBorderBottomColorValue::Exact(StyleBorderBottomColor {
417                        inner: ColorU {
418                            r: 178,
419                            g: 178,
420                            b: 178,
421                            a: 255,
422                        },
423                    }),
424                )),
425                CssPropertyWithConditions::simple(CssProperty::BorderLeftColor(
426                    StyleBorderLeftColorValue::Exact(StyleBorderLeftColor {
427                        inner: ColorU {
428                            r: 178,
429                            g: 178,
430                            b: 178,
431                            a: 255,
432                        },
433                    }),
434                )),
435                CssPropertyWithConditions::simple(CssProperty::BorderRightColor(
436                    StyleBorderRightColorValue::Exact(StyleBorderRightColor {
437                        inner: ColorU {
438                            r: 178,
439                            g: 178,
440                            b: 178,
441                            a: 255,
442                        },
443                    }),
444                )),
445                CssPropertyWithConditions::simple(CssProperty::BorderTopColor(
446                    StyleBorderTopColorValue::Exact(StyleBorderTopColor {
447                        inner: ColorU {
448                            r: 178,
449                            g: 178,
450                            b: 178,
451                            a: 255,
452                        },
453                    }),
454                )),
455                CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
456                    StyleBackgroundContentVecValue::Exact(self.container_background.clone()),
457                )),
458            ]))
459            .with_ids_and_classes({
460                const IDS_AND_CLASSES_10874511710181900075: &[IdOrClass] = &[Class(
461                    AzString::from_const_str("__azul-native-progress-bar-container"),
462                )];
463                IdOrClassVec::from_const_slice(IDS_AND_CLASSES_10874511710181900075)
464            })
465            .with_children(DomVec::from_vec(vec![
466                Dom::create_div()
467                    .with_css_props(CssPropertyWithConditionsVec::from_vec(vec![
468                        // .__azul-native-progress-bar-bar
469                        // Use percentage width instead of flex-grow hack
470                        CssPropertyWithConditions::simple(CssProperty::Width(
471                            LayoutWidthValue::Exact(LayoutWidth::Px(
472                                PixelValue::percent(percent_done),
473                            )),
474                        )),
475                        CssPropertyWithConditions::simple(CssProperty::BoxShadowBottom(
476                            StyleBoxShadowValue::Exact(StyleBoxShadow {
477                                offset_x: PixelValueNoPercent {
478                                    inner: PixelValue::const_px(0),
479                                },
480                                offset_y: PixelValueNoPercent {
481                                    inner: PixelValue::const_px(0),
482                                },
483                                color: ColorU {
484                                    r: 0,
485                                    g: 51,
486                                    b: 0,
487                                    a: 51,
488                                },
489                                blur_radius: PixelValueNoPercent {
490                                    inner: PixelValue::const_px(15),
491                                },
492                                spread_radius: PixelValueNoPercent {
493                                    inner: PixelValue::const_px(12),
494                                },
495                                clip_mode: BoxShadowClipMode::Inset,
496                            }),
497                        )),
498                        CssPropertyWithConditions::simple(CssProperty::BoxShadowTop(
499                            StyleBoxShadowValue::Exact(StyleBoxShadow {
500                                offset_x: PixelValueNoPercent {
501                                    inner: PixelValue::const_px(0),
502                                },
503                                offset_y: PixelValueNoPercent {
504                                    inner: PixelValue::const_px(0),
505                                },
506                                color: ColorU {
507                                    r: 0,
508                                    g: 51,
509                                    b: 0,
510                                    a: 51,
511                                },
512                                blur_radius: PixelValueNoPercent {
513                                    inner: PixelValue::const_px(15),
514                                },
515                                spread_radius: PixelValueNoPercent {
516                                    inner: PixelValue::const_px(12),
517                                },
518                                clip_mode: BoxShadowClipMode::Inset,
519                            }),
520                        )),
521                        CssPropertyWithConditions::simple(CssProperty::BoxShadowRight(
522                            StyleBoxShadowValue::Exact(StyleBoxShadow {
523                                offset_x: PixelValueNoPercent {
524                                    inner: PixelValue::const_px(0),
525                                },
526                                offset_y: PixelValueNoPercent {
527                                    inner: PixelValue::const_px(0),
528                                },
529                                color: ColorU {
530                                    r: 0,
531                                    g: 51,
532                                    b: 0,
533                                    a: 51,
534                                },
535                                blur_radius: PixelValueNoPercent {
536                                    inner: PixelValue::const_px(15),
537                                },
538                                spread_radius: PixelValueNoPercent {
539                                    inner: PixelValue::const_px(12),
540                                },
541                                clip_mode: BoxShadowClipMode::Inset,
542                            }),
543                        )),
544                        CssPropertyWithConditions::simple(CssProperty::BoxShadowLeft(
545                            StyleBoxShadowValue::Exact(StyleBoxShadow {
546                                offset_x: PixelValueNoPercent {
547                                    inner: PixelValue::const_px(0),
548                                },
549                                offset_y: PixelValueNoPercent {
550                                    inner: PixelValue::const_px(0),
551                                },
552                                color: ColorU {
553                                    r: 0,
554                                    g: 51,
555                                    b: 0,
556                                    a: 51,
557                                },
558                                blur_radius: PixelValueNoPercent {
559                                    inner: PixelValue::const_px(15),
560                                },
561                                spread_radius: PixelValueNoPercent {
562                                    inner: PixelValue::const_px(12),
563                                },
564                                clip_mode: BoxShadowClipMode::Inset,
565                            }),
566                        )),
567                        CssPropertyWithConditions::simple(CssProperty::BorderBottomRightRadius(
568                            StyleBorderBottomRightRadiusValue::Exact(
569                                StyleBorderBottomRightRadius {
570                                    inner: PixelValue::const_px(1),
571                                },
572                            ),
573                        )),
574                        CssPropertyWithConditions::simple(CssProperty::BorderBottomLeftRadius(
575                            StyleBorderBottomLeftRadiusValue::Exact(StyleBorderBottomLeftRadius {
576                                inner: PixelValue::const_px(1),
577                            }),
578                        )),
579                        CssPropertyWithConditions::simple(CssProperty::BorderTopRightRadius(
580                            StyleBorderTopRightRadiusValue::Exact(StyleBorderTopRightRadius {
581                                inner: PixelValue::const_px(1),
582                            }),
583                        )),
584                        CssPropertyWithConditions::simple(CssProperty::BorderTopLeftRadius(
585                            StyleBorderTopLeftRadiusValue::Exact(StyleBorderTopLeftRadius {
586                                inner: PixelValue::const_px(1),
587                            }),
588                        )),
589                        CssPropertyWithConditions::simple(CssProperty::BackgroundContent(
590                            StyleBackgroundContentVecValue::Exact(self.bar_background.clone()),
591                        )),
592                    ]))
593                    .with_ids_and_classes({
594                        const IDS_AND_CLASSES_16512648314570682783: &[IdOrClass] = &[Class(
595                            AzString::from_const_str("__azul-native-progress-bar-bar"),
596                        )];
597                        IdOrClassVec::from_const_slice(IDS_AND_CLASSES_16512648314570682783)
598                    }),
599                Dom::create_div()
600                    .with_css_props(CssPropertyWithConditionsVec::from_vec(vec![
601                        // .__azul-native-progress-bar-remaining
602                        // Use percentage width for the remaining space
603                        CssPropertyWithConditions::simple(CssProperty::Width(
604                            LayoutWidthValue::Exact(LayoutWidth::Px(
605                                PixelValue::percent(100.0 - percent_done),
606                            )),
607                        )),
608                    ]))
609                    .with_ids_and_classes({
610                        const IDS_AND_CLASSES_2492405364126620395: &[IdOrClass] = &[Class(
611                            AzString::from_const_str("__azul-native-progress-bar-remaining"),
612                        )];
613                        IdOrClassVec::from_const_slice(IDS_AND_CLASSES_2492405364126620395)
614                    }),
615            ]))
616    }
617}