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