1use std::{
2 borrow::Cow,
3 hash::{
4 Hash,
5 Hasher,
6 },
7};
8
9use paste::paste;
10use ragnarok::CursorPoint;
11use rustc_hash::{
12 FxHashMap,
13 FxHasher,
14};
15use torin::{
16 content::Content,
17 gaps::Gaps,
18 prelude::{
19 Alignment,
20 Direction,
21 Length,
22 Position,
23 VisibleSize,
24 },
25 size::Size,
26};
27
28use crate::{
29 data::{
30 AccessibilityData,
31 EffectData,
32 LayoutData,
33 Overflow,
34 TextStyleData,
35 },
36 diff_key::DiffKey,
37 element::{
38 Element,
39 EventHandlerType,
40 },
41 elements::image::{
42 AspectRatio,
43 ImageCover,
44 ImageData,
45 SamplingMode,
46 },
47 event_handler::EventHandler,
48 events::{
49 data::{
50 Event,
51 KeyboardEventData,
52 MouseEventData,
53 SizedEventData,
54 WheelEventData,
55 },
56 name::EventName,
57 },
58 layers::Layer,
59 prelude::*,
60 style::{
61 font_size::FontSize,
62 font_slant::FontSlant,
63 font_weight::FontWeight,
64 font_width::FontWidth,
65 scale::Scale,
66 shader::ShaderFill,
67 text_height::TextHeightBehavior,
68 text_overflow::TextOverflow,
69 text_shadow::TextShadow,
70 transform_origin::TransformOrigin,
71 },
72};
73
74pub trait ChildrenExt: Sized {
76 fn get_children(&mut self) -> &mut Vec<Element>;
87
88 fn children(mut self, children: impl IntoIterator<Item = Element>) -> Self {
95 self.get_children().extend(children);
96 self
97 }
98
99 fn maybe_child<C: IntoElement>(mut self, child: Option<C>) -> Self {
106 if let Some(child) = child {
107 self.get_children().push(child.into_element());
108 }
109 self
110 }
111
112 fn child<C: IntoElement>(mut self, child: C) -> Self {
119 self.get_children().push(child.into_element());
120 self
121 }
122}
123
124pub trait KeyExt: Sized {
126 fn write_key(&mut self) -> &mut DiffKey;
128
129 fn key(mut self, key: impl Hash) -> Self {
131 let mut hasher = FxHasher::default();
132 key.hash(&mut hasher);
133 *self.write_key() = DiffKey::U64(hasher.finish());
134 self
135 }
136}
137
138pub trait ListExt {
140 fn with(self, other: Self) -> Self;
142}
143
144impl<T> ListExt for Vec<T> {
145 fn with(mut self, other: Self) -> Self {
146 self.extend(other);
147 self
148 }
149}
150
151macro_rules! event_handlers {
152 (
153 $handler_variant:ident, $event_data:ty;
154 $(
155 $(#[$attr:meta])*
156 $name:ident => $event_variant:expr ;
157 )*
158 ) => {
159 paste! {
160 $(
161 $(#[$attr])*
162 fn [<on_$name>](mut self, [<on_$name>]: impl Into<EventHandler<Event<$event_data>>>) -> Self {
163 self.get_event_handlers()
164 .insert($event_variant, EventHandlerType::$handler_variant([<on_$name>].into()));
165 self
166 }
167 )*
168 }
169 };
170}
171
172pub trait EventHandlersExt: Sized {
180 fn get_event_handlers(&mut self) -> &mut FxHashMap<EventName, EventHandlerType>;
182
183 fn with_event_handlers(
185 mut self,
186 event_handlers: FxHashMap<EventName, EventHandlerType>,
187 ) -> Self {
188 *self.get_event_handlers() = event_handlers;
189 self
190 }
191
192 event_handlers! {
193 Mouse,
194 MouseEventData;
195
196 mouse_down => EventName::MouseDown;
198 mouse_up => EventName::MouseUp;
200 mouse_move => EventName::MouseMove;
202
203 }
204
205 event_handlers! {
206 Pointer,
207 PointerEventData;
208
209 global_pointer_press => EventName::GlobalPointerPress;
211 global_pointer_down => EventName::GlobalPointerDown;
213 global_pointer_move => EventName::GlobalPointerMove;
215
216 capture_global_pointer_move => EventName::CaptureGlobalPointerMove;
218 capture_global_pointer_press => EventName::CaptureGlobalPointerPress;
220 }
221
222 event_handlers! {
223 Keyboard,
224 KeyboardEventData;
225
226 key_down => EventName::KeyDown;
228 key_up => EventName::KeyUp;
230
231 global_key_down => EventName::GlobalKeyDown;
233 global_key_up => EventName::GlobalKeyUp;
235 }
236
237 event_handlers! {
238 Wheel,
239 WheelEventData;
240
241 wheel => EventName::Wheel;
243 }
244
245 event_handlers! {
246 Touch,
247 TouchEventData;
248
249 touch_cancel => EventName::TouchCancel;
251 touch_start => EventName::TouchStart;
253 touch_move => EventName::TouchMove;
255 touch_end => EventName::TouchEnd;
257 }
258
259 event_handlers! {
260 Pointer,
261 PointerEventData;
262
263 pointer_press => EventName::PointerPress;
265 pointer_down => EventName::PointerDown;
267 pointer_move => EventName::PointerMove;
269 pointer_enter => EventName::PointerEnter;
271 pointer_leave => EventName::PointerLeave;
273 pointer_over => EventName::PointerOver;
275 pointer_out => EventName::PointerOut;
277 }
278
279 event_handlers! {
280 File,
281 FileEventData;
282
283 file_drop => EventName::FileDrop;
285 global_file_hover => EventName::GlobalFileHover;
287 global_file_hover_cancelled => EventName::GlobalFileHoverCancelled;
289 }
290
291 event_handlers! {
292 ImePreedit,
293 ImePreeditEventData;
294
295 ime_preedit => EventName::ImePreedit;
297 }
298
299 fn on_sized(mut self, on_sized: impl Into<EventHandler<Event<SizedEventData>>>) -> Self
301 where
302 Self: LayoutExt,
303 {
304 self.get_event_handlers()
305 .insert(EventName::Sized, EventHandlerType::Sized(on_sized.into()));
306 self.get_layout().layout.has_layout_references = true;
307 self
308 }
309
310 fn on_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
317 let on_press = on_press.into();
318 self.on_pointer_press({
319 let on_press = on_press.clone();
320 move |e: Event<PointerEventData>| {
321 let event = e.try_map(|d| match d {
322 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
323 Some(PressEventData::Mouse(m))
324 }
325 PointerEventData::Touch(t) => Some(PressEventData::Touch(t)),
326 _ => None,
327 });
328 if let Some(event) = event {
329 on_press.call(event);
330 }
331 }
332 })
333 .on_key_down(move |e: Event<KeyboardEventData>| {
334 if e.is_press_event() {
335 on_press.call(e.map(PressEventData::Keyboard))
336 }
337 })
338 }
339
340 fn on_secondary_down(
344 self,
345 on_secondary_down: impl Into<EventHandler<Event<PressEventData>>>,
346 ) -> Self {
347 let on_secondary_down = on_secondary_down.into();
348 self.on_pointer_down(move |e: Event<PointerEventData>| {
349 let event = e.try_map(|d| match d {
350 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Right) => {
351 Some(PressEventData::Mouse(m))
352 }
353 _ => None,
354 });
355 if let Some(event) = event {
356 on_secondary_down.call(event);
357 }
358 })
359 }
360
361 fn on_all_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
366 let on_press = on_press.into();
367 self.on_pointer_press({
368 let on_press = on_press.clone();
369 move |e: Event<PointerEventData>| {
370 let event = e.map(|d| match d {
371 PointerEventData::Mouse(m) => PressEventData::Mouse(m),
372 PointerEventData::Touch(t) => PressEventData::Touch(t),
373 });
374 on_press.call(event);
375 }
376 })
377 .on_key_down(move |e: Event<KeyboardEventData>| {
378 if e.is_press_event() {
379 on_press.call(e.map(PressEventData::Keyboard))
380 }
381 })
382 }
383 fn on_focus_press(
389 self,
390 on_focus_press: impl Into<EventHandler<Event<FocusPressEventData>>>,
391 ) -> Self {
392 let on_focus_press = on_focus_press.into();
393 if cfg!(target_os = "android") {
394 self.on_pointer_press(move |e: Event<PointerEventData>| {
395 let event = e.try_map(|d| match d {
396 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
397 Some(FocusPressEventData::Mouse(m))
398 }
399 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
400 _ => None,
401 });
402 if let Some(event) = event {
403 on_focus_press.call(event);
404 }
405 })
406 } else {
407 self.on_pointer_down(move |e: Event<PointerEventData>| {
408 let event = e.try_map(|d| match d {
409 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
410 Some(FocusPressEventData::Mouse(m))
411 }
412 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
413 _ => None,
414 });
415 if let Some(event) = event {
416 on_focus_press.call(event);
417 }
418 })
419 }
420 }
421}
422
423#[derive(Debug, Clone, PartialEq)]
425pub enum FocusPressEventData {
426 Mouse(MouseEventData),
427 Touch(TouchEventData),
428}
429
430impl FocusPressEventData {
431 pub fn global_location(&self) -> CursorPoint {
432 match self {
433 Self::Mouse(m) => m.global_location,
434 Self::Touch(t) => t.global_location,
435 }
436 }
437
438 pub fn element_location(&self) -> CursorPoint {
439 match self {
440 Self::Mouse(m) => m.element_location,
441 Self::Touch(t) => t.element_location,
442 }
443 }
444
445 pub fn button(&self) -> Option<MouseButton> {
446 match self {
447 Self::Mouse(m) => m.button,
448 Self::Touch(_) => None,
449 }
450 }
451}
452
453#[derive(Debug, Clone, PartialEq)]
455pub enum PressEventData {
456 Mouse(MouseEventData),
457 Keyboard(KeyboardEventData),
458 Touch(TouchEventData),
459}
460
461pub trait ContainerWithContentExt
463where
464 Self: LayoutExt,
465{
466 fn direction(mut self, direction: Direction) -> Self {
468 self.get_layout().layout.direction = direction;
469 self
470 }
471 fn main_align(mut self, main_align: Alignment) -> Self {
473 self.get_layout().layout.main_alignment = main_align;
474 self
475 }
476
477 fn cross_align(mut self, cross_align: Alignment) -> Self {
479 self.get_layout().layout.cross_alignment = cross_align;
480 self
481 }
482
483 fn spacing(mut self, spacing: impl Into<f32>) -> Self {
485 self.get_layout().layout.spacing = Length::new(spacing.into());
486 self
487 }
488
489 fn content(mut self, content: Content) -> Self {
491 self.get_layout().layout.content = content;
492 self
493 }
494 fn center(mut self) -> Self {
496 self.get_layout().layout.main_alignment = Alignment::Center;
497 self.get_layout().layout.cross_alignment = Alignment::Center;
498
499 self
500 }
501
502 fn offset_x(mut self, offset_x: impl Into<f32>) -> Self {
504 self.get_layout().layout.offset_x = Length::new(offset_x.into());
505 self
506 }
507
508 fn offset_y(mut self, offset_y: impl Into<f32>) -> Self {
510 self.get_layout().layout.offset_y = Length::new(offset_y.into());
511 self
512 }
513
514 fn vertical(mut self) -> Self {
516 self.get_layout().layout.direction = Direction::vertical();
517 self
518 }
519
520 fn horizontal(mut self) -> Self {
522 self.get_layout().layout.direction = Direction::horizontal();
523 self
524 }
525}
526
527pub trait ContainerSizeExt
529where
530 Self: LayoutExt,
531{
532 fn width(mut self, width: impl Into<Size>) -> Self {
534 self.get_layout().layout.width = width.into();
535 self
536 }
537
538 fn height(mut self, height: impl Into<Size>) -> Self {
540 self.get_layout().layout.height = height.into();
541 self
542 }
543
544 fn expanded(mut self) -> Self {
546 self.get_layout().layout.width = Size::fill();
547 self.get_layout().layout.height = Size::fill();
548 self
549 }
550}
551
552impl<T: ContainerExt> ContainerSizeExt for T {}
553
554pub trait ContainerExt
556where
557 Self: LayoutExt,
558{
559 fn position(mut self, position: impl Into<Position>) -> Self {
561 self.get_layout().layout.position = position.into();
562 self
563 }
564
565 fn padding(mut self, padding: impl Into<Gaps>) -> Self {
567 self.get_layout().layout.padding = padding.into();
568 self
569 }
570
571 fn margin(mut self, margin: impl Into<Gaps>) -> Self {
573 self.get_layout().layout.margin = margin.into();
574 self
575 }
576
577 fn min_width(mut self, minimum_width: impl Into<Size>) -> Self {
579 self.get_layout().layout.minimum_width = minimum_width.into();
580 self
581 }
582
583 fn min_height(mut self, minimum_height: impl Into<Size>) -> Self {
585 self.get_layout().layout.minimum_height = minimum_height.into();
586 self
587 }
588
589 fn max_width(mut self, maximum_width: impl Into<Size>) -> Self {
591 self.get_layout().layout.maximum_width = maximum_width.into();
592 self
593 }
594
595 fn max_height(mut self, maximum_height: impl Into<Size>) -> Self {
597 self.get_layout().layout.maximum_height = maximum_height.into();
598 self
599 }
600
601 fn visible_width(mut self, visible_width: impl Into<VisibleSize>) -> Self {
603 self.get_layout().layout.visible_width = visible_width.into();
604 self
605 }
606
607 fn visible_height(mut self, visible_height: impl Into<VisibleSize>) -> Self {
609 self.get_layout().layout.visible_height = visible_height.into();
610 self
611 }
612}
613
614pub trait LayoutExt
616where
617 Self: Sized,
618{
619 fn get_layout(&mut self) -> &mut LayoutData;
621
622 fn layout(mut self, layout: LayoutData) -> Self {
624 *self.get_layout() = layout;
625 self
626 }
627}
628
629pub trait ImageExt
631where
632 Self: LayoutExt,
633{
634 fn get_image_data(&mut self) -> &mut ImageData;
636
637 fn image_data(mut self, image_data: ImageData) -> Self {
639 *self.get_image_data() = image_data;
640 self
641 }
642
643 fn sampling_mode(mut self, sampling_mode: SamplingMode) -> Self {
645 self.get_image_data().sampling_mode = sampling_mode;
646 self
647 }
648
649 fn aspect_ratio(mut self, aspect_ratio: AspectRatio) -> Self {
651 self.get_image_data().aspect_ratio = aspect_ratio;
652 self
653 }
654
655 fn image_cover(mut self, image_cover: ImageCover) -> Self {
657 self.get_image_data().image_cover = image_cover;
658 self
659 }
660}
661
662pub trait AccessibilityExt: Sized {
664 fn get_accessibility_data(&mut self) -> &mut AccessibilityData;
666
667 fn accessibility(mut self, accessibility: AccessibilityData) -> Self {
669 *self.get_accessibility_data() = accessibility;
670 self
671 }
672
673 fn a11y_id(mut self, a11y_id: impl Into<Option<AccessibilityId>>) -> Self {
675 self.get_accessibility_data().a11y_id = a11y_id.into();
676 self
677 }
678
679 fn a11y_focusable(mut self, a11y_focusable: impl Into<Focusable>) -> Self {
681 self.get_accessibility_data().a11y_focusable = a11y_focusable.into();
682 self
683 }
684
685 fn a11y_auto_focus(mut self, a11y_auto_focus: impl Into<bool>) -> Self {
687 self.get_accessibility_data().a11y_auto_focus = a11y_auto_focus.into();
688 self
689 }
690
691 fn a11y_member_of(mut self, a11y_member_of: impl Into<AccessibilityId>) -> Self {
693 self.get_accessibility_data()
694 .builder
695 .set_member_of(a11y_member_of.into());
696 self
697 }
698
699 fn a11y_role(mut self, a11y_role: impl Into<AccessibilityRole>) -> Self {
701 self.get_accessibility_data()
702 .builder
703 .set_role(a11y_role.into());
704 self
705 }
706
707 fn a11y_alt(mut self, value: impl Into<Box<str>>) -> Self {
709 self.get_accessibility_data().builder.set_label(value);
710 self
711 }
712
713 fn a11y_builder(mut self, with: impl FnOnce(&mut accesskit::Node)) -> Self {
715 with(&mut self.get_accessibility_data().builder);
716 self
717 }
718}
719
720pub trait TextStyleExt
722where
723 Self: Sized,
724{
725 fn get_text_style_data(&mut self) -> &mut TextStyleData;
727
728 fn text_style(mut self, data: TextStyleData) -> Self {
730 *self.get_text_style_data() = data;
731 self
732 }
733
734 fn color(mut self, color: impl Into<Color>) -> Self {
736 self.get_text_style_data().color = Some(Fill::Color(color.into()));
737 self
738 }
739
740 fn color_conic_gradient<S: Into<ConicGradient>>(mut self, color: S) -> Self {
742 self.get_text_style_data().color = Some(Fill::ConicGradient(Box::new(color.into())));
743 self
744 }
745
746 fn color_linear_gradient<S: Into<LinearGradient>>(mut self, color: S) -> Self {
748 self.get_text_style_data().color = Some(Fill::LinearGradient(Box::new(color.into())));
749 self
750 }
751
752 fn color_radial_gradient<S: Into<RadialGradient>>(mut self, color: S) -> Self {
754 self.get_text_style_data().color = Some(Fill::RadialGradient(Box::new(color.into())));
755 self
756 }
757
758 fn color_shader(mut self, color: impl Into<ShaderFill>) -> Self {
760 self.get_text_style_data().color = Some(Fill::Shader(Box::new(color.into())));
761 self
762 }
763
764 fn text_align(mut self, text_align: impl Into<TextAlign>) -> Self {
766 self.get_text_style_data().text_align = Some(text_align.into());
767 self
768 }
769
770 fn font_size(mut self, font_size: impl Into<FontSize>) -> Self {
772 self.get_text_style_data().font_size = Some(font_size.into());
773 self
774 }
775
776 fn font_family(mut self, font_family: impl Into<Cow<'static, str>>) -> Self {
778 self.get_text_style_data()
779 .font_families
780 .push(font_family.into());
781 self
782 }
783
784 fn font_slant(mut self, font_slant: impl Into<FontSlant>) -> Self {
786 self.get_text_style_data().font_slant = Some(font_slant.into());
787 self
788 }
789
790 fn font_weight(mut self, font_weight: impl Into<FontWeight>) -> Self {
792 self.get_text_style_data().font_weight = Some(font_weight.into());
793 self
794 }
795
796 fn font_width(mut self, font_width: impl Into<FontWidth>) -> Self {
798 self.get_text_style_data().font_width = Some(font_width.into());
799 self
800 }
801
802 fn text_height(mut self, text_height: impl Into<TextHeightBehavior>) -> Self {
804 self.get_text_style_data().text_height = Some(text_height.into());
805 self
806 }
807
808 fn text_overflow(mut self, text_overflow: impl Into<TextOverflow>) -> Self {
810 self.get_text_style_data().text_overflow = Some(text_overflow.into());
811 self
812 }
813
814 fn text_shadow(mut self, text_shadow: impl Into<TextShadow>) -> Self {
816 self.get_text_style_data()
817 .text_shadows
818 .push(text_shadow.into());
819 self
820 }
821
822 fn text_decoration(mut self, text_decoration: impl Into<TextDecoration>) -> Self {
824 self.get_text_style_data().text_decoration = Some(text_decoration.into());
825 self
826 }
827}
828
829pub trait StyleExt
831where
832 Self: Sized,
833{
834 fn get_style(&mut self) -> &mut StyleState;
836
837 fn background<S: Into<Color>>(mut self, background: S) -> Self {
839 self.get_style().background = Fill::Color(background.into());
840 self
841 }
842
843 fn background_conic_gradient<S: Into<ConicGradient>>(mut self, background: S) -> Self {
845 self.get_style().background = Fill::ConicGradient(Box::new(background.into()));
846 self
847 }
848
849 fn background_linear_gradient<S: Into<LinearGradient>>(mut self, background: S) -> Self {
851 self.get_style().background = Fill::LinearGradient(Box::new(background.into()));
852 self
853 }
854
855 fn background_radial_gradient<S: Into<RadialGradient>>(mut self, background: S) -> Self {
857 self.get_style().background = Fill::RadialGradient(Box::new(background.into()));
858 self
859 }
860
861 fn background_shader(mut self, background: impl Into<ShaderFill>) -> Self {
863 self.get_style().background = Fill::Shader(Box::new(background.into()));
864 self
865 }
866
867 fn border(mut self, border: impl Into<Option<Border>>) -> Self {
869 if let Some(border) = border.into() {
870 self.get_style().borders.push(border);
871 }
872 self
873 }
874
875 fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
877 self.get_style().shadows.push(shadow.into());
878 self
879 }
880
881 fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
883 self.get_style().corner_radius = corner_radius.into();
884 self
885 }
886}
887
888impl<T: StyleExt> CornerRadiusExt for T {
889 fn with_corner_radius(mut self, corner_radius: f32) -> Self {
890 self.get_style().corner_radius = CornerRadius::new_all(corner_radius);
891 self
892 }
893}
894
895pub trait CornerRadiusExt: Sized {
897 fn with_corner_radius(self, corner_radius: f32) -> Self;
899
900 fn rounded_none(self) -> Self {
902 self.with_corner_radius(0.)
903 }
904
905 fn rounded(self) -> Self {
907 self.with_corner_radius(6.)
908 }
909
910 fn rounded_sm(self) -> Self {
912 self.with_corner_radius(4.)
913 }
914
915 fn rounded_md(self) -> Self {
917 self.with_corner_radius(6.)
918 }
919
920 fn rounded_lg(self) -> Self {
922 self.with_corner_radius(8.)
923 }
924
925 fn rounded_xl(self) -> Self {
927 self.with_corner_radius(12.)
928 }
929
930 fn rounded_2xl(self) -> Self {
932 self.with_corner_radius(16.)
933 }
934
935 fn rounded_3xl(self) -> Self {
937 self.with_corner_radius(24.)
938 }
939
940 fn rounded_4xl(self) -> Self {
942 self.with_corner_radius(32.)
943 }
944
945 fn rounded_full(self) -> Self {
947 self.with_corner_radius(99.)
948 }
949}
950
951pub trait MaybeExt
953where
954 Self: Sized,
955{
956 fn maybe(self, bool: impl Into<bool>, then: impl FnOnce(Self) -> Self) -> Self {
958 if bool.into() { then(self) } else { self }
959 }
960
961 fn map<T>(self, data: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self {
963 if let Some(data) = data {
964 then(self, data)
965 } else {
966 self
967 }
968 }
969}
970
971pub trait LayerExt
973where
974 Self: Sized,
975{
976 fn get_layer(&mut self) -> &mut Layer;
978
979 fn layer(mut self, layer: impl Into<Layer>) -> Self {
981 *self.get_layer() = layer.into();
982 self
983 }
984}
985
986pub trait ScrollableExt
987where
988 Self: Sized,
989{
990 fn get_effect(&mut self) -> &mut EffectData;
992
993 fn scrollable(mut self, scrollable: impl Into<bool>) -> Self {
996 self.get_effect().scrollable = scrollable.into();
997 self
998 }
999}
1000
1001pub trait InteractiveExt
1003where
1004 Self: Sized,
1005{
1006 fn get_effect(&mut self) -> &mut EffectData;
1008
1009 fn interactive(mut self, interactive: impl Into<Interactive>) -> Self {
1011 self.get_effect().interactive = interactive.into();
1012 self
1013 }
1014}
1015
1016pub trait EffectExt: Sized {
1018 fn get_effect(&mut self) -> &mut EffectData;
1020
1021 fn effect(mut self, effect: EffectData) -> Self {
1023 *self.get_effect() = effect;
1024 self
1025 }
1026
1027 fn overflow(mut self, overflow: impl Into<Overflow>) -> Self {
1029 self.get_effect().overflow = overflow.into();
1030 self
1031 }
1032
1033 fn blur(mut self, blur: impl Into<f32>) -> Self {
1035 self.get_effect().blur = Some(blur.into());
1036 self
1037 }
1038
1039 fn rotation(mut self, rotation: impl Into<f32>) -> Self {
1041 self.get_effect().rotation = Some(rotation.into());
1042 self
1043 }
1044
1045 fn opacity(mut self, opacity: impl Into<f32>) -> Self {
1047 self.get_effect().opacity = Some(opacity.into());
1048 self
1049 }
1050
1051 fn scale(mut self, scale: impl Into<Scale>) -> Self {
1053 self.get_effect().scale = Some(scale.into());
1054 self
1055 }
1056
1057 fn transform_origin(mut self, transform_origin: impl Into<TransformOrigin>) -> Self {
1061 self.get_effect().transform_origin = transform_origin.into();
1062 self
1063 }
1064}