1use std::{
2 borrow::Cow,
3 hash::{
4 Hash,
5 Hasher,
6 },
7};
8
9use paste::paste;
10use rustc_hash::{
11 FxHashMap,
12 FxHasher,
13};
14use torin::{
15 content::Content,
16 gaps::Gaps,
17 prelude::{
18 Alignment,
19 Direction,
20 Length,
21 Position,
22 VisibleSize,
23 },
24 size::{
25 Size,
26 SizeFn,
27 SizeFnContext,
28 },
29};
30
31use crate::{
32 data::{
33 AccessibilityData,
34 EffectData,
35 LayoutData,
36 Overflow,
37 TextStyleData,
38 },
39 diff_key::DiffKey,
40 element::{
41 Element,
42 EventHandlerType,
43 },
44 elements::image::{
45 AspectRatio,
46 ImageCover,
47 ImageData,
48 SamplingMode,
49 },
50 event_handler::EventHandler,
51 events::{
52 data::{
53 Event,
54 KeyboardEventData,
55 MouseEventData,
56 SizedEventData,
57 WheelEventData,
58 },
59 name::EventName,
60 },
61 layers::Layer,
62 prelude::*,
63 style::{
64 font_size::FontSize,
65 font_slant::FontSlant,
66 font_weight::FontWeight,
67 font_width::FontWidth,
68 scale::Scale,
69 text_height::TextHeightBehavior,
70 text_overflow::TextOverflow,
71 text_shadow::TextShadow,
72 },
73};
74
75pub trait SizeExt {
76 fn auto() -> Size;
77 fn fill() -> Size;
78 fn fill_minimum() -> Size;
79 fn percent(percent: impl Into<f32>) -> Size;
80 fn px(px: impl Into<f32>) -> Size;
81 fn window_percent(percent: impl Into<f32>) -> Size;
82 fn flex(flex: impl Into<f32>) -> Size;
83 fn func(func: impl Fn(SizeFnContext) -> Option<f32> + 'static + Sync + Send) -> Size;
84 fn func_data<D: Hash>(
85 func: impl Fn(SizeFnContext) -> Option<f32> + 'static + Sync + Send,
86 data: &D,
87 ) -> Size;
88}
89
90impl SizeExt for Size {
91 fn auto() -> Size {
92 Size::Inner
93 }
94
95 fn fill() -> Size {
96 Size::Fill
97 }
98
99 fn fill_minimum() -> Size {
100 Size::FillMinimum
101 }
102
103 fn percent(percent: impl Into<f32>) -> Size {
104 Size::Percentage(Length::new(percent.into()))
105 }
106
107 fn px(px: impl Into<f32>) -> Size {
108 Size::Pixels(Length::new(px.into()))
109 }
110
111 fn window_percent(percent: impl Into<f32>) -> Size {
112 Size::RootPercentage(Length::new(percent.into()))
113 }
114
115 fn flex(flex: impl Into<f32>) -> Size {
116 Size::Flex(Length::new(flex.into()))
117 }
118
119 fn func(func: impl Fn(SizeFnContext) -> Option<f32> + 'static + Sync + Send) -> Size {
120 Self::Fn(Box::new(SizeFn::new(func)))
121 }
122
123 fn func_data<D: Hash>(
124 func: impl Fn(SizeFnContext) -> Option<f32> + 'static + Sync + Send,
125 data: &D,
126 ) -> Size {
127 Self::Fn(Box::new(SizeFn::new_data(func, data)))
128 }
129}
130
131pub trait DirectionExt {
132 fn vertical() -> Direction;
133 fn horizontal() -> Direction;
134}
135
136impl DirectionExt for Direction {
137 fn vertical() -> Direction {
138 Direction::Vertical
139 }
140 fn horizontal() -> Direction {
141 Direction::Horizontal
142 }
143}
144
145pub trait AlignmentExt {
146 fn start() -> Alignment;
147 fn center() -> Alignment;
148 fn end() -> Alignment;
149 fn space_between() -> Alignment;
150 fn space_evenly() -> Alignment;
151 fn space_around() -> Alignment;
152}
153
154impl AlignmentExt for Alignment {
155 fn start() -> Alignment {
156 Alignment::Start
157 }
158
159 fn center() -> Alignment {
160 Alignment::Center
161 }
162
163 fn end() -> Alignment {
164 Alignment::End
165 }
166
167 fn space_between() -> Alignment {
168 Alignment::SpaceBetween
169 }
170
171 fn space_evenly() -> Alignment {
172 Alignment::SpaceEvenly
173 }
174
175 fn space_around() -> Alignment {
176 Alignment::SpaceAround
177 }
178}
179
180pub trait ContentExt {
181 fn normal() -> Content;
182 fn fit() -> Content;
183 fn flex() -> Content;
184 fn wrap() -> Content;
185}
186
187impl ContentExt for Content {
188 fn normal() -> Content {
189 Content::Normal
190 }
191
192 fn fit() -> Content {
193 Content::Fit
194 }
195
196 fn flex() -> Content {
197 Content::Flex
198 }
199
200 fn wrap() -> Content {
201 Content::Wrap
202 }
203}
204
205pub trait VisibleSizeExt {
206 fn full() -> VisibleSize;
207 fn inner_percent(value: impl Into<f32>) -> VisibleSize;
208}
209
210impl VisibleSizeExt for VisibleSize {
211 fn full() -> VisibleSize {
212 VisibleSize::Full
213 }
214
215 fn inner_percent(value: impl Into<f32>) -> VisibleSize {
216 VisibleSize::InnerPercentage(Length::new(value.into()))
217 }
218}
219
220pub trait ChildrenExt: Sized {
221 fn get_children(&mut self) -> &mut Vec<Element>;
222
223 fn children(mut self, children: impl IntoIterator<Item = Element>) -> Self {
224 self.get_children().extend(children);
225 self
226 }
227
228 fn maybe_child<C: IntoElement>(mut self, child: Option<C>) -> Self {
229 if let Some(child) = child {
230 self.get_children().push(child.into_element());
231 }
232 self
233 }
234
235 fn child<C: IntoElement>(mut self, child: C) -> Self {
236 self.get_children().push(child.into_element());
237 self
238 }
239}
240
241pub trait KeyExt: Sized {
242 fn write_key(&mut self) -> &mut DiffKey;
243
244 fn key(mut self, key: impl Hash) -> Self {
245 let mut hasher = FxHasher::default();
246 key.hash(&mut hasher);
247 *self.write_key() = DiffKey::U64(hasher.finish());
248 self
249 }
250}
251
252pub trait ListExt {
253 fn with(self, other: Self) -> Self;
254}
255
256impl<T> ListExt for Vec<T> {
257 fn with(mut self, other: Self) -> Self {
258 self.extend(other);
259 self
260 }
261}
262
263macro_rules! event_handlers {
264 (
265 $handler_variant:ident, $event_data:ty;
266 $(
267 $name:ident => $event_variant:expr ;
268 )*
269 ) => {
270 paste! {
271 $(
272 fn [<on_$name>](mut self, [<on_$name>]: impl Into<EventHandler<Event<$event_data>>>) -> Self {
273 self.get_event_handlers()
274 .insert($event_variant, EventHandlerType::$handler_variant([<on_$name>].into()));
275 self
276 }
277 )*
278 }
279 };
280}
281
282pub trait EventHandlersExt: Sized {
283 fn get_event_handlers(&mut self) -> &mut FxHashMap<EventName, EventHandlerType>;
284
285 fn with_event_handlers(
286 mut self,
287 event_handlers: FxHashMap<EventName, EventHandlerType>,
288 ) -> Self {
289 *self.get_event_handlers() = event_handlers;
290 self
291 }
292
293 event_handlers! {
294 Mouse,
295 MouseEventData;
296
297 mouse_down => EventName::MouseDown;
298 mouse_up => EventName::MouseUp;
299 mouse_move => EventName::MouseMove;
300
301 global_mouse_up => EventName::GlobalMouseUp;
302 global_mouse_down => EventName::GlobalMouseDown;
303 global_mouse_move => EventName::GlobalMouseMove;
304
305 capture_global_mouse_move => EventName::CaptureGlobalMouseMove;
306 capture_global_mouse_up => EventName::CaptureGlobalMouseUp;
307 }
308
309 event_handlers! {
310 Keyboard,
311 KeyboardEventData;
312
313 key_down => EventName::KeyDown;
314 key_up => EventName::KeyUp;
315
316 global_key_down => EventName::GlobalKeyDown;
317 global_key_up => EventName::GlobalKeyUp;
318 }
319
320 event_handlers! {
321 Wheel,
322 WheelEventData;
323
324 wheel => EventName::Wheel;
325 }
326
327 event_handlers! {
328 Touch,
329 TouchEventData;
330
331 touch_cancel => EventName::TouchCancel;
332 touch_start => EventName::TouchStart;
333 touch_move => EventName::TouchMove;
334 touch_end => EventName::TouchEnd;
335 }
336
337 event_handlers! {
338 Pointer,
339 PointerEventData;
340
341 pointer_press => EventName::PointerPress;
342 pointer_down => EventName::PointerDown;
343 pointer_enter => EventName::PointerEnter;
344 pointer_leave => EventName::PointerLeave;
345 }
346
347 event_handlers! {
348 File,
349 FileEventData;
350
351 file_drop => EventName::FileDrop;
352 global_file_hover => EventName::GlobalFileHover;
353 global_file_hover_cancelled => EventName::GlobalFileHoverCancelled;
354 }
355
356 event_handlers! {
357 ImePreedit,
358 ImePreeditEventData;
359
360 ime_preedit => EventName::ImePreedit;
361 }
362
363 fn on_sized(mut self, on_sized: impl Into<EventHandler<Event<SizedEventData>>>) -> Self
364 where
365 Self: LayoutExt,
366 {
367 self.get_event_handlers()
368 .insert(EventName::Sized, EventHandlerType::Sized(on_sized.into()));
369 self.get_layout().layout.has_layout_references = true;
370 self
371 }
372
373 fn on_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
380 let on_press = on_press.into();
381 self.on_pointer_press({
382 let on_press = on_press.clone();
383 move |e: Event<PointerEventData>| {
384 let event = e.try_map(|d| match d {
385 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
386 Some(PressEventData::Mouse(m))
387 }
388 PointerEventData::Touch(t) => Some(PressEventData::Touch(t)),
389 _ => None,
390 });
391 if let Some(event) = event {
392 on_press.call(event);
393 }
394 }
395 })
396 .on_key_down({
397 let on_press = on_press.clone();
398 move |e: Event<KeyboardEventData>| {
399 if Focus::is_pressed(&e) {
400 on_press.call(e.map(PressEventData::Keyboard))
401 }
402 }
403 })
404 }
405
406 fn on_secondary_press(
410 self,
411 on_pointer_press: impl Into<EventHandler<Event<PressEventData>>>,
412 ) -> Self {
413 let on_pointer_press = on_pointer_press.into();
414 self.on_pointer_press({
415 let on_pointer_press = on_pointer_press.clone();
416 move |e: Event<PointerEventData>| {
417 let event = e.try_map(|d| match d {
418 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Right) => {
419 Some(PressEventData::Mouse(m))
420 }
421 _ => None,
422 });
423 if let Some(event) = event {
424 on_pointer_press.call(event);
425 }
426 }
427 })
428 }
429
430 fn on_all_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
435 let on_press = on_press.into();
436 self.on_pointer_press({
437 let on_press = on_press.clone();
438 move |e: Event<PointerEventData>| {
439 let event = e.try_map(|d| match d {
440 PointerEventData::Mouse(m) => Some(PressEventData::Mouse(m)),
441 PointerEventData::Touch(t) => Some(PressEventData::Touch(t)),
442 });
443 if let Some(event) = event {
444 on_press.call(event);
445 }
446 }
447 })
448 .on_key_down({
449 let on_press = on_press.clone();
450 move |e: Event<KeyboardEventData>| {
451 if Focus::is_pressed(&e) {
452 on_press.call(e.map(PressEventData::Keyboard))
453 }
454 }
455 })
456 }
457}
458
459#[derive(Debug, Clone, PartialEq)]
460pub enum PressEventData {
461 Mouse(MouseEventData),
462 Keyboard(KeyboardEventData),
463 Touch(TouchEventData),
464}
465
466pub trait ContainerWithContentExt
467where
468 Self: LayoutExt,
469{
470 fn direction(mut self, direction: Direction) -> Self {
471 self.get_layout().layout.direction = direction;
472 self
473 }
474 fn main_align(mut self, main_align: Alignment) -> Self {
475 self.get_layout().layout.main_alignment = main_align;
476 self
477 }
478
479 fn cross_align(mut self, cross_align: Alignment) -> Self {
480 self.get_layout().layout.cross_alignment = cross_align;
481 self
482 }
483
484 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 {
490 self.get_layout().layout.content = content;
491 self
492 }
493 fn center(mut self) -> Self {
494 self.get_layout().layout.main_alignment = Alignment::Center;
495 self.get_layout().layout.cross_alignment = Alignment::Center;
496
497 self
498 }
499
500 fn offset_x(mut self, offset_x: impl Into<f32>) -> Self {
501 self.get_layout().layout.offset_x = Length::new(offset_x.into());
502 self
503 }
504
505 fn offset_y(mut self, offset_y: impl Into<f32>) -> Self {
506 self.get_layout().layout.offset_y = Length::new(offset_y.into());
507 self
508 }
509
510 fn vertical(mut self) -> Self {
511 self.get_layout().layout.direction = Direction::vertical();
512 self
513 }
514
515 fn horizontal(mut self) -> Self {
516 self.get_layout().layout.direction = Direction::horizontal();
517 self
518 }
519}
520
521pub trait ContainerSizeExt
522where
523 Self: LayoutExt,
524{
525 fn width(mut self, width: impl Into<Size>) -> Self {
526 self.get_layout().layout.width = width.into();
527 self
528 }
529
530 fn height(mut self, height: impl Into<Size>) -> Self {
531 self.get_layout().layout.height = height.into();
532 self
533 }
534
535 fn expanded(mut self) -> Self {
537 self.get_layout().layout.width = Size::fill();
538 self.get_layout().layout.height = Size::fill();
539 self
540 }
541}
542
543impl<T: ContainerExt> ContainerSizeExt for T {}
544
545pub trait ContainerExt
546where
547 Self: LayoutExt,
548{
549 fn position(mut self, position: impl Into<Position>) -> Self {
550 self.get_layout().layout.position = position.into();
551 self
552 }
553
554 fn padding(mut self, padding: impl Into<Gaps>) -> Self {
555 self.get_layout().layout.padding = padding.into();
556 self
557 }
558
559 fn margin(mut self, margin: impl Into<Gaps>) -> Self {
560 self.get_layout().layout.margin = margin.into();
561 self
562 }
563
564 fn min_width(mut self, minimum_width: impl Into<Size>) -> Self {
565 self.get_layout().layout.minimum_width = minimum_width.into();
566 self
567 }
568
569 fn min_height(mut self, minimum_height: impl Into<Size>) -> Self {
570 self.get_layout().layout.minimum_height = minimum_height.into();
571 self
572 }
573
574 fn max_width(mut self, maximum_width: impl Into<Size>) -> Self {
575 self.get_layout().layout.maximum_width = maximum_width.into();
576 self
577 }
578
579 fn max_height(mut self, maximum_height: impl Into<Size>) -> Self {
580 self.get_layout().layout.maximum_height = maximum_height.into();
581 self
582 }
583
584 fn visible_width(mut self, visible_width: impl Into<VisibleSize>) -> Self {
585 self.get_layout().layout.visible_width = visible_width.into();
586 self
587 }
588
589 fn visible_height(mut self, visible_height: impl Into<VisibleSize>) -> Self {
590 self.get_layout().layout.visible_height = visible_height.into();
591 self
592 }
593}
594
595pub trait LayoutExt
596where
597 Self: Sized,
598{
599 fn get_layout(&mut self) -> &mut LayoutData;
600
601 fn layout(mut self, layout: LayoutData) -> Self {
602 *self.get_layout() = layout;
603 self
604 }
605}
606
607pub trait ImageExt
608where
609 Self: LayoutExt,
610{
611 fn get_image_data(&mut self) -> &mut ImageData;
612
613 fn image_data(mut self, image_data: ImageData) -> Self {
614 *self.get_image_data() = image_data;
615 self
616 }
617
618 fn sampling_mode(mut self, sampling_mode: SamplingMode) -> Self {
619 self.get_image_data().sampling_mode = sampling_mode;
620 self
621 }
622
623 fn aspect_ratio(mut self, aspect_ratio: AspectRatio) -> Self {
624 self.get_image_data().aspect_ratio = aspect_ratio;
625 self
626 }
627
628 fn image_cover(mut self, image_cover: ImageCover) -> Self {
629 self.get_image_data().image_cover = image_cover;
630 self
631 }
632}
633
634pub trait AccessibilityExt: Sized {
635 fn get_accessibility_data(&mut self) -> &mut AccessibilityData;
636
637 fn accessibility(mut self, accessibility: AccessibilityData) -> Self {
638 *self.get_accessibility_data() = accessibility;
639 self
640 }
641
642 fn a11y_id(mut self, a11y_id: impl Into<Option<AccessibilityId>>) -> Self {
643 self.get_accessibility_data().a11y_id = a11y_id.into();
644 self
645 }
646
647 fn a11y_focusable(mut self, a11y_focusable: impl Into<Focusable>) -> Self {
648 self.get_accessibility_data().a11y_focusable = a11y_focusable.into();
649 self
650 }
651
652 fn a11y_auto_focus(mut self, a11y_auto_focus: impl Into<bool>) -> Self {
653 self.get_accessibility_data().a11y_auto_focus = a11y_auto_focus.into();
654 self
655 }
656
657 fn a11y_member_of(mut self, a11y_member_of: impl Into<AccessibilityId>) -> Self {
658 self.get_accessibility_data()
659 .builder
660 .set_member_of(a11y_member_of.into());
661 self
662 }
663
664 fn a11y_role(mut self, a11y_role: impl Into<AccessibilityRole>) -> Self {
665 self.get_accessibility_data()
666 .builder
667 .set_role(a11y_role.into());
668 self
669 }
670
671 fn a11y_alt(mut self, value: impl Into<Box<str>>) -> Self {
672 self.get_accessibility_data().builder.set_label(value);
673 self
674 }
675
676 fn a11y_builder(mut self, with: impl FnOnce(&mut accesskit::Node)) -> Self {
677 with(&mut self.get_accessibility_data().builder);
678 self
679 }
680}
681
682pub trait TextStyleExt
683where
684 Self: Sized,
685{
686 fn get_text_style_data(&mut self) -> &mut TextStyleData;
687
688 fn color(mut self, color: impl Into<Color>) -> Self {
689 self.get_text_style_data().color = Some(color.into());
690 self
691 }
692
693 fn text_align(mut self, text_align: impl Into<TextAlign>) -> Self {
694 self.get_text_style_data().text_align = Some(text_align.into());
695 self
696 }
697
698 fn font_size(mut self, font_size: impl Into<FontSize>) -> Self {
699 self.get_text_style_data().font_size = Some(font_size.into());
700 self
701 }
702
703 fn font_family(mut self, font_family: impl Into<Cow<'static, str>>) -> Self {
704 self.get_text_style_data()
705 .font_families
706 .push(font_family.into());
707 self
708 }
709
710 fn font_slant(mut self, font_slant: impl Into<FontSlant>) -> Self {
711 self.get_text_style_data().font_slant = Some(font_slant.into());
712 self
713 }
714
715 fn font_weight(mut self, font_weight: impl Into<FontWeight>) -> Self {
716 self.get_text_style_data().font_weight = Some(font_weight.into());
717 self
718 }
719
720 fn font_width(mut self, font_width: impl Into<FontWidth>) -> Self {
721 self.get_text_style_data().font_width = Some(font_width.into());
722 self
723 }
724
725 fn text_height(mut self, text_height: impl Into<TextHeightBehavior>) -> Self {
726 self.get_text_style_data().text_height = Some(text_height.into());
727 self
728 }
729
730 fn text_overflow(mut self, text_overflow: impl Into<TextOverflow>) -> Self {
731 self.get_text_style_data().text_overflow = Some(text_overflow.into());
732 self
733 }
734
735 fn text_shadow(mut self, text_shadow: impl Into<TextShadow>) -> Self {
736 self.get_text_style_data()
737 .text_shadows
738 .push(text_shadow.into());
739 self
740 }
741}
742
743pub trait StyleExt
744where
745 Self: Sized,
746{
747 fn get_style(&mut self) -> &mut StyleState;
748
749 fn background<S: Into<Color>>(mut self, background: S) -> Self {
750 self.get_style().background = Fill::Color(background.into());
751 self
752 }
753
754 fn background_conic_gradient<S: Into<ConicGradient>>(mut self, background: S) -> Self {
755 self.get_style().background = Fill::ConicGradient(Box::new(background.into()));
756 self
757 }
758
759 fn background_linear_gradient<S: Into<LinearGradient>>(mut self, background: S) -> Self {
760 self.get_style().background = Fill::LinearGradient(Box::new(background.into()));
761 self
762 }
763
764 fn background_radial_gradient<S: Into<RadialGradient>>(mut self, background: S) -> Self {
765 self.get_style().background = Fill::RadialGradient(Box::new(background.into()));
766 self
767 }
768
769 fn border(mut self, border: impl Into<Option<Border>>) -> Self {
770 if let Some(border) = border.into() {
771 self.get_style().borders.push(border);
772 }
773 self
774 }
775
776 fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
777 self.get_style().shadows.push(shadow.into());
778 self
779 }
780
781 fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
782 self.get_style().corner_radius = corner_radius.into();
783 self
784 }
785}
786
787impl<T: StyleExt> CornerRadiusExt for T {
788 fn with_corner_radius(mut self, corner_radius: f32) -> Self {
789 self.get_style().corner_radius = CornerRadius::new_all(corner_radius);
790 self
791 }
792}
793
794pub trait CornerRadiusExt: Sized {
795 fn with_corner_radius(self, corner_radius: f32) -> Self;
796
797 fn rounded_none(self) -> Self {
799 self.with_corner_radius(0.)
800 }
801
802 fn rounded(self) -> Self {
804 self.with_corner_radius(6.)
805 }
806
807 fn rounded_sm(self) -> Self {
809 self.with_corner_radius(4.)
810 }
811
812 fn rounded_md(self) -> Self {
814 self.with_corner_radius(6.)
815 }
816
817 fn rounded_lg(self) -> Self {
819 self.with_corner_radius(8.)
820 }
821
822 fn rounded_xl(self) -> Self {
824 self.with_corner_radius(12.)
825 }
826
827 fn rounded_2xl(self) -> Self {
829 self.with_corner_radius(16.)
830 }
831
832 fn rounded_3xl(self) -> Self {
834 self.with_corner_radius(24.)
835 }
836
837 fn rounded_4xl(self) -> Self {
839 self.with_corner_radius(32.)
840 }
841
842 fn rounded_full(self) -> Self {
844 self.with_corner_radius(99.)
845 }
846}
847
848pub trait MaybeExt
849where
850 Self: Sized,
851{
852 fn maybe(self, bool: impl Into<bool>, then: impl FnOnce(Self) -> Self) -> Self {
853 if bool.into() { then(self) } else { self }
854 }
855
856 fn map<T>(self, data: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self {
857 if let Some(data) = data {
858 then(self, data)
859 } else {
860 self
861 }
862 }
863}
864
865pub trait LayerExt
866where
867 Self: Sized,
868{
869 fn get_layer(&mut self) -> &mut Layer;
870
871 fn layer(mut self, layer: impl Into<Layer>) -> Self {
872 *self.get_layer() = layer.into();
873 self
874 }
875}
876
877pub trait ScrollableExt
878where
879 Self: Sized,
880{
881 fn get_effect(&mut self) -> &mut EffectData;
882
883 fn scrollable(mut self, scrollable: impl Into<bool>) -> Self {
884 self.get_effect().scrollable = scrollable.into();
885 self
886 }
887}
888
889pub trait InteractiveExt
890where
891 Self: Sized,
892{
893 fn get_effect(&mut self) -> &mut EffectData;
894
895 fn interactive(mut self, interactive: impl Into<Interactive>) -> Self {
896 self.get_effect().interactive = interactive.into();
897 self
898 }
899}
900
901pub trait EffectExt: Sized {
902 fn get_effect(&mut self) -> &mut EffectData;
903
904 fn effect(mut self, effect: EffectData) -> Self {
905 *self.get_effect() = effect;
906 self
907 }
908
909 fn overflow(mut self, overflow: impl Into<Overflow>) -> Self {
910 self.get_effect().overflow = overflow.into();
911 self
912 }
913
914 fn blur(mut self, blur: impl Into<f32>) -> Self {
915 self.get_effect().blur = Some(blur.into());
916 self
917 }
918
919 fn rotation(mut self, rotation: impl Into<f32>) -> Self {
920 self.get_effect().rotation = Some(rotation.into());
921 self
922 }
923
924 fn opacity(mut self, opacity: impl Into<f32>) -> Self {
925 self.get_effect().opacity = Some(opacity.into());
926 self
927 }
928
929 fn scale(mut self, scale: impl Into<Scale>) -> Self {
930 self.get_effect().scale = Some(scale.into());
931 self
932 }
933}