1use std::{
2 borrow::Cow,
3 hash::{
4 Hash,
5 Hasher,
6 },
7};
8
9use paste::paste;
10use ragnarok::CursorPoint;
11use rustc_hash::FxHasher;
12use torin::{
13 content::Content,
14 gaps::Gaps,
15 prelude::{
16 Alignment,
17 Direction,
18 Length,
19 Position,
20 VisibleSize,
21 },
22 size::Size,
23};
24
25use crate::{
26 data::{
27 AccessibilityData,
28 EffectData,
29 LayoutData,
30 Overflow,
31 TextStyleData,
32 },
33 diff_key::DiffKey,
34 element::{
35 Element,
36 EventHandlerType,
37 EventHandlers,
38 },
39 elements::image::{
40 AspectRatio,
41 ImageCover,
42 ImageData,
43 SamplingMode,
44 },
45 event_handler::EventHandler,
46 events::{
47 data::{
48 Event,
49 KeyboardEventData,
50 MouseEventData,
51 SizedEventData,
52 StyledEventData,
53 VisibleEventData,
54 WheelEventData,
55 },
56 name::EventName,
57 },
58 layers::Layer,
59 prelude::*,
60 style::{
61 font_feature::FontFeature,
62 font_size::FontSize,
63 font_slant::FontSlant,
64 font_weight::FontWeight,
65 font_width::FontWidth,
66 letter_spacing::LetterSpacing,
67 scale::Scale,
68 text_height::TextHeightBehavior,
69 text_overflow::TextOverflow,
70 text_shadow::TextShadow,
71 transform_origin::TransformOrigin,
72 },
73};
74
75pub trait ChildrenExt: Sized {
77 fn get_children(&mut self) -> &mut Vec<Element>;
88
89 fn children(mut self, children: impl IntoIterator<Item = impl IntoElement>) -> Self {
96 self.get_children()
97 .extend(children.into_iter().map(IntoElement::into_element));
98 self
99 }
100
101 fn maybe_child<C: IntoElement>(mut self, child: Option<C>) -> Self {
108 if let Some(child) = child {
109 self.get_children().push(child.into_element());
110 }
111 self
112 }
113
114 fn child<C: IntoElement>(mut self, child: C) -> Self {
121 self.get_children().push(child.into_element());
122 self
123 }
124}
125
126pub trait KeyExt: Sized {
128 fn write_key(&mut self) -> &mut DiffKey;
130
131 fn key(mut self, key: impl Hash) -> Self
135 where
136 Self: 'static,
137 {
138 let mut hasher = FxHasher::default();
139 std::any::TypeId::of::<Self>().hash(&mut hasher);
140 key.hash(&mut hasher);
141 *self.write_key() = DiffKey::U64(hasher.finish());
142 self
143 }
144}
145
146pub trait ListExt {
148 fn with(self, other: Self) -> Self;
150}
151
152impl<T> ListExt for Vec<T> {
153 fn with(mut self, other: Self) -> Self {
154 self.extend(other);
155 self
156 }
157}
158
159macro_rules! event_handlers {
160 (
161 $handler_variant:ident, $event_data:ty;
162 $(
163 $(#[$attr:meta])*
164 $name:ident => $event_variant:expr ;
165 )*
166 ) => {
167 paste! {
168 $(
169 $(#[$attr])*
170 fn [<on_$name>](mut self, [<on_$name>]: impl Into<EventHandler<Event<$event_data>>>) -> Self {
171 self.get_event_handlers()
172 .insert($event_variant, EventHandlerType::$handler_variant([<on_$name>].into()));
173 self
174 }
175 )*
176 }
177 };
178}
179
180pub trait EventHandlersExt: Sized {
188 fn get_event_handlers(&mut self) -> &mut EventHandlers;
190
191 fn event_handlers(mut self, event_handlers: EventHandlers) -> Self {
193 *self.get_event_handlers() = event_handlers;
194 self
195 }
196
197 event_handlers! {
198 Mouse,
199 MouseEventData;
200
201 mouse_down => EventName::MouseDown;
203 mouse_up => EventName::MouseUp;
205 mouse_move => EventName::MouseMove;
207
208 }
209
210 event_handlers! {
211 Pointer,
212 PointerEventData;
213
214 global_pointer_press => EventName::GlobalPointerPress;
216 global_pointer_down => EventName::GlobalPointerDown;
218 global_pointer_move => EventName::GlobalPointerMove;
220
221 capture_global_pointer_move => EventName::CaptureGlobalPointerMove;
223 capture_global_pointer_press => EventName::CaptureGlobalPointerPress;
225 }
226
227 event_handlers! {
228 Keyboard,
229 KeyboardEventData;
230
231 key_down => EventName::KeyDown;
233 key_up => EventName::KeyUp;
235
236 global_key_down => EventName::GlobalKeyDown;
238 global_key_up => EventName::GlobalKeyUp;
240 }
241
242 event_handlers! {
243 Wheel,
244 WheelEventData;
245
246 wheel => EventName::Wheel;
248 }
249
250 event_handlers! {
251 Touch,
252 TouchEventData;
253
254 touch_cancel => EventName::TouchCancel;
256 touch_start => EventName::TouchStart;
258 touch_move => EventName::TouchMove;
260 touch_end => EventName::TouchEnd;
262 }
263
264 event_handlers! {
265 Pointer,
266 PointerEventData;
267
268 pointer_press => EventName::PointerPress;
270 pointer_down => EventName::PointerDown;
272 pointer_move => EventName::PointerMove;
274 pointer_enter => EventName::PointerEnter;
276 pointer_leave => EventName::PointerLeave;
278 pointer_over => EventName::PointerOver;
280 pointer_out => EventName::PointerOut;
282 }
283
284 event_handlers! {
285 File,
286 FileEventData;
287
288 file_drop => EventName::FileDrop;
290 global_file_hover => EventName::GlobalFileHover;
292 global_file_hover_cancelled => EventName::GlobalFileHoverCancelled;
294 }
295
296 event_handlers! {
297 ImePreedit,
298 ImePreeditEventData;
299
300 ime_preedit => EventName::ImePreedit;
302 }
303
304 fn on_sized(mut self, on_sized: impl Into<EventHandler<Event<SizedEventData>>>) -> Self
306 where
307 Self: LayoutExt,
308 {
309 self.get_event_handlers()
310 .insert(EventName::Sized, EventHandlerType::Sized(on_sized.into()));
311 self.get_layout().layout.has_layout_references = true;
312 self
313 }
314
315 fn on_visible(mut self, on_visible: impl Into<EventHandler<Event<VisibleEventData>>>) -> Self {
317 self.get_event_handlers().insert(
318 EventName::Visible,
319 EventHandlerType::Visible(on_visible.into()),
320 );
321 self
322 }
323
324 fn on_hidden(mut self, on_hidden: impl Into<EventHandler<Event<VisibleEventData>>>) -> Self {
326 self.get_event_handlers().insert(
327 EventName::Hidden,
328 EventHandlerType::Visible(on_hidden.into()),
329 );
330 self
331 }
332
333 fn on_styled(mut self, on_styled: impl Into<EventHandler<Event<StyledEventData>>>) -> Self {
335 self.get_event_handlers().insert(
336 EventName::Styled,
337 EventHandlerType::Styled(on_styled.into()),
338 );
339 self
340 }
341
342 fn on_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
349 let on_press = on_press.into();
350 self.on_pointer_press({
351 let on_press = on_press.clone();
352 move |e: Event<PointerEventData>| {
353 let event = e.try_map(|d| match d {
354 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
355 Some(PressEventData::Mouse(m))
356 }
357 PointerEventData::Touch(t) => Some(PressEventData::Touch(t)),
358 _ => None,
359 });
360 if let Some(event) = event {
361 on_press.call(event);
362 }
363 }
364 })
365 .on_key_down(move |e: Event<KeyboardEventData>| {
366 if e.is_press_event() {
367 on_press.call(e.map(PressEventData::Keyboard))
368 }
369 })
370 }
371
372 fn on_secondary_down(
376 self,
377 on_secondary_down: impl Into<EventHandler<Event<PressEventData>>>,
378 ) -> Self {
379 let on_secondary_down = on_secondary_down.into();
380 self.on_pointer_down(move |e: Event<PointerEventData>| {
381 let event = e.try_map(|d| match d {
382 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Right) => {
383 Some(PressEventData::Mouse(m))
384 }
385 _ => None,
386 });
387 if let Some(event) = event {
388 on_secondary_down.call(event);
389 }
390 })
391 }
392
393 fn on_all_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
398 let on_press = on_press.into();
399 self.on_pointer_press({
400 let on_press = on_press.clone();
401 move |e: Event<PointerEventData>| {
402 let event = e.map(|d| match d {
403 PointerEventData::Mouse(m) => PressEventData::Mouse(m),
404 PointerEventData::Touch(t) => PressEventData::Touch(t),
405 });
406 on_press.call(event);
407 }
408 })
409 .on_key_down(move |e: Event<KeyboardEventData>| {
410 if e.is_press_event() {
411 on_press.call(e.map(PressEventData::Keyboard))
412 }
413 })
414 }
415 fn on_focus_press(
421 self,
422 on_focus_press: impl Into<EventHandler<Event<FocusPressEventData>>>,
423 ) -> Self {
424 let on_focus_press = on_focus_press.into();
425 if cfg!(target_os = "android") {
426 self.on_pointer_press(move |e: Event<PointerEventData>| {
427 let event = e.try_map(|d| match d {
428 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
429 Some(FocusPressEventData::Mouse(m))
430 }
431 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
432 _ => None,
433 });
434 if let Some(event) = event {
435 on_focus_press.call(event);
436 }
437 })
438 } else {
439 self.on_pointer_down(move |e: Event<PointerEventData>| {
440 let event = e.try_map(|d| match d {
441 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
442 Some(FocusPressEventData::Mouse(m))
443 }
444 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
445 _ => None,
446 });
447 if let Some(event) = event {
448 on_focus_press.call(event);
449 }
450 })
451 }
452 }
453}
454
455#[derive(Debug, Clone, PartialEq)]
457pub enum FocusPressEventData {
458 Mouse(MouseEventData),
459 Touch(TouchEventData),
460}
461
462impl FocusPressEventData {
463 pub fn global_location(&self) -> CursorPoint {
464 match self {
465 Self::Mouse(m) => m.global_location,
466 Self::Touch(t) => t.global_location,
467 }
468 }
469
470 pub fn element_location(&self) -> CursorPoint {
471 match self {
472 Self::Mouse(m) => m.element_location,
473 Self::Touch(t) => t.element_location,
474 }
475 }
476
477 pub fn button(&self) -> Option<MouseButton> {
478 match self {
479 Self::Mouse(m) => m.button,
480 Self::Touch(_) => None,
481 }
482 }
483}
484
485#[derive(Debug, Clone, PartialEq)]
487pub enum PressEventData {
488 Mouse(MouseEventData),
489 Keyboard(KeyboardEventData),
490 Touch(TouchEventData),
491}
492
493pub trait ContainerWithContentExt
495where
496 Self: LayoutExt,
497{
498 fn direction(mut self, direction: Direction) -> Self {
500 self.get_layout().layout.direction = direction;
501 self
502 }
503 fn main_align(mut self, main_align: impl Into<Alignment>) -> Self {
505 self.get_layout().layout.main_alignment = main_align.into();
506 self
507 }
508
509 fn cross_align(mut self, cross_align: impl Into<Alignment>) -> Self {
511 self.get_layout().layout.cross_alignment = cross_align.into();
512 self
513 }
514
515 fn spacing(mut self, spacing: f32) -> Self {
517 self.get_layout().layout.spacing = Length::new(spacing);
518 self
519 }
520
521 fn content(mut self, content: Content) -> Self {
523 self.get_layout().layout.content = content;
524 self
525 }
526 fn center(mut self) -> Self {
528 self.get_layout().layout.main_alignment = Alignment::Center;
529 self.get_layout().layout.cross_alignment = Alignment::Center;
530
531 self
532 }
533
534 fn offset_x(mut self, offset_x: f32) -> Self {
536 self.get_layout().layout.offset_x = Length::new(offset_x);
537 self
538 }
539
540 fn offset_y(mut self, offset_y: f32) -> Self {
542 self.get_layout().layout.offset_y = Length::new(offset_y);
543 self
544 }
545
546 fn vertical(mut self) -> Self {
548 self.get_layout().layout.direction = Direction::vertical();
549 self
550 }
551
552 fn horizontal(mut self) -> Self {
554 self.get_layout().layout.direction = Direction::horizontal();
555 self
556 }
557}
558
559pub trait ContainerSizeExt
561where
562 Self: LayoutExt,
563{
564 fn width(mut self, width: impl Into<Size>) -> Self {
566 self.get_layout().layout.width = width.into();
567 self
568 }
569
570 fn height(mut self, height: impl Into<Size>) -> Self {
572 self.get_layout().layout.height = height.into();
573 self
574 }
575
576 fn expanded(mut self) -> Self {
578 self.get_layout().layout.width = Size::fill();
579 self.get_layout().layout.height = Size::fill();
580 self
581 }
582}
583
584impl<T: ContainerExt> ContainerSizeExt for T {}
585
586pub trait ContainerPositionExt
588where
589 Self: LayoutExt,
590{
591 fn position(mut self, position: impl Into<Position>) -> Self {
593 self.get_layout().layout.position = position.into();
594 self
595 }
596
597 fn margin(mut self, margin: impl Into<Gaps>) -> Self {
599 self.get_layout().layout.margin = margin.into();
600 self
601 }
602}
603
604impl<T: ContainerExt> ContainerPositionExt for T {}
605
606pub trait ContainerExt
608where
609 Self: LayoutExt,
610{
611 fn padding(mut self, padding: impl Into<Gaps>) -> Self {
613 self.get_layout().layout.padding = padding.into();
614 self
615 }
616}
617
618pub trait ContainerConstraintsExt
620where
621 Self: LayoutExt,
622{
623 fn min_width(mut self, minimum_width: impl Into<Size>) -> Self {
625 self.get_layout().layout.minimum_width = minimum_width.into();
626 self
627 }
628
629 fn min_height(mut self, minimum_height: impl Into<Size>) -> Self {
631 self.get_layout().layout.minimum_height = minimum_height.into();
632 self
633 }
634
635 fn max_width(mut self, maximum_width: impl Into<Size>) -> Self {
637 self.get_layout().layout.maximum_width = maximum_width.into();
638 self
639 }
640
641 fn max_height(mut self, maximum_height: impl Into<Size>) -> Self {
643 self.get_layout().layout.maximum_height = maximum_height.into();
644 self
645 }
646
647 fn visible_width(mut self, visible_width: impl Into<VisibleSize>) -> Self {
649 self.get_layout().layout.visible_width = visible_width.into();
650 self
651 }
652
653 fn visible_height(mut self, visible_height: impl Into<VisibleSize>) -> Self {
655 self.get_layout().layout.visible_height = visible_height.into();
656 self
657 }
658}
659
660impl<T: ContainerExt> ContainerConstraintsExt for T {}
661
662pub trait LayoutExt
664where
665 Self: Sized,
666{
667 fn get_layout(&mut self) -> &mut LayoutData;
669
670 fn layout(mut self, layout: LayoutData) -> Self {
672 *self.get_layout() = layout;
673 self
674 }
675}
676
677pub trait ImageExt
679where
680 Self: LayoutExt,
681{
682 fn get_image_data(&mut self) -> &mut ImageData;
684
685 fn image_data(mut self, image_data: ImageData) -> Self {
687 *self.get_image_data() = image_data;
688 self
689 }
690
691 fn sampling_mode(mut self, sampling_mode: SamplingMode) -> Self {
693 self.get_image_data().sampling_mode = sampling_mode;
694 self
695 }
696
697 fn aspect_ratio(mut self, aspect_ratio: AspectRatio) -> Self {
699 self.get_image_data().aspect_ratio = aspect_ratio;
700 self
701 }
702
703 fn image_cover(mut self, image_cover: ImageCover) -> Self {
705 self.get_image_data().image_cover = image_cover;
706 self
707 }
708
709 fn snap_to_grid(mut self, snap_to_grid: bool) -> Self {
711 self.get_image_data().snap_to_grid = snap_to_grid;
712 self
713 }
714}
715
716pub trait AccessibilityExt: Sized {
718 fn get_accessibility_data(&mut self) -> &mut AccessibilityData;
720
721 fn accessibility(mut self, accessibility: AccessibilityData) -> Self {
723 *self.get_accessibility_data() = accessibility;
724 self
725 }
726
727 fn a11y_id(mut self, a11y_id: impl Into<Option<AccessibilityId>>) -> Self {
729 self.get_accessibility_data().a11y_id = a11y_id.into();
730 self
731 }
732
733 fn a11y_focusable(mut self, a11y_focusable: impl Into<Focusable>) -> Self {
735 self.get_accessibility_data().a11y_focusable = a11y_focusable.into();
736 self
737 }
738
739 fn a11y_auto_focus(mut self, a11y_auto_focus: impl Into<bool>) -> Self {
741 self.get_accessibility_data().a11y_auto_focus = a11y_auto_focus.into();
742 self
743 }
744
745 fn a11y_member_of(mut self, a11y_member_of: impl Into<AccessibilityId>) -> Self {
747 self.get_accessibility_data()
748 .builder
749 .set_member_of(a11y_member_of.into());
750 self
751 }
752
753 fn a11y_role(mut self, a11y_role: impl Into<AccessibilityRole>) -> Self {
755 self.get_accessibility_data()
756 .builder
757 .set_role(a11y_role.into());
758 self
759 }
760
761 fn a11y_alt(mut self, value: impl Into<Box<str>>) -> Self {
763 self.get_accessibility_data().builder.set_label(value);
764 self
765 }
766
767 fn a11y_builder(mut self, with: impl FnOnce(&mut accesskit::Node)) -> Self {
769 with(&mut self.get_accessibility_data().builder);
770 self
771 }
772}
773
774pub trait TextStyleExt
776where
777 Self: Sized,
778{
779 fn get_text_style_data(&mut self) -> &mut TextStyleData;
781
782 fn text_style(mut self, data: TextStyleData) -> Self {
784 *self.get_text_style_data() = data;
785 self
786 }
787
788 fn color(mut self, color: impl Into<Fill>) -> Self {
790 self.get_text_style_data().color = Some(color.into());
791 self
792 }
793
794 fn text_align(mut self, text_align: impl Into<TextAlign>) -> Self {
796 self.get_text_style_data().text_align = Some(text_align.into());
797 self
798 }
799
800 fn font_size(mut self, font_size: impl Into<FontSize>) -> Self {
802 self.get_text_style_data().font_size = Some(font_size.into());
803 self
804 }
805
806 fn letter_spacing(mut self, letter_spacing: impl Into<LetterSpacing>) -> Self {
808 self.get_text_style_data().letter_spacing = Some(letter_spacing.into());
809 self
810 }
811
812 fn font_feature(mut self, font_feature: impl Into<FontFeature>) -> Self {
814 self.get_text_style_data()
815 .font_features
816 .push(font_feature.into());
817 self
818 }
819
820 fn font_tabular(self) -> Self {
822 self.font_feature(FontFeature::TABULAR_NUMBERS)
823 }
824
825 fn font_small_caps(self) -> Self {
827 self.font_feature(FontFeature::SMALL_CAPS)
828 }
829
830 fn font_slashed_zero(self) -> Self {
832 self.font_feature(FontFeature::SLASHED_ZERO)
833 }
834
835 fn font_fractions(self) -> Self {
837 self.font_feature(FontFeature::FRACTIONS)
838 }
839
840 fn font_no_ligatures(self) -> Self {
842 self.font_feature(FontFeature::NO_LIGATURES)
843 }
844
845 fn font_family(mut self, font_family: impl Into<Cow<'static, str>>) -> Self {
847 self.get_text_style_data()
848 .font_families
849 .push(font_family.into());
850 self
851 }
852
853 fn font_slant(mut self, font_slant: impl Into<FontSlant>) -> Self {
855 self.get_text_style_data().font_slant = Some(font_slant.into());
856 self
857 }
858
859 fn font_weight(mut self, font_weight: impl Into<FontWeight>) -> Self {
861 self.get_text_style_data().font_weight = Some(font_weight.into());
862 self
863 }
864
865 fn font_width(mut self, font_width: impl Into<FontWidth>) -> Self {
867 self.get_text_style_data().font_width = Some(font_width.into());
868 self
869 }
870
871 fn text_height(mut self, text_height: impl Into<TextHeightBehavior>) -> Self {
873 self.get_text_style_data().text_height = Some(text_height.into());
874 self
875 }
876
877 fn text_overflow(mut self, text_overflow: impl Into<TextOverflow>) -> Self {
879 self.get_text_style_data().text_overflow = Some(text_overflow.into());
880 self
881 }
882
883 fn text_shadow(mut self, text_shadow: impl Into<TextShadow>) -> Self {
885 self.get_text_style_data()
886 .text_shadows
887 .push(text_shadow.into());
888 self
889 }
890
891 fn text_decoration(mut self, text_decoration: impl Into<TextDecoration>) -> Self {
893 self.get_text_style_data().text_decoration = Some(text_decoration.into());
894 self
895 }
896}
897
898pub trait StyleExt
900where
901 Self: Sized,
902{
903 fn get_style(&mut self) -> &mut StyleState;
905
906 fn style(mut self, style: StyleState) -> Self {
908 *self.get_style() = style;
909 self
910 }
911
912 fn background(mut self, background: impl Into<Fill>) -> Self {
914 self.get_style().background = background.into();
915 self
916 }
917
918 fn border(mut self, border: impl Into<Option<Border>>) -> Self {
920 if let Some(border) = border.into() {
921 self.get_style().borders.push(border);
922 }
923 self
924 }
925
926 fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
928 self.get_style().shadows.push(shadow.into());
929 self
930 }
931
932 fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
934 self.get_style().corner_radius = corner_radius.into();
935 self
936 }
937
938 fn cursor(mut self, cursor: impl Into<Option<CursorIcon>>) -> Self {
943 self.get_style().cursor = cursor.into();
944 self
945 }
946}
947
948impl<T: StyleExt> CornerRadiusExt for T {
949 fn with_corner_radius(mut self, corner_radius: f32) -> Self {
950 self.get_style().corner_radius = CornerRadius::new_all(corner_radius);
951 self
952 }
953}
954
955pub trait CornerRadiusExt: Sized {
957 fn with_corner_radius(self, corner_radius: f32) -> Self;
959
960 fn rounded_none(self) -> Self {
962 self.with_corner_radius(0.)
963 }
964
965 fn rounded(self) -> Self {
967 self.with_corner_radius(6.)
968 }
969
970 fn rounded_sm(self) -> Self {
972 self.with_corner_radius(4.)
973 }
974
975 fn rounded_md(self) -> Self {
977 self.with_corner_radius(6.)
978 }
979
980 fn rounded_lg(self) -> Self {
982 self.with_corner_radius(8.)
983 }
984
985 fn rounded_xl(self) -> Self {
987 self.with_corner_radius(12.)
988 }
989
990 fn rounded_2xl(self) -> Self {
992 self.with_corner_radius(16.)
993 }
994
995 fn rounded_3xl(self) -> Self {
997 self.with_corner_radius(24.)
998 }
999
1000 fn rounded_4xl(self) -> Self {
1002 self.with_corner_radius(32.)
1003 }
1004
1005 fn rounded_full(self) -> Self {
1007 self.with_corner_radius(99.)
1008 }
1009}
1010
1011pub trait MaybeExt
1013where
1014 Self: Sized,
1015{
1016 fn maybe(self, bool: impl Into<bool>, then: impl FnOnce(Self) -> Self) -> Self {
1018 if bool.into() { then(self) } else { self }
1019 }
1020
1021 fn map<T>(self, data: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self {
1023 if let Some(data) = data {
1024 then(self, data)
1025 } else {
1026 self
1027 }
1028 }
1029}
1030
1031pub trait LayerExt
1033where
1034 Self: Sized,
1035{
1036 fn get_layer(&mut self) -> &mut Layer;
1038
1039 fn layer(mut self, layer: impl Into<Layer>) -> Self {
1041 *self.get_layer() = layer.into();
1042 self
1043 }
1044}
1045
1046pub trait ScrollableExt
1047where
1048 Self: Sized,
1049{
1050 fn get_effect(&mut self) -> &mut EffectData;
1052
1053 fn scrollable(mut self, scrollable: impl Into<bool>) -> Self {
1056 self.get_effect().scrollable = scrollable.into();
1057 self
1058 }
1059}
1060
1061pub trait InteractiveExt
1063where
1064 Self: Sized,
1065{
1066 fn get_effect(&mut self) -> &mut EffectData;
1068
1069 fn interactive(mut self, interactive: impl Into<Interactive>) -> Self {
1071 self.get_effect().interactive = interactive.into();
1072 self
1073 }
1074}
1075
1076pub trait EffectExt: Sized {
1078 fn get_effect(&mut self) -> &mut EffectData;
1080
1081 fn effect(mut self, effect: EffectData) -> Self {
1083 *self.get_effect() = effect;
1084 self
1085 }
1086
1087 fn overflow(mut self, overflow: impl Into<Overflow>) -> Self {
1089 self.get_effect().overflow = overflow.into();
1090 self
1091 }
1092
1093 fn blur(mut self, blur: f32) -> Self {
1095 self.get_effect().blur = Some(blur);
1096 self
1097 }
1098
1099 fn rotation(mut self, rotation: f32) -> Self {
1101 self.get_effect().rotation = Some(rotation);
1102 self
1103 }
1104
1105 fn opacity(mut self, opacity: f32) -> Self {
1107 self.get_effect().opacity = Some(opacity);
1108 self
1109 }
1110
1111 fn scale(mut self, scale: impl Into<Scale>) -> Self {
1113 self.get_effect().scale = Some(scale.into());
1114 self
1115 }
1116
1117 fn transform_origin(mut self, transform_origin: impl Into<TransformOrigin>) -> Self {
1121 self.get_effect().transform_origin = transform_origin.into();
1122 self
1123 }
1124}