1use hashbrown::{HashMap, HashSet};
64use indexmap::IndexMap;
65use log::warn;
66use std::fmt::Debug;
67use std::ops::{Deref, DerefMut, Range};
68use vizia_style::selectors::parser::{AncestorHashes, Selector};
69
70use crate::prelude::*;
71
72pub use vizia_style::{
73 Alignment, Angle, BackgroundImage, BackgroundSize, BorderStyleKeyword, ClipPath, Color,
74 CornerShape, CssRule, CursorIcon, Display, Filter, FontFamily, FontSize, FontSlant,
75 FontVariation, FontWeight, FontWeightKeyword, FontWidth, GenericFontFamily, Gradient,
76 HorizontalPosition, HorizontalPositionKeyword, Length, LengthOrPercentage, LengthValue,
77 LineClamp, LineDirection, LinearGradient, Matrix, Opacity, Overflow, PointerEvents, Position,
78 PositionType, RGBA, Scale, Shadow, TextAlign, TextDecorationLine, TextDecorationStyle,
79 TextOverflow, TextStroke, TextStrokeStyle, Transform, Transition, Translate, VerticalPosition,
80 VerticalPositionKeyword, Visibility,
81};
82
83use vizia_style::{
84 BlendMode, EasingFunction, KeyframeSelector, ParserOptions, Property, Selectors, StyleSheet,
85};
86
87mod rule;
88pub(crate) use rule::Rule;
89
90mod pseudoclass;
91pub(crate) use pseudoclass::*;
92
93mod transform;
94pub(crate) use transform::*;
95
96use crate::animation::{AnimationState, Interpolator, Keyframe, TimingFunction};
97use crate::storage::animatable_set::AnimatableSet;
98use crate::storage::style_set::StyleSet;
99use bitflags::bitflags;
100use vizia_id::IdManager;
101use vizia_storage::SparseSet;
102
103bitflags! {
104 #[derive(Debug, Clone, Copy)]
106 pub(crate) struct Abilities: u8 {
107 const HOVERABLE = 1 << 0;
109 const FOCUSABLE = 1 << 1;
111 const CHECKABLE = 1 << 2;
113 const NAVIGABLE = 1 << 3;
115 const DRAGGABLE = 1 << 4;
117 }
118}
119
120impl Default for Abilities {
121 fn default() -> Abilities {
122 Abilities::HOVERABLE
123 }
124}
125
126bitflags! {
127 pub(crate) struct SystemFlags: u8 {
128 const RELAYOUT = 1;
129 const RESTYLE = 1 << 1;
130 const REFLOW = 1 << 2;
131 const REDRAW = 1 << 3;
132 const RETRANSFORM = 1 << 4;
133 const RECLIP = 1 << 5;
134 }
135}
136
137impl Default for SystemFlags {
138 fn default() -> Self {
139 SystemFlags::all()
140 }
141}
142
143#[derive(Debug, Clone, PartialEq)]
145pub enum ImageOrGradient {
146 Image(String),
148 Gradient(Gradient),
150}
151
152#[derive(Debug, Clone, PartialEq, Eq)]
154pub enum FamilyOwned {
155 Generic(GenericFontFamily),
157 Named(String),
159}
160
161impl AsRef<str> for FamilyOwned {
162 fn as_ref(&self) -> &str {
163 match self {
164 FamilyOwned::Generic(generic) => match generic {
165 GenericFontFamily::Serif => "serif",
166 GenericFontFamily::SansSerif => "sans-serif",
167 GenericFontFamily::Cursive => todo!(),
168 GenericFontFamily::Fantasy => todo!(),
169 GenericFontFamily::Monospace => "Cascadia Mono",
170 },
171 FamilyOwned::Named(family) => family.as_str(),
172 }
173 }
174}
175
176pub(crate) struct Bloom(pub(crate) qfilter::Filter);
177
178impl Default for Bloom {
179 fn default() -> Self {
180 Self(qfilter::Filter::new_resizeable(10000, 10000000, 0.01).unwrap())
181 }
182}
183
184impl Deref for Bloom {
185 type Target = qfilter::Filter;
186
187 fn deref(&self) -> &Self::Target {
188 &self.0
189 }
190}
191
192impl DerefMut for Bloom {
193 fn deref_mut(&mut self) -> &mut Self::Target {
194 &mut self.0
195 }
196}
197
198pub(crate) struct StyleRule {
199 pub(crate) selector: Selector<Selectors>,
200 pub(crate) hashes: AncestorHashes,
202}
203
204impl StyleRule {
205 pub(crate) fn new(selector: Selector<Selectors>) -> Self {
206 let hashes = AncestorHashes::new(&selector, vizia_style::QuirksMode::NoQuirks);
207 Self { selector, hashes }
208 }
209}
210
211#[derive(Default)]
213pub struct Style {
214 pub(crate) rule_manager: IdManager<Rule>,
215
216 pub(crate) animation_manager: IdManager<Animation>,
218 pub(crate) animations: HashMap<String, Animation>,
219 pub(crate) pending_animations: Vec<(Entity, Animation, Duration, Duration)>,
221
222 pub(crate) rules: IndexMap<Rule, StyleRule>,
224
225 pub(crate) default_font: Vec<FamilyOwned>,
226
227 pub(crate) element: SparseSet<u32>,
229 pub(crate) ids: SparseSet<String>,
230 pub(crate) classes: SparseSet<HashSet<String>>,
231 pub(crate) pseudo_classes: SparseSet<PseudoClassFlags>,
232 pub(crate) disabled: StyleSet<bool>,
233 pub(crate) abilities: SparseSet<Abilities>,
234
235 pub(crate) name: StyleSet<String>,
237 pub(crate) role: SparseSet<Role>,
238 pub(crate) live: SparseSet<Live>,
239 pub(crate) labelled_by: SparseSet<Entity>,
240 pub(crate) hidden: SparseSet<bool>,
241 pub(crate) text_value: SparseSet<String>,
242 pub(crate) numeric_value: SparseSet<f64>,
243
244 pub(crate) visibility: StyleSet<Visibility>,
246
247 pub(crate) opacity: AnimatableSet<Opacity>,
249
250 pub(crate) z_index: StyleSet<i32>,
252
253 pub(crate) clip_path: AnimatableSet<ClipPath>,
255
256 pub(crate) overflowx: StyleSet<Overflow>,
258 pub(crate) overflowy: StyleSet<Overflow>,
259
260 pub(crate) backdrop_filter: AnimatableSet<Filter>,
262
263 pub(crate) blend_mode: StyleSet<BlendMode>,
264
265 pub(crate) transform: AnimatableSet<Vec<Transform>>,
267 pub(crate) transform_origin: AnimatableSet<Translate>,
268 pub(crate) translate: AnimatableSet<Translate>,
269 pub(crate) rotate: AnimatableSet<Angle>,
270 pub(crate) scale: AnimatableSet<Scale>,
271
272 pub(crate) border_width: AnimatableSet<LengthOrPercentage>,
274 pub(crate) border_color: AnimatableSet<Color>,
275 pub(crate) border_style: StyleSet<BorderStyleKeyword>,
276
277 pub(crate) corner_top_left_shape: StyleSet<CornerShape>,
279 pub(crate) corner_top_right_shape: StyleSet<CornerShape>,
280 pub(crate) corner_bottom_left_shape: StyleSet<CornerShape>,
281 pub(crate) corner_bottom_right_shape: StyleSet<CornerShape>,
282
283 pub(crate) corner_top_left_radius: AnimatableSet<LengthOrPercentage>,
285 pub(crate) corner_top_right_radius: AnimatableSet<LengthOrPercentage>,
286 pub(crate) corner_bottom_left_radius: AnimatableSet<LengthOrPercentage>,
287 pub(crate) corner_bottom_right_radius: AnimatableSet<LengthOrPercentage>,
288
289 pub(crate) corner_top_left_smoothing: AnimatableSet<f32>,
291 pub(crate) corner_top_right_smoothing: AnimatableSet<f32>,
292 pub(crate) corner_bottom_left_smoothing: AnimatableSet<f32>,
293 pub(crate) corner_bottom_right_smoothing: AnimatableSet<f32>,
294
295 pub(crate) outline_width: AnimatableSet<LengthOrPercentage>,
297 pub(crate) outline_color: AnimatableSet<Color>,
298 pub(crate) outline_offset: AnimatableSet<LengthOrPercentage>,
299
300 pub(crate) background_color: AnimatableSet<Color>,
302 pub(crate) background_image: AnimatableSet<Vec<ImageOrGradient>>,
303 pub(crate) background_size: AnimatableSet<Vec<BackgroundSize>>,
304
305 pub(crate) shadow: AnimatableSet<Vec<Shadow>>,
307
308 pub(crate) text: SparseSet<String>,
310 pub(crate) text_wrap: StyleSet<bool>,
311 pub(crate) text_overflow: StyleSet<TextOverflow>,
312 pub(crate) line_clamp: StyleSet<LineClamp>,
313 pub(crate) text_align: StyleSet<TextAlign>,
314 pub(crate) text_decoration_line: StyleSet<TextDecorationLine>,
315 pub(crate) text_stroke_width: StyleSet<Length>,
316 pub(crate) text_stroke_style: StyleSet<TextStrokeStyle>,
317 pub(crate) underline_style: StyleSet<TextDecorationLine>,
318 pub(crate) overline_style: StyleSet<TextDecorationStyle>,
319 pub(crate) strikethrough_style: StyleSet<TextDecorationStyle>,
320 pub(crate) underline_color: AnimatableSet<Color>,
321 pub(crate) overline_color: AnimatableSet<Color>,
322 pub(crate) strikethrough_color: AnimatableSet<Color>,
323 pub(crate) font_family: StyleSet<Vec<FamilyOwned>>,
324 pub(crate) font_color: AnimatableSet<Color>,
325 pub(crate) font_size: AnimatableSet<FontSize>,
326 pub(crate) font_weight: StyleSet<FontWeight>,
327 pub(crate) font_slant: StyleSet<FontSlant>,
328 pub(crate) font_width: StyleSet<FontWidth>,
329 pub(crate) font_variation_settings: StyleSet<Vec<FontVariation>>,
330 pub(crate) caret_color: AnimatableSet<Color>,
331 pub(crate) selection_color: AnimatableSet<Color>,
332
333 pub(crate) fill: AnimatableSet<Color>,
334
335 pub(crate) cursor: StyleSet<CursorIcon>,
337
338 pub(crate) pointer_events: StyleSet<PointerEvents>,
339
340 pub(crate) display: AnimatableSet<Display>,
344
345 pub(crate) layout_type: StyleSet<LayoutType>,
347
348 pub(crate) position_type: StyleSet<PositionType>,
350
351 pub(crate) alignment: StyleSet<Alignment>,
352
353 pub(crate) grid_columns: StyleSet<Vec<Units>>,
355 pub(crate) grid_rows: StyleSet<Vec<Units>>,
356
357 pub(crate) column_start: StyleSet<usize>,
358 pub(crate) column_span: StyleSet<usize>,
359 pub(crate) row_start: StyleSet<usize>,
360 pub(crate) row_span: StyleSet<usize>,
361
362 pub(crate) left: AnimatableSet<Units>,
364 pub(crate) right: AnimatableSet<Units>,
365 pub(crate) top: AnimatableSet<Units>,
366 pub(crate) bottom: AnimatableSet<Units>,
367
368 pub(crate) padding_left: AnimatableSet<Units>,
370 pub(crate) padding_right: AnimatableSet<Units>,
371 pub(crate) padding_top: AnimatableSet<Units>,
372 pub(crate) padding_bottom: AnimatableSet<Units>,
373 pub(crate) vertical_gap: AnimatableSet<Units>,
374 pub(crate) horizontal_gap: AnimatableSet<Units>,
375
376 pub(crate) vertical_scroll: AnimatableSet<f32>,
378 pub(crate) horizontal_scroll: AnimatableSet<f32>,
379
380 pub(crate) width: AnimatableSet<Units>,
382 pub(crate) height: AnimatableSet<Units>,
383
384 pub(crate) min_width: AnimatableSet<Units>,
386 pub(crate) max_width: AnimatableSet<Units>,
387 pub(crate) min_height: AnimatableSet<Units>,
388 pub(crate) max_height: AnimatableSet<Units>,
389
390 pub(crate) min_horizontal_gap: AnimatableSet<Units>,
392 pub(crate) max_horizontal_gap: AnimatableSet<Units>,
393 pub(crate) min_vertical_gap: AnimatableSet<Units>,
394 pub(crate) max_vertical_gap: AnimatableSet<Units>,
395
396 pub(crate) system_flags: SystemFlags,
397
398 pub(crate) restyle: HashSet<Entity>,
399 pub(crate) text_construction: Bloom,
400 pub(crate) text_layout: Bloom,
401 pub(crate) reaccess: Bloom,
402 pub(crate) retransform: Bloom,
403 pub(crate) reclip: Bloom,
404
405 pub(crate) text_range: SparseSet<Range<usize>>,
406 pub(crate) text_span: SparseSet<bool>,
407
408 pub(crate) dpi_factor: f64,
410}
411
412impl Style {
413 pub fn scale_factor(&self) -> f32 {
415 self.dpi_factor as f32
416 }
417
418 pub fn logical_to_physical(&self, logical: f32) -> f32 {
420 (logical * self.dpi_factor as f32).round()
421 }
422
423 pub fn physical_to_logical(&self, physical: f32) -> f32 {
425 physical / self.dpi_factor as f32
426 }
427
428 pub(crate) fn remove_rules(&mut self) {
429 self.rule_manager.reset();
430 self.rules.clear();
431 }
432
433 pub(crate) fn get_animation(&self, name: &str) -> Option<&Animation> {
434 self.animations.get(name)
435 }
436
437 pub(crate) fn add_keyframe(
438 &mut self,
439 animation_id: Animation,
440 time: f32,
441 properties: &[Property],
442 ) {
443 fn insert_keyframe<T: 'static + Interpolator + Debug + Clone + PartialEq + Default>(
444 storage: &mut AnimatableSet<T>,
445 animation_id: Animation,
446 time: f32,
447 value: T,
448 ) {
449 let keyframe = Keyframe { time, value, timing_function: TimingFunction::linear() };
450
451 if let Some(anim_state) = storage.get_animation_mut(animation_id) {
452 anim_state.keyframes.push(keyframe)
453 } else {
454 let anim_state = AnimationState::new(animation_id).with_keyframe(keyframe);
455 storage.insert_animation(animation_id, anim_state);
456 }
457 }
458
459 for property in properties.iter() {
460 match property {
461 Property::Display(value) => {
463 insert_keyframe(&mut self.display, animation_id, time, *value);
464 }
465
466 Property::Opacity(value) => {
467 insert_keyframe(&mut self.opacity, animation_id, time, *value);
468 }
469
470 Property::ClipPath(value) => {
471 insert_keyframe(&mut self.clip_path, animation_id, time, value.clone());
472 }
473
474 Property::Transform(value) => {
476 insert_keyframe(&mut self.transform, animation_id, time, value.clone());
477 }
478
479 Property::TransformOrigin(transform_origin) => {
480 let x = transform_origin.x.to_length_or_percentage();
481 let y = transform_origin.y.to_length_or_percentage();
482 let value = Translate { x, y };
483 insert_keyframe(&mut self.transform_origin, animation_id, time, value);
484 }
485
486 Property::Translate(value) => {
487 insert_keyframe(&mut self.translate, animation_id, time, value.clone());
488 }
489
490 Property::Rotate(value) => {
491 insert_keyframe(&mut self.rotate, animation_id, time, *value);
492 }
493
494 Property::Scale(value) => {
495 insert_keyframe(&mut self.scale, animation_id, time, *value);
496 }
497
498 Property::BorderWidth(value) => {
500 insert_keyframe(
501 &mut self.border_width,
502 animation_id,
503 time,
504 value.left.0.clone(),
505 );
506 }
507
508 Property::BorderColor(value) => {
509 insert_keyframe(&mut self.border_color, animation_id, time, *value);
510 }
511
512 Property::CornerTopLeftRadius(value) => {
513 insert_keyframe(
514 &mut self.corner_top_left_radius,
515 animation_id,
516 time,
517 value.clone(),
518 );
519 }
520
521 Property::CornerTopRightRadius(value) => {
522 insert_keyframe(
523 &mut self.corner_top_right_radius,
524 animation_id,
525 time,
526 value.clone(),
527 );
528 }
529
530 Property::CornerBottomLeftRadius(value) => {
531 insert_keyframe(
532 &mut self.corner_bottom_left_radius,
533 animation_id,
534 time,
535 value.clone(),
536 );
537 }
538
539 Property::CornerBottomRightRadius(value) => {
540 insert_keyframe(
541 &mut self.corner_bottom_right_radius,
542 animation_id,
543 time,
544 value.clone(),
545 );
546 }
547
548 Property::OutlineWidth(value) => {
550 insert_keyframe(
551 &mut self.outline_width,
552 animation_id,
553 time,
554 value.left.0.clone(),
555 );
556 }
557
558 Property::OutlineColor(value) => {
559 insert_keyframe(&mut self.outline_color, animation_id, time, *value);
560 }
561
562 Property::OutlineOffset(value) => {
563 insert_keyframe(&mut self.outline_offset, animation_id, time, value.clone());
564 }
565
566 Property::BackgroundColor(value) => {
568 insert_keyframe(&mut self.background_color, animation_id, time, *value);
569 }
570
571 Property::BackgroundImage(images) => {
572 let images = images
573 .iter()
574 .filter_map(|img| match img {
575 BackgroundImage::None => None,
576 BackgroundImage::Gradient(gradient) => {
577 Some(ImageOrGradient::Gradient(*gradient.clone()))
578 }
579 BackgroundImage::Url(url) => {
580 Some(ImageOrGradient::Image(url.url.to_string()))
581 }
582 })
583 .collect::<Vec<_>>();
584 insert_keyframe(&mut self.background_image, animation_id, time, images);
585 }
586
587 Property::BackgroundSize(value) => {
588 insert_keyframe(&mut self.background_size, animation_id, time, value.clone());
589 }
590
591 Property::Shadow(value) => {
593 insert_keyframe(&mut self.shadow, animation_id, time, value.clone());
594 }
595
596 Property::FontColor(value) => {
598 insert_keyframe(&mut self.font_color, animation_id, time, *value);
599 }
600
601 Property::FontSize(value) => {
602 insert_keyframe(&mut self.font_size, animation_id, time, value.clone());
603 }
604
605 Property::CaretColor(value) => {
606 insert_keyframe(&mut self.caret_color, animation_id, time, *value);
607 }
608
609 Property::SelectionColor(value) => {
610 insert_keyframe(&mut self.selection_color, animation_id, time, *value);
611 }
612
613 Property::Left(value) => {
615 insert_keyframe(&mut self.left, animation_id, time, *value);
616 }
617
618 Property::Right(value) => {
619 insert_keyframe(&mut self.right, animation_id, time, *value);
620 }
621
622 Property::Top(value) => {
623 insert_keyframe(&mut self.top, animation_id, time, *value);
624 }
625
626 Property::Bottom(value) => {
627 insert_keyframe(&mut self.bottom, animation_id, time, *value);
628 }
629
630 Property::PaddingLeft(value) => {
632 insert_keyframe(&mut self.padding_left, animation_id, time, *value);
633 }
634
635 Property::PaddingRight(value) => {
636 insert_keyframe(&mut self.padding_right, animation_id, time, *value);
637 }
638
639 Property::PaddingTop(value) => {
640 insert_keyframe(&mut self.padding_top, animation_id, time, *value);
641 }
642
643 Property::PaddingBottom(value) => {
644 insert_keyframe(&mut self.padding_bottom, animation_id, time, *value);
645 }
646
647 Property::HorizontalGap(value) => {
648 insert_keyframe(&mut self.horizontal_gap, animation_id, time, *value);
649 }
650
651 Property::VerticalGap(value) => {
652 insert_keyframe(&mut self.vertical_gap, animation_id, time, *value);
653 }
654
655 Property::Gap(value) => {
656 insert_keyframe(&mut self.horizontal_gap, animation_id, time, *value);
657 insert_keyframe(&mut self.vertical_gap, animation_id, time, *value);
658 }
659
660 Property::MinGap(value) => {
662 insert_keyframe(&mut self.min_horizontal_gap, animation_id, time, *value);
663 insert_keyframe(&mut self.min_vertical_gap, animation_id, time, *value);
664 }
665
666 Property::MaxGap(value) => {
667 insert_keyframe(&mut self.max_horizontal_gap, animation_id, time, *value);
668 insert_keyframe(&mut self.max_vertical_gap, animation_id, time, *value);
669 }
670
671 Property::MinHorizontalGap(value) => {
672 insert_keyframe(&mut self.min_horizontal_gap, animation_id, time, *value);
673 }
674
675 Property::MaxHorizontalGap(value) => {
676 insert_keyframe(&mut self.max_horizontal_gap, animation_id, time, *value);
677 }
678
679 Property::MinVerticalGap(value) => {
680 insert_keyframe(&mut self.min_vertical_gap, animation_id, time, *value);
681 }
682
683 Property::MaxVerticalGap(value) => {
684 insert_keyframe(&mut self.max_vertical_gap, animation_id, time, *value);
685 }
686
687 Property::Width(value) => {
689 insert_keyframe(&mut self.width, animation_id, time, *value);
690 }
691
692 Property::Height(value) => {
693 insert_keyframe(&mut self.height, animation_id, time, *value);
694 }
695
696 Property::MinWidth(value) => {
698 insert_keyframe(&mut self.min_width, animation_id, time, *value);
699 }
700
701 Property::MaxWidth(value) => {
702 insert_keyframe(&mut self.max_width, animation_id, time, *value);
703 }
704
705 Property::MinHeight(value) => {
706 insert_keyframe(&mut self.min_height, animation_id, time, *value);
707 }
708
709 Property::MaxHeight(value) => {
710 insert_keyframe(&mut self.max_height, animation_id, time, *value);
711 }
712
713 Property::UnderlineColor(value) => {
714 insert_keyframe(&mut self.underline_color, animation_id, time, *value);
715 }
716
717 Property::Fill(value) => {
718 insert_keyframe(&mut self.fill, animation_id, time, *value);
719 }
720
721 _ => {}
722 }
723 }
724 }
725
726 pub(crate) fn add_animation(&mut self, animation: AnimationBuilder) -> Animation {
727 let animation_id = self.animation_manager.create();
728 for keyframe in animation.keyframes.iter() {
729 self.add_keyframe(animation_id, keyframe.time, &keyframe.properties);
730 }
731
732 animation_id
733 }
734
735 pub(crate) fn enqueue_animation(
736 &mut self,
737 entity: Entity,
738 animation: Animation,
739 duration: Duration,
740 delay: Duration,
741 ) {
742 self.pending_animations.push((entity, animation, duration, delay));
743 }
744
745 pub(crate) fn play_pending_animations(&mut self) {
746 let start_time = Instant::now();
747
748 let pending_animations = self.pending_animations.drain(..).collect::<Vec<_>>();
749
750 for (entity, animation, duration, delay) in pending_animations {
751 self.play_animation(entity, animation, start_time + delay, duration, delay)
752 }
753 }
754
755 pub(crate) fn play_animation(
756 &mut self,
757 entity: Entity,
758 animation: Animation,
759 start_time: Instant,
760 duration: Duration,
761 delay: Duration,
762 ) {
763 self.display.play_animation(entity, animation, start_time, duration, delay);
764 self.opacity.play_animation(entity, animation, start_time, duration, delay);
765 self.clip_path.play_animation(entity, animation, start_time, duration, delay);
766
767 self.transform.play_animation(entity, animation, start_time, duration, delay);
768 self.transform_origin.play_animation(entity, animation, start_time, duration, delay);
769 self.translate.play_animation(entity, animation, start_time, duration, delay);
770 self.rotate.play_animation(entity, animation, start_time, duration, delay);
771 self.scale.play_animation(entity, animation, start_time, duration, delay);
772
773 self.border_width.play_animation(entity, animation, start_time, duration, delay);
774 self.border_color.play_animation(entity, animation, start_time, duration, delay);
775
776 self.corner_top_left_radius.play_animation(entity, animation, start_time, duration, delay);
777 self.corner_top_right_radius.play_animation(entity, animation, start_time, duration, delay);
778 self.corner_bottom_left_radius
779 .play_animation(entity, animation, start_time, duration, delay);
780 self.corner_bottom_right_radius
781 .play_animation(entity, animation, start_time, duration, delay);
782
783 self.outline_width.play_animation(entity, animation, start_time, duration, delay);
784 self.outline_color.play_animation(entity, animation, start_time, duration, delay);
785 self.outline_offset.play_animation(entity, animation, start_time, duration, delay);
786
787 self.background_color.play_animation(entity, animation, start_time, duration, delay);
788 self.background_image.play_animation(entity, animation, start_time, duration, delay);
789 self.background_size.play_animation(entity, animation, start_time, duration, delay);
790
791 self.shadow.play_animation(entity, animation, start_time, duration, delay);
792
793 self.font_color.play_animation(entity, animation, start_time, duration, delay);
794 self.font_size.play_animation(entity, animation, start_time, duration, delay);
795 self.caret_color.play_animation(entity, animation, start_time, duration, delay);
796 self.selection_color.play_animation(entity, animation, start_time, duration, delay);
797
798 self.left.play_animation(entity, animation, start_time, duration, delay);
799 self.right.play_animation(entity, animation, start_time, duration, delay);
800 self.top.play_animation(entity, animation, start_time, duration, delay);
801 self.bottom.play_animation(entity, animation, start_time, duration, delay);
802
803 self.padding_left.play_animation(entity, animation, start_time, duration, delay);
804 self.padding_right.play_animation(entity, animation, start_time, duration, delay);
805 self.padding_top.play_animation(entity, animation, start_time, duration, delay);
806 self.padding_bottom.play_animation(entity, animation, start_time, duration, delay);
807 self.horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
808 self.vertical_gap.play_animation(entity, animation, start_time, duration, delay);
809
810 self.width.play_animation(entity, animation, start_time, duration, delay);
811 self.height.play_animation(entity, animation, start_time, duration, delay);
812
813 self.min_width.play_animation(entity, animation, start_time, duration, delay);
814 self.max_width.play_animation(entity, animation, start_time, duration, delay);
815 self.min_height.play_animation(entity, animation, start_time, duration, delay);
816 self.max_height.play_animation(entity, animation, start_time, duration, delay);
817
818 self.min_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
819 self.max_horizontal_gap.play_animation(entity, animation, start_time, duration, delay);
820 self.min_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
821 self.max_vertical_gap.play_animation(entity, animation, start_time, duration, delay);
822
823 self.underline_color.play_animation(entity, animation, start_time, duration, delay);
824
825 self.fill.play_animation(entity, animation, start_time, duration, delay);
826 }
827
828 pub(crate) fn is_animating(&self, entity: Entity, animation: Animation) -> bool {
829 self.display.has_active_animation(entity, animation)
830 | self.opacity.has_active_animation(entity, animation)
831 | self.clip_path.has_active_animation(entity, animation)
832 | self.transform.has_active_animation(entity, animation)
833 | self.transform_origin.has_active_animation(entity, animation)
834 | self.translate.has_active_animation(entity, animation)
835 | self.rotate.has_active_animation(entity, animation)
836 | self.scale.has_active_animation(entity, animation)
837 | self.border_width.has_active_animation(entity, animation)
838 | self.border_color.has_active_animation(entity, animation)
839 | self.corner_top_left_radius.has_active_animation(entity, animation)
840 | self.corner_top_right_radius.has_active_animation(entity, animation)
841 | self.corner_bottom_left_radius.has_active_animation(entity, animation)
842 | self.corner_bottom_right_radius.has_active_animation(entity, animation)
843 | self.outline_width.has_active_animation(entity, animation)
844 | self.outline_color.has_active_animation(entity, animation)
845 | self.outline_offset.has_active_animation(entity, animation)
846 | self.background_color.has_active_animation(entity, animation)
847 | self.background_image.has_active_animation(entity, animation)
848 | self.background_size.has_active_animation(entity, animation)
849 | self.shadow.has_active_animation(entity, animation)
850 | self.font_color.has_active_animation(entity, animation)
851 | self.font_size.has_active_animation(entity, animation)
852 | self.caret_color.has_active_animation(entity, animation)
853 | self.selection_color.has_active_animation(entity, animation)
854 | self.left.has_active_animation(entity, animation)
855 | self.right.has_active_animation(entity, animation)
856 | self.top.has_active_animation(entity, animation)
857 | self.bottom.has_active_animation(entity, animation)
858 | self.padding_left.has_active_animation(entity, animation)
859 | self.padding_right.has_active_animation(entity, animation)
860 | self.padding_top.has_active_animation(entity, animation)
861 | self.padding_bottom.has_active_animation(entity, animation)
862 | self.horizontal_gap.has_active_animation(entity, animation)
863 | self.vertical_gap.has_active_animation(entity, animation)
864 | self.width.has_active_animation(entity, animation)
865 | self.height.has_active_animation(entity, animation)
866 | self.min_width.has_active_animation(entity, animation)
867 | self.max_width.has_active_animation(entity, animation)
868 | self.min_height.has_active_animation(entity, animation)
869 | self.max_height.has_active_animation(entity, animation)
870 | self.min_horizontal_gap.has_active_animation(entity, animation)
871 | self.max_horizontal_gap.has_active_animation(entity, animation)
872 | self.min_vertical_gap.has_active_animation(entity, animation)
873 | self.max_vertical_gap.has_active_animation(entity, animation)
874 | self.underline_color.has_active_animation(entity, animation)
875 | self.fill.has_active_animation(entity, animation)
876 }
877
878 pub(crate) fn parse_theme(&mut self, stylesheet: &str) {
879 if let Ok(stylesheet) = StyleSheet::parse(stylesheet, ParserOptions::new()) {
880 let rules = stylesheet.rules.0;
881
882 for rule in rules {
883 match rule {
884 CssRule::Style(style_rule) => {
885 for selector in style_rule.selectors.slice() {
888 let rule_id = self.rule_manager.create();
889
890 for property in style_rule.declarations.declarations.iter() {
891 match property {
892 Property::Transition(transitions) => {
893 for transition in transitions.iter() {
894 self.insert_transition(rule_id, transition);
895 }
896 }
897
898 _ => {
899 self.insert_property(rule_id, property);
900 }
901 }
902 }
903
904 self.rules.insert(rule_id, StyleRule::new(selector.clone()));
905 }
906 }
907
908 CssRule::Keyframes(keyframes_rule) => {
909 let name = keyframes_rule.name.as_string();
910
911 let animation_id = self.animation_manager.create();
912
913 for keyframes in keyframes_rule.keyframes {
914 for selector in keyframes.selectors.iter() {
915 let time = match selector {
916 KeyframeSelector::From => 0.0,
917 KeyframeSelector::To => 1.0,
918 KeyframeSelector::Percentage(percentage) => {
919 percentage.0 / 100.0
920 }
921 };
922
923 self.add_keyframe(
924 animation_id,
925 time,
926 &keyframes.declarations.declarations,
927 );
928 }
929 }
930
931 self.animations.insert(name, animation_id);
932 }
933
934 _ => {}
935 }
936 }
937 } else {
938 println!("Failed to parse stylesheet");
939 }
940 }
941
942 fn insert_transition(&mut self, rule_id: Rule, transition: &Transition) {
943 let animation = self.animation_manager.create();
944 match transition.property.as_ref() {
945 "display" => {
946 self.display.insert_animation(animation, self.add_transition(transition));
947 self.display.insert_transition(rule_id, animation);
948 }
949
950 "opacity" => {
951 self.opacity.insert_animation(animation, self.add_transition(transition));
952 self.opacity.insert_transition(rule_id, animation);
953 }
954
955 "clip-path" => {
956 self.clip_path.insert_animation(animation, self.add_transition(transition));
957 self.clip_path.insert_transition(rule_id, animation);
958 }
959
960 "transform" => {
961 self.transform.insert_animation(animation, self.add_transition(transition));
962 self.transform.insert_transition(rule_id, animation);
963 }
964
965 "transform-origin" => {
966 self.transform_origin.insert_animation(animation, self.add_transition(transition));
967 self.transform_origin.insert_transition(rule_id, animation);
968 }
969
970 "translate" => {
971 self.translate.insert_animation(animation, self.add_transition(transition));
972 self.translate.insert_transition(rule_id, animation);
973 }
974
975 "rotate" => {
976 self.rotate.insert_animation(animation, self.add_transition(transition));
977 self.rotate.insert_transition(rule_id, animation);
978 }
979
980 "scale" => {
981 self.scale.insert_animation(animation, self.add_transition(transition));
982 self.scale.insert_transition(rule_id, animation);
983 }
984
985 "border" => {
986 self.border_width.insert_animation(animation, self.add_transition(transition));
987 self.border_width.insert_transition(rule_id, animation);
988 self.border_color.insert_animation(animation, self.add_transition(transition));
989 self.border_color.insert_transition(rule_id, animation);
990 }
991
992 "border-width" => {
993 self.border_width.insert_animation(animation, self.add_transition(transition));
994 self.border_width.insert_transition(rule_id, animation);
995 }
996
997 "border-color" => {
998 self.border_color.insert_animation(animation, self.add_transition(transition));
999 self.border_color.insert_transition(rule_id, animation);
1000 }
1001
1002 "corner-radius" => {
1003 self.corner_bottom_left_radius
1004 .insert_animation(animation, self.add_transition(transition));
1005 self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1006 self.corner_bottom_right_radius
1007 .insert_animation(animation, self.add_transition(transition));
1008 self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1009 self.corner_top_left_radius
1010 .insert_animation(animation, self.add_transition(transition));
1011 self.corner_top_left_radius.insert_transition(rule_id, animation);
1012 self.corner_top_right_radius
1013 .insert_animation(animation, self.add_transition(transition));
1014 self.corner_top_right_radius.insert_transition(rule_id, animation);
1015 }
1016
1017 "corner-top-left-radius" => {
1018 self.corner_top_left_radius
1019 .insert_animation(animation, self.add_transition(transition));
1020 self.corner_top_left_radius.insert_transition(rule_id, animation);
1021 }
1022
1023 "corner-top-right-radius" => {
1024 self.corner_top_right_radius
1025 .insert_animation(animation, self.add_transition(transition));
1026 self.corner_top_right_radius.insert_transition(rule_id, animation);
1027 }
1028
1029 "corner-bottom-left-radius" => {
1030 self.corner_bottom_left_radius
1031 .insert_animation(animation, self.add_transition(transition));
1032 self.corner_bottom_left_radius.insert_transition(rule_id, animation);
1033 }
1034
1035 "corner-bottom-right-radius" => {
1036 self.corner_bottom_right_radius
1037 .insert_animation(animation, self.add_transition(transition));
1038 self.corner_bottom_right_radius.insert_transition(rule_id, animation);
1039 }
1040
1041 "outline" => {
1042 self.outline_width.insert_animation(animation, self.add_transition(transition));
1043 self.outline_width.insert_transition(rule_id, animation);
1044 self.outline_color.insert_animation(animation, self.add_transition(transition));
1045 self.outline_color.insert_transition(rule_id, animation);
1046 }
1047
1048 "outline-width" => {
1049 self.outline_width.insert_animation(animation, self.add_transition(transition));
1050 self.outline_width.insert_transition(rule_id, animation);
1051 }
1052
1053 "outline-color" => {
1054 self.outline_color.insert_animation(animation, self.add_transition(transition));
1055 self.outline_color.insert_transition(rule_id, animation);
1056 }
1057
1058 "outline-offset" => {
1059 self.outline_offset.insert_animation(animation, self.add_transition(transition));
1060 self.outline_offset.insert_transition(rule_id, animation);
1061 }
1062
1063 "background-color" => {
1064 self.background_color.insert_animation(animation, self.add_transition(transition));
1065 self.background_color.insert_transition(rule_id, animation);
1066 }
1067
1068 "background-image" => {
1069 self.background_image.insert_animation(animation, self.add_transition(transition));
1070 self.background_image.insert_transition(rule_id, animation);
1071 }
1072
1073 "background-size" => {
1074 self.background_size.insert_animation(animation, self.add_transition(transition));
1075 self.background_size.insert_transition(rule_id, animation);
1076 }
1077
1078 "shadow" => {
1079 self.shadow.insert_animation(animation, self.add_transition(transition));
1080 self.shadow.insert_transition(rule_id, animation);
1081 }
1082
1083 "color" => {
1084 self.font_color.insert_animation(animation, self.add_transition(transition));
1085 self.font_color.insert_transition(rule_id, animation);
1086 }
1087
1088 "font-size" => {
1089 self.font_size.insert_animation(animation, self.add_transition(transition));
1090 self.font_size.insert_transition(rule_id, animation);
1091 }
1092
1093 "caret-color" => {
1094 self.caret_color.insert_animation(animation, self.add_transition(transition));
1095 self.caret_color.insert_transition(rule_id, animation);
1096 }
1097
1098 "selection-color" => {
1099 self.selection_color.insert_animation(animation, self.add_transition(transition));
1100 self.selection_color.insert_transition(rule_id, animation);
1101 }
1102
1103 "left" => {
1104 self.left.insert_animation(animation, self.add_transition(transition));
1105 self.left.insert_transition(rule_id, animation);
1106 }
1107
1108 "right" => {
1109 self.right.insert_animation(animation, self.add_transition(transition));
1110 self.right.insert_transition(rule_id, animation);
1111 }
1112
1113 "top" => {
1114 self.top.insert_animation(animation, self.add_transition(transition));
1115 self.top.insert_transition(rule_id, animation);
1116 }
1117
1118 "bottom" => {
1119 self.bottom.insert_animation(animation, self.add_transition(transition));
1120 self.bottom.insert_transition(rule_id, animation);
1121 }
1122
1123 "padding-left" => {
1124 self.padding_left.insert_animation(animation, self.add_transition(transition));
1125 self.padding_left.insert_transition(rule_id, animation);
1126 }
1127
1128 "padding-right" => {
1129 self.padding_right.insert_animation(animation, self.add_transition(transition));
1130 self.padding_right.insert_transition(rule_id, animation);
1131 }
1132
1133 "padding-top" => {
1134 self.padding_top.insert_animation(animation, self.add_transition(transition));
1135 self.padding_top.insert_transition(rule_id, animation);
1136 }
1137
1138 "padding-bottom" => {
1139 self.padding_bottom.insert_animation(animation, self.add_transition(transition));
1140 self.padding_bottom.insert_transition(rule_id, animation);
1141 }
1142
1143 "horizontal-gap" => {
1144 self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1145 self.horizontal_gap.insert_transition(rule_id, animation);
1146 }
1147
1148 "vertical-gap" => {
1149 self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1150 self.vertical_gap.insert_transition(rule_id, animation);
1151 }
1152
1153 "gap" => {
1154 self.horizontal_gap.insert_animation(animation, self.add_transition(transition));
1155 self.horizontal_gap.insert_transition(rule_id, animation);
1156 self.vertical_gap.insert_animation(animation, self.add_transition(transition));
1157 self.vertical_gap.insert_transition(rule_id, animation);
1158 }
1159
1160 "width" => {
1161 self.width.insert_animation(animation, self.add_transition(transition));
1162 self.width.insert_transition(rule_id, animation);
1163 }
1164
1165 "height" => {
1166 self.height.insert_animation(animation, self.add_transition(transition));
1167 self.height.insert_transition(rule_id, animation);
1168 }
1169
1170 "min-width" => {
1171 self.min_width.insert_animation(animation, self.add_transition(transition));
1172 self.min_width.insert_transition(rule_id, animation);
1173 }
1174
1175 "max-width" => {
1176 self.max_width.insert_animation(animation, self.add_transition(transition));
1177 self.max_width.insert_transition(rule_id, animation);
1178 }
1179
1180 "min-height" => {
1181 self.min_height.insert_animation(animation, self.add_transition(transition));
1182 self.min_height.insert_transition(rule_id, animation);
1183 }
1184
1185 "max-height" => {
1186 self.max_height.insert_animation(animation, self.add_transition(transition));
1187 self.max_height.insert_transition(rule_id, animation);
1188 }
1189
1190 "min-horizontal-gap" => {
1191 self.min_horizontal_gap
1192 .insert_animation(animation, self.add_transition(transition));
1193 self.min_horizontal_gap.insert_transition(rule_id, animation);
1194 }
1195
1196 "max-horizontal-gap" => {
1197 self.max_horizontal_gap
1198 .insert_animation(animation, self.add_transition(transition));
1199 self.max_horizontal_gap.insert_transition(rule_id, animation);
1200 }
1201
1202 "min-vertical-gap" => {
1203 self.min_vertical_gap.insert_animation(animation, self.add_transition(transition));
1204 self.min_vertical_gap.insert_transition(rule_id, animation);
1205 }
1206
1207 "max-vertical-gap" => {
1208 self.max_vertical_gap.insert_animation(animation, self.add_transition(transition));
1209 self.max_vertical_gap.insert_transition(rule_id, animation);
1210 }
1211
1212 "underline-color" => {
1213 self.underline_color.insert_animation(animation, self.add_transition(transition));
1214 self.underline_color.insert_transition(rule_id, animation);
1215 }
1216
1217 "fill" => {
1218 self.fill.insert_animation(animation, self.add_transition(transition));
1219 self.fill.insert_transition(rule_id, animation);
1220 }
1221
1222 _ => {}
1223 }
1224 }
1225
1226 fn insert_property(&mut self, rule_id: Rule, property: &Property) {
1227 match property.clone() {
1228 Property::Display(display) => {
1230 self.display.insert_rule(rule_id, display);
1231 }
1232
1233 Property::Visibility(visibility) => {
1235 self.visibility.insert_rule(rule_id, visibility);
1236 }
1237
1238 Property::Opacity(opacity) => {
1240 self.opacity.insert_rule(rule_id, opacity);
1241 }
1242
1243 Property::ClipPath(clip) => {
1245 self.clip_path.insert_rule(rule_id, clip);
1246 }
1247
1248 Property::BackdropFilter(filter) => {
1250 self.backdrop_filter.insert_rule(rule_id, filter);
1251 }
1252
1253 Property::BlendMode(blend_mode) => {
1255 self.blend_mode.insert_rule(rule_id, blend_mode);
1256 }
1257
1258 Property::LayoutType(layout_type) => {
1260 self.layout_type.insert_rule(rule_id, layout_type);
1261 }
1262
1263 Property::PositionType(position) => {
1265 self.position_type.insert_rule(rule_id, position);
1266 }
1267
1268 Property::Alignment(alignment) => {
1269 self.alignment.insert_rule(rule_id, alignment);
1270 }
1271
1272 Property::GridColumns(columns) => {
1274 self.grid_columns.insert_rule(rule_id, columns);
1275 }
1276
1277 Property::GridRows(rows) => {
1278 self.grid_rows.insert_rule(rule_id, rows);
1279 }
1280
1281 Property::ColumnStart(start) => {
1282 self.column_start.insert_rule(rule_id, start);
1283 }
1284
1285 Property::ColumnSpan(span) => {
1286 self.column_span.insert_rule(rule_id, span);
1287 }
1288
1289 Property::RowStart(start) => {
1290 self.row_start.insert_rule(rule_id, start);
1291 }
1292
1293 Property::RowSpan(span) => {
1294 self.row_span.insert_rule(rule_id, span);
1295 }
1296
1297 Property::Space(space) => {
1299 self.left.insert_rule(rule_id, space);
1300 self.right.insert_rule(rule_id, space);
1301 self.top.insert_rule(rule_id, space);
1302 self.bottom.insert_rule(rule_id, space);
1303 }
1304
1305 Property::Left(left) => {
1306 self.left.insert_rule(rule_id, left);
1307 }
1308
1309 Property::Right(right) => {
1310 self.right.insert_rule(rule_id, right);
1311 }
1312
1313 Property::Top(top) => {
1314 self.top.insert_rule(rule_id, top);
1315 }
1316
1317 Property::Bottom(bottom) => {
1318 self.bottom.insert_rule(rule_id, bottom);
1319 }
1320
1321 Property::Size(size) => {
1323 self.width.insert_rule(rule_id, size);
1324 self.height.insert_rule(rule_id, size);
1325 }
1326
1327 Property::Width(width) => {
1328 self.width.insert_rule(rule_id, width);
1329 }
1330
1331 Property::Height(height) => {
1332 self.height.insert_rule(rule_id, height);
1333 }
1334
1335 Property::Padding(padding) => {
1337 self.padding_left.insert_rule(rule_id, padding);
1338 self.padding_right.insert_rule(rule_id, padding);
1339 self.padding_top.insert_rule(rule_id, padding);
1340 self.padding_bottom.insert_rule(rule_id, padding);
1341 }
1342
1343 Property::PaddingLeft(padding_left) => {
1344 self.padding_left.insert_rule(rule_id, padding_left);
1345 }
1346
1347 Property::PaddingRight(padding_right) => {
1348 self.padding_right.insert_rule(rule_id, padding_right);
1349 }
1350
1351 Property::PaddingTop(padding_top) => {
1352 self.padding_top.insert_rule(rule_id, padding_top);
1353 }
1354
1355 Property::PaddingBottom(padding_bottom) => {
1356 self.padding_bottom.insert_rule(rule_id, padding_bottom);
1357 }
1358
1359 Property::VerticalGap(vertical_gap) => {
1360 self.vertical_gap.insert_rule(rule_id, vertical_gap);
1361 }
1362
1363 Property::HorizontalGap(horizontal_gap) => {
1364 self.horizontal_gap.insert_rule(rule_id, horizontal_gap);
1365 }
1366
1367 Property::Gap(gap) => {
1368 self.horizontal_gap.insert_rule(rule_id, gap);
1369 self.vertical_gap.insert_rule(rule_id, gap);
1370 }
1371
1372 Property::MinSize(min_size) => {
1374 self.min_width.insert_rule(rule_id, min_size);
1375 self.min_height.insert_rule(rule_id, min_size);
1376 }
1377
1378 Property::MinWidth(min_width) => {
1379 self.min_width.insert_rule(rule_id, min_width);
1380 }
1381
1382 Property::MinHeight(min_height) => {
1383 self.min_height.insert_rule(rule_id, min_height);
1384 }
1385
1386 Property::MaxSize(max_size) => {
1387 self.max_width.insert_rule(rule_id, max_size);
1388 self.max_height.insert_rule(rule_id, max_size);
1389 }
1390
1391 Property::MaxWidth(max_width) => {
1392 self.max_width.insert_rule(rule_id, max_width);
1393 }
1394
1395 Property::MaxHeight(max_height) => {
1396 self.max_height.insert_rule(rule_id, max_height);
1397 }
1398
1399 Property::MinGap(min_gap) => {
1401 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
1402 self.min_vertical_gap.insert_rule(rule_id, min_gap);
1403 }
1404
1405 Property::MinHorizontalGap(min_gap) => {
1406 self.min_horizontal_gap.insert_rule(rule_id, min_gap);
1407 }
1408
1409 Property::MinVerticalGap(min_gap) => {
1410 self.min_vertical_gap.insert_rule(rule_id, min_gap);
1411 }
1412
1413 Property::MaxGap(max_gap) => {
1414 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
1415 self.max_vertical_gap.insert_rule(rule_id, max_gap);
1416 }
1417
1418 Property::MaxHorizontalGap(max_gap) => {
1419 self.max_horizontal_gap.insert_rule(rule_id, max_gap);
1420 }
1421
1422 Property::MaxVerticalGap(max_gap) => {
1423 self.max_vertical_gap.insert_rule(rule_id, max_gap);
1424 }
1425
1426 Property::BackgroundColor(color) => {
1428 self.background_color.insert_rule(rule_id, color);
1429 }
1430
1431 Property::Border(border) => {
1433 if let Some(border_color) = border.color {
1434 self.border_color.insert_rule(rule_id, border_color);
1435 }
1436
1437 if let Some(border_width) = border.width {
1438 self.border_width.insert_rule(rule_id, border_width.into());
1439 }
1440
1441 if let Some(border_style) = border.style {
1442 self.border_style.insert_rule(rule_id, border_style.top);
1443 }
1444 }
1445
1446 Property::BorderWidth(border_width) => {
1448 self.border_width.insert_rule(rule_id, border_width.top.0);
1449 }
1450
1451 Property::BorderColor(color) => {
1452 self.border_color.insert_rule(rule_id, color);
1453 }
1454
1455 Property::BorderStyle(style) => {
1456 self.border_style.insert_rule(rule_id, style.top);
1457 }
1458
1459 Property::CornerRadius(corner_radius) => {
1461 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius.bottom_left);
1462 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius.bottom_right);
1463 self.corner_top_left_radius.insert_rule(rule_id, corner_radius.top_left);
1464 self.corner_top_right_radius.insert_rule(rule_id, corner_radius.top_right);
1465 }
1466
1467 Property::CornerBottomLeftRadius(corner_radius) => {
1468 self.corner_bottom_left_radius.insert_rule(rule_id, corner_radius);
1469 }
1470
1471 Property::CornerTopLeftRadius(corner_radius) => {
1472 self.corner_top_left_radius.insert_rule(rule_id, corner_radius);
1473 }
1474
1475 Property::CornerBottomRightRadius(corner_radius) => {
1476 self.corner_bottom_right_radius.insert_rule(rule_id, corner_radius);
1477 }
1478
1479 Property::CornerTopRightRadius(corner_radius) => {
1480 self.corner_top_right_radius.insert_rule(rule_id, corner_radius);
1481 }
1482
1483 Property::CornerShape(corner_shape) => {
1485 self.corner_top_left_shape.insert_rule(rule_id, corner_shape.0);
1486 self.corner_top_right_shape.insert_rule(rule_id, corner_shape.1);
1487 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape.2);
1488 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape.3);
1489 }
1490
1491 Property::CornerTopLeftShape(corner_shape) => {
1492 self.corner_top_left_shape.insert_rule(rule_id, corner_shape);
1493 }
1494
1495 Property::CornerTopRightShape(corner_shape) => {
1496 self.corner_top_right_shape.insert_rule(rule_id, corner_shape);
1497 }
1498
1499 Property::CornerBottomLeftShape(corner_shape) => {
1500 self.corner_bottom_left_shape.insert_rule(rule_id, corner_shape);
1501 }
1502
1503 Property::CornerBottomRightShape(corner_shape) => {
1504 self.corner_bottom_right_shape.insert_rule(rule_id, corner_shape);
1505 }
1506
1507 Property::FontFamily(font_family) => {
1509 self.font_family.insert_rule(
1510 rule_id,
1511 font_family
1512 .iter()
1513 .map(|family| match family {
1514 FontFamily::Named(name) => FamilyOwned::Named(name.to_string()),
1515 FontFamily::Generic(generic) => FamilyOwned::Generic(*generic),
1516 })
1517 .collect::<Vec<_>>(),
1518 );
1519 }
1520
1521 Property::FontColor(font_color) => {
1523 self.font_color.insert_rule(rule_id, font_color);
1524 }
1525
1526 Property::FontSize(font_size) => {
1528 self.font_size.insert_rule(rule_id, font_size);
1529 }
1530
1531 Property::FontWeight(font_weight) => {
1533 self.font_weight.insert_rule(rule_id, font_weight);
1534 }
1535
1536 Property::FontSlant(font_slant) => {
1538 self.font_slant.insert_rule(rule_id, font_slant);
1539 }
1540
1541 Property::FontWidth(font_width) => {
1543 self.font_width.insert_rule(rule_id, font_width);
1544 }
1545
1546 Property::FontVariationSettings(font_variation_settings) => {
1548 self.font_variation_settings.insert_rule(rule_id, font_variation_settings);
1549 }
1550
1551 Property::CaretColor(caret_color) => {
1553 self.caret_color.insert_rule(rule_id, caret_color);
1554 }
1555
1556 Property::SelectionColor(selection_color) => {
1558 self.selection_color.insert_rule(rule_id, selection_color);
1559 }
1560
1561 Property::Transform(transforms) => {
1563 self.transform.insert_rule(rule_id, transforms);
1564 }
1565
1566 Property::TransformOrigin(transform_origin) => {
1567 let x = transform_origin.x.to_length_or_percentage();
1568 let y = transform_origin.y.to_length_or_percentage();
1569 self.transform_origin.insert_rule(rule_id, Translate { x, y });
1570 }
1571
1572 Property::Translate(translate) => {
1573 self.translate.insert_rule(rule_id, translate);
1574 }
1575
1576 Property::Rotate(rotate) => {
1577 self.rotate.insert_rule(rule_id, rotate);
1578 }
1579
1580 Property::Scale(scale) => {
1581 self.scale.insert_rule(rule_id, scale);
1582 }
1583
1584 Property::Overflow(overflow) => {
1586 self.overflowx.insert_rule(rule_id, overflow);
1587 self.overflowy.insert_rule(rule_id, overflow);
1588 }
1589
1590 Property::OverflowX(overflow) => {
1591 self.overflowx.insert_rule(rule_id, overflow);
1592 }
1593
1594 Property::OverflowY(overflow) => {
1595 self.overflowy.insert_rule(rule_id, overflow);
1596 }
1597
1598 Property::ZIndex(z_index) => self.z_index.insert_rule(rule_id, z_index),
1600
1601 Property::Outline(outline) => {
1603 if let Some(outline_color) = outline.color {
1604 self.outline_color.insert_rule(rule_id, outline_color);
1605 }
1606
1607 if let Some(outline_width) = outline.width {
1608 self.outline_width.insert_rule(rule_id, outline_width.into());
1609 }
1610 }
1611
1612 Property::OutlineColor(outline_color) => {
1613 self.outline_color.insert_rule(rule_id, outline_color);
1614 }
1615
1616 Property::OutlineWidth(outline_width) => {
1617 self.outline_width.insert_rule(rule_id, outline_width.left.0);
1618 }
1619
1620 Property::OutlineOffset(outline_offset) => {
1621 self.outline_offset.insert_rule(rule_id, outline_offset);
1622 }
1623
1624 Property::BackgroundImage(images) => {
1626 let images = images
1627 .into_iter()
1628 .filter_map(|img| match img {
1629 BackgroundImage::None => None,
1630 BackgroundImage::Gradient(gradient) => {
1631 Some(ImageOrGradient::Gradient(*gradient))
1632 }
1633 BackgroundImage::Url(url) => {
1634 Some(ImageOrGradient::Image(url.url.to_string()))
1635 }
1636 })
1637 .collect::<Vec<_>>();
1638
1639 self.background_image.insert_rule(rule_id, images);
1640 }
1641
1642 Property::BackgroundSize(sizes) => {
1644 self.background_size.insert_rule(rule_id, sizes);
1645 }
1646
1647 Property::TextWrap(text_wrap) => {
1649 self.text_wrap.insert_rule(rule_id, text_wrap);
1650 }
1651
1652 Property::TextAlign(text_align) => {
1654 self.text_align.insert_rule(rule_id, text_align);
1655 }
1656
1657 Property::Shadow(shadows) => {
1659 self.shadow.insert_rule(rule_id, shadows);
1660 }
1661
1662 Property::Cursor(cursor) => {
1664 self.cursor.insert_rule(rule_id, cursor);
1665 }
1666
1667 Property::PointerEvents(pointer_events) => {
1668 self.pointer_events.insert_rule(rule_id, pointer_events);
1669 }
1670
1671 Property::Unparsed(unparsed) => {
1673 warn!("Unparsed: {}", unparsed.name);
1674 }
1675
1676 Property::Custom(custom) => {
1678 warn!("Custom Property: {}", custom.name);
1679 }
1680 Property::TextOverflow(text_overflow) => {
1681 self.text_overflow.insert_rule(rule_id, text_overflow);
1682 }
1683 Property::LineClamp(line_clamp) => {
1684 self.line_clamp.insert_rule(rule_id, line_clamp);
1685 }
1686 Property::TextDecorationLine(line) => {
1687 self.text_decoration_line.insert_rule(rule_id, line);
1688 }
1689 Property::TextStroke(stroke) => {
1690 self.text_stroke_width.insert_rule(rule_id, stroke.width);
1691 self.text_stroke_style.insert_rule(rule_id, stroke.style);
1692 }
1693 Property::TextStrokeWidth(stroke_width) => {
1694 self.text_stroke_width.insert_rule(rule_id, stroke_width);
1695 }
1696 Property::TextStrokeStyle(stroke_style) => {
1697 self.text_stroke_style.insert_rule(rule_id, stroke_style);
1698 }
1699 Property::Fill(fill) => {
1700 self.fill.insert_rule(rule_id, fill);
1701 }
1702 _ => {}
1703 }
1704 }
1705
1706 fn add_transition<T: Default + Interpolator>(
1708 &self,
1709 transition: &Transition,
1710 ) -> AnimationState<T> {
1711 let timing_function = transition
1712 .timing_function
1713 .map(|easing| match easing {
1714 EasingFunction::Linear => TimingFunction::linear(),
1715 EasingFunction::Ease => TimingFunction::ease(),
1716 EasingFunction::EaseIn => TimingFunction::ease_in(),
1717 EasingFunction::EaseOut => TimingFunction::ease_out(),
1718 EasingFunction::EaseInOut => TimingFunction::ease_in_out(),
1719 EasingFunction::CubicBezier(x1, y1, x2, y2) => TimingFunction::new(x1, y1, x2, y2),
1720 })
1721 .unwrap_or_default();
1722
1723 AnimationState::new(Animation::null())
1724 .with_duration(transition.duration)
1725 .with_delay(transition.delay.unwrap_or_default())
1726 .with_keyframe(Keyframe { time: 0.0, value: Default::default(), timing_function })
1727 .with_keyframe(Keyframe { time: 1.0, value: Default::default(), timing_function })
1728 }
1729
1730 pub(crate) fn add(&mut self, entity: Entity) {
1732 self.pseudo_classes.insert(entity, PseudoClassFlags::VALID);
1733 self.classes.insert(entity, HashSet::new());
1734 self.abilities.insert(entity, Abilities::default());
1735 self.system_flags = SystemFlags::RELAYOUT;
1736 self.restyle.insert(entity);
1737 self.reaccess.0.insert(entity).unwrap();
1738 self.retransform.0.insert(entity).unwrap();
1739 self.reclip.0.insert(entity).unwrap();
1740 }
1741
1742 pub(crate) fn remove(&mut self, entity: Entity) {
1744 self.ids.remove(entity);
1745 self.classes.remove(entity);
1746 self.pseudo_classes.remove(entity);
1747 self.disabled.remove(entity);
1748 self.abilities.remove(entity);
1749
1750 self.name.remove(entity);
1751 self.role.remove(entity);
1752 self.live.remove(entity);
1754 self.labelled_by.remove(entity);
1755 self.hidden.remove(entity);
1756 self.text_value.remove(entity);
1757 self.numeric_value.remove(entity);
1758
1759 self.display.remove(entity);
1761 self.visibility.remove(entity);
1763 self.opacity.remove(entity);
1765 self.z_index.remove(entity);
1767 self.clip_path.remove(entity);
1769
1770 self.overflowx.remove(entity);
1771 self.overflowy.remove(entity);
1772
1773 self.backdrop_filter.remove(entity);
1775
1776 self.blend_mode.remove(entity);
1778
1779 self.transform.remove(entity);
1781 self.transform_origin.remove(entity);
1782 self.translate.remove(entity);
1783 self.rotate.remove(entity);
1784 self.scale.remove(entity);
1785
1786 self.border_width.remove(entity);
1788 self.border_color.remove(entity);
1789 self.border_style.remove(entity);
1790
1791 self.corner_bottom_left_shape.remove(entity);
1793 self.corner_bottom_right_shape.remove(entity);
1794 self.corner_top_left_shape.remove(entity);
1795 self.corner_top_right_shape.remove(entity);
1796
1797 self.corner_bottom_left_radius.remove(entity);
1799 self.corner_bottom_right_radius.remove(entity);
1800 self.corner_top_left_radius.remove(entity);
1801 self.corner_top_right_radius.remove(entity);
1802
1803 self.corner_bottom_left_smoothing.remove(entity);
1805 self.corner_bottom_right_smoothing.remove(entity);
1806 self.corner_top_left_smoothing.remove(entity);
1807 self.corner_top_right_smoothing.remove(entity);
1808
1809 self.outline_width.remove(entity);
1811 self.outline_color.remove(entity);
1812 self.outline_offset.remove(entity);
1813
1814 self.background_color.remove(entity);
1816 self.background_image.remove(entity);
1817 self.background_size.remove(entity);
1818
1819 self.shadow.remove(entity);
1821
1822 self.text.remove(entity);
1824 self.text_wrap.remove(entity);
1825 self.text_overflow.remove(entity);
1826 self.line_clamp.remove(entity);
1827 self.text_align.remove(entity);
1828 self.font_family.remove(entity);
1829 self.font_color.remove(entity);
1830 self.font_size.remove(entity);
1831 self.font_weight.remove(entity);
1832 self.font_slant.remove(entity);
1833 self.font_width.remove(entity);
1834 self.font_variation_settings.remove(entity);
1835 self.caret_color.remove(entity);
1836 self.selection_color.remove(entity);
1837 self.text_decoration_line.remove(entity);
1838 self.text_stroke_width.remove(entity);
1839 self.text_stroke_style.remove(entity);
1840
1841 self.cursor.remove(entity);
1843
1844 self.pointer_events.remove(entity);
1845
1846 self.layout_type.remove(entity);
1848
1849 self.position_type.remove(entity);
1851
1852 self.alignment.remove(entity);
1853
1854 self.grid_columns.remove(entity);
1856 self.grid_rows.remove(entity);
1857 self.column_start.remove(entity);
1858 self.column_span.remove(entity);
1859 self.row_start.remove(entity);
1860 self.row_span.remove(entity);
1861
1862 self.left.remove(entity);
1864 self.right.remove(entity);
1865 self.top.remove(entity);
1866 self.bottom.remove(entity);
1867
1868 self.padding_left.remove(entity);
1870 self.padding_right.remove(entity);
1871 self.padding_top.remove(entity);
1872 self.padding_bottom.remove(entity);
1873 self.vertical_gap.remove(entity);
1874 self.horizontal_gap.remove(entity);
1875
1876 self.vertical_scroll.remove(entity);
1878 self.horizontal_scroll.remove(entity);
1879
1880 self.width.remove(entity);
1882 self.height.remove(entity);
1883
1884 self.min_width.remove(entity);
1886 self.max_width.remove(entity);
1887 self.min_height.remove(entity);
1888 self.max_height.remove(entity);
1889
1890 self.min_horizontal_gap.remove(entity);
1891 self.max_horizontal_gap.remove(entity);
1892 self.min_vertical_gap.remove(entity);
1893 self.max_vertical_gap.remove(entity);
1894
1895 self.text_range.remove(entity);
1896 self.text_span.remove(entity);
1897
1898 self.fill.remove(entity);
1899 }
1900
1901 pub(crate) fn needs_restyle(&mut self, entity: Entity) {
1902 if entity == Entity::null() || self.restyle.contains(&entity) {
1903 return;
1904 }
1905 self.restyle.insert(entity);
1906 }
1907
1908 pub(crate) fn needs_relayout(&mut self) {
1909 self.system_flags.set(SystemFlags::RELAYOUT, true);
1910 }
1911
1912 pub(crate) fn needs_access_update(&mut self, entity: Entity) {
1913 self.reaccess.0.insert(entity).unwrap();
1914 }
1915
1916 pub(crate) fn needs_text_update(&mut self, entity: Entity) {
1917 self.text_construction.0.insert(entity).unwrap();
1918 self.text_layout.0.insert(entity).unwrap();
1919 }
1920
1921 pub(crate) fn needs_text_layout(&mut self, entity: Entity) {
1922 self.text_layout.0.insert(entity).unwrap();
1923 }
1924
1925 pub(crate) fn needs_retransform(&mut self, entity: Entity) {
1926 self.retransform.0.insert(entity).unwrap();
1927 }
1928
1929 pub(crate) fn needs_reclip(&mut self, entity: Entity) {
1930 self.reclip.0.insert(entity).unwrap();
1931 }
1932
1933 pub(crate) fn clear_style_rules(&mut self) {
1941 self.disabled.clear_rules();
1942 self.display.clear_rules();
1944 self.visibility.clear_rules();
1946 self.opacity.clear_rules();
1948 self.z_index.clear_rules();
1950
1951 self.clip_path.clear_rules();
1953
1954 self.backdrop_filter.clear_rules();
1956
1957 self.blend_mode.clear_rules();
1959
1960 self.transform.clear_rules();
1962 self.transform_origin.clear_rules();
1963 self.translate.clear_rules();
1964 self.rotate.clear_rules();
1965 self.scale.clear_rules();
1966
1967 self.overflowx.clear_rules();
1968 self.overflowy.clear_rules();
1969
1970 self.border_width.clear_rules();
1972 self.border_color.clear_rules();
1973 self.border_style.clear_rules();
1974
1975 self.corner_bottom_left_shape.clear_rules();
1977 self.corner_bottom_right_shape.clear_rules();
1978 self.corner_top_left_shape.clear_rules();
1979 self.corner_top_right_shape.clear_rules();
1980
1981 self.corner_bottom_left_radius.clear_rules();
1983 self.corner_bottom_right_radius.clear_rules();
1984 self.corner_top_left_radius.clear_rules();
1985 self.corner_top_right_radius.clear_rules();
1986
1987 self.corner_bottom_left_smoothing.clear_rules();
1989 self.corner_bottom_right_smoothing.clear_rules();
1990 self.corner_top_left_smoothing.clear_rules();
1991 self.corner_top_right_smoothing.clear_rules();
1992
1993 self.outline_width.clear_rules();
1995 self.outline_color.clear_rules();
1996 self.outline_offset.clear_rules();
1997
1998 self.background_color.clear_rules();
2000 self.background_image.clear_rules();
2001 self.background_size.clear_rules();
2002
2003 self.shadow.clear_rules();
2004
2005 self.layout_type.clear_rules();
2006 self.position_type.clear_rules();
2007 self.alignment.clear_rules();
2008
2009 self.grid_columns.clear_rules();
2011 self.grid_rows.clear_rules();
2012 self.column_start.clear_rules();
2013 self.column_span.clear_rules();
2014
2015 self.left.clear_rules();
2017 self.right.clear_rules();
2018 self.top.clear_rules();
2019 self.bottom.clear_rules();
2020
2021 self.width.clear_rules();
2023 self.height.clear_rules();
2024
2025 self.min_width.clear_rules();
2027 self.max_width.clear_rules();
2028 self.min_height.clear_rules();
2029 self.max_height.clear_rules();
2030
2031 self.min_horizontal_gap.clear_rules();
2032 self.max_horizontal_gap.clear_rules();
2033 self.min_vertical_gap.clear_rules();
2034 self.max_vertical_gap.clear_rules();
2035
2036 self.padding_left.clear_rules();
2038 self.padding_right.clear_rules();
2039 self.padding_top.clear_rules();
2040 self.padding_bottom.clear_rules();
2041 self.horizontal_gap.clear_rules();
2042 self.vertical_gap.clear_rules();
2043
2044 self.horizontal_scroll.clear_rules();
2046 self.vertical_scroll.clear_rules();
2047
2048 self.text_wrap.clear_rules();
2050 self.text_overflow.clear_rules();
2051 self.line_clamp.clear_rules();
2052 self.text_align.clear_rules();
2053 self.font_family.clear_rules();
2054 self.font_weight.clear_rules();
2055 self.font_slant.clear_rules();
2056 self.font_color.clear_rules();
2057 self.font_size.clear_rules();
2058 self.font_variation_settings.clear_rules();
2059 self.selection_color.clear_rules();
2060 self.caret_color.clear_rules();
2061 self.text_decoration_line.clear_rules();
2062 self.text_stroke_width.clear_rules();
2063 self.text_stroke_style.clear_rules();
2064
2065 self.cursor.clear_rules();
2066
2067 self.pointer_events.clear_rules();
2068
2069 self.name.clear_rules();
2070
2071 self.fill.clear_rules();
2072 }
2073}