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::{
40 image::{
41 AspectRatio,
42 Image,
43 ImageCover,
44 ImageData,
45 SamplingMode,
46 },
47 label::Label,
48 paragraph::Paragraph,
49 rect::Rect,
50 },
51 event_handler::EventHandler,
52 events::{
53 data::{
54 Event,
55 KeyboardEventData,
56 MouseEventData,
57 SizedEventData,
58 StyledEventData,
59 VisibleEventData,
60 WheelEventData,
61 },
62 name::EventName,
63 },
64 layers::Layer,
65 prelude::*,
66 style::{
67 font_feature::FontFeature,
68 font_size::FontSize,
69 font_slant::FontSlant,
70 font_weight::FontWeight,
71 font_width::FontWidth,
72 letter_spacing::LetterSpacing,
73 scale::Scale,
74 text_height::TextHeightBehavior,
75 text_overflow::TextOverflow,
76 text_shadow::TextShadow,
77 transform_origin::TransformOrigin,
78 },
79};
80
81pub trait ChildrenExt: Sized {
83 fn get_children(&mut self) -> &mut Vec<Element>;
94
95 fn children(mut self, children: impl IntoIterator<Item = impl IntoElement>) -> Self {
102 self.get_children()
103 .extend(children.into_iter().map(IntoElement::into_element));
104 self
105 }
106
107 fn maybe_child<C: IntoElement>(mut self, child: Option<C>) -> Self {
114 if let Some(child) = child {
115 self.get_children().push(child.into_element());
116 }
117 self
118 }
119
120 fn child<C: IntoElement>(mut self, child: C) -> Self {
127 self.get_children().push(child.into_element());
128 self
129 }
130}
131
132pub trait KeyExt: Sized {
134 fn write_key(&mut self) -> &mut DiffKey;
136
137 fn key(mut self, key: impl Hash) -> Self
141 where
142 Self: 'static,
143 {
144 let mut hasher = FxHasher::default();
145 std::any::TypeId::of::<Self>().hash(&mut hasher);
146 key.hash(&mut hasher);
147 *self.write_key() = DiffKey::U64(hasher.finish());
148 self
149 }
150}
151
152pub trait WithExt: Sized {
154 fn with(self, with: impl FnOnce(Self) -> Self) -> Self {
156 with(self)
157 }
158}
159
160impl WithExt for Rect {}
161impl WithExt for Label {}
162impl WithExt for Paragraph {}
163impl WithExt for Image {}
164
165macro_rules! event_handlers {
166 (
167 $handler_variant:ident, $event_data:ty;
168 $(
169 $(#[$attr:meta])*
170 $name:ident => $event_variant:expr ;
171 )*
172 ) => {
173 paste! {
174 $(
175 $(#[$attr])*
176 fn [<on_$name>](mut self, [<on_$name>]: impl Into<EventHandler<Event<$event_data>>>) -> Self {
177 self.get_event_handlers()
178 .insert($event_variant, EventHandlerType::$handler_variant([<on_$name>].into()));
179 self
180 }
181 )*
182 }
183 };
184}
185
186pub trait EventHandlersExt: Sized {
194 fn get_event_handlers(&mut self) -> &mut EventHandlers;
196
197 fn event_handlers(mut self, event_handlers: EventHandlers) -> Self {
199 *self.get_event_handlers() = event_handlers;
200 self
201 }
202
203 event_handlers! {
204 Mouse,
205 MouseEventData;
206
207 mouse_down => EventName::MouseDown;
209 mouse_up => EventName::MouseUp;
211 mouse_move => EventName::MouseMove;
213
214 }
215
216 event_handlers! {
217 Pointer,
218 PointerEventData;
219
220 global_pointer_up => EventName::GlobalPointerUp;
222 global_pointer_down => EventName::GlobalPointerDown;
224 global_pointer_move => EventName::GlobalPointerMove;
226
227 capture_global_pointer_move => EventName::CaptureGlobalPointerMove;
229 capture_global_pointer_up => EventName::CaptureGlobalPointerUp;
231 }
232
233 event_handlers! {
234 Keyboard,
235 KeyboardEventData;
236
237 key_down => EventName::KeyDown;
239 key_up => EventName::KeyUp;
241
242 global_key_down => EventName::GlobalKeyDown;
244 global_key_up => EventName::GlobalKeyUp;
246 }
247
248 event_handlers! {
249 Wheel,
250 WheelEventData;
251
252 wheel => EventName::Wheel;
254 }
255
256 event_handlers! {
257 Touch,
258 TouchEventData;
259
260 touch_cancel => EventName::TouchCancel;
262 touch_start => EventName::TouchStart;
264 touch_move => EventName::TouchMove;
266 touch_end => EventName::TouchEnd;
268 }
269
270 event_handlers! {
271 Pointer,
272 PointerEventData;
273
274 pointer_press => EventName::PointerPress;
276 pointer_down => EventName::PointerDown;
278 pointer_move => EventName::PointerMove;
280 pointer_enter => EventName::PointerEnter;
282 pointer_leave => EventName::PointerLeave;
284 pointer_over => EventName::PointerOver;
286 pointer_out => EventName::PointerOut;
288 }
289
290 event_handlers! {
291 File,
292 FileEventData;
293
294 file_drop => EventName::FileDrop;
296 global_file_hover => EventName::GlobalFileHover;
298 global_file_hover_cancelled => EventName::GlobalFileHoverCancelled;
300 }
301
302 event_handlers! {
303 ImePreedit,
304 ImePreeditEventData;
305
306 ime_preedit => EventName::ImePreedit;
308 }
309
310 fn on_sized(mut self, on_sized: impl Into<EventHandler<Event<SizedEventData>>>) -> Self
312 where
313 Self: LayoutExt,
314 {
315 self.get_event_handlers()
316 .insert(EventName::Sized, EventHandlerType::Sized(on_sized.into()));
317 self.get_layout().layout.has_layout_references = true;
318 self
319 }
320
321 fn on_visible(mut self, on_visible: impl Into<EventHandler<Event<VisibleEventData>>>) -> Self {
323 self.get_event_handlers().insert(
324 EventName::Visible,
325 EventHandlerType::Visible(on_visible.into()),
326 );
327 self
328 }
329
330 fn on_hidden(mut self, on_hidden: impl Into<EventHandler<Event<VisibleEventData>>>) -> Self {
332 self.get_event_handlers().insert(
333 EventName::Hidden,
334 EventHandlerType::Visible(on_hidden.into()),
335 );
336 self
337 }
338
339 fn on_styled(mut self, on_styled: impl Into<EventHandler<Event<StyledEventData>>>) -> Self {
341 self.get_event_handlers().insert(
342 EventName::Styled,
343 EventHandlerType::Styled(on_styled.into()),
344 );
345 self
346 }
347
348 fn on_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
355 let on_press = on_press.into();
356 self.on_pointer_press({
357 let on_press = on_press.clone();
358 move |e: Event<PointerEventData>| {
359 let event = e.try_map(|d| match d {
360 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
361 Some(PressEventData::Mouse(m))
362 }
363 PointerEventData::Touch(t) => Some(PressEventData::Touch(t)),
364 _ => None,
365 });
366 if let Some(event) = event {
367 on_press.call(event);
368 }
369 }
370 })
371 .on_key_down(move |e: Event<KeyboardEventData>| {
372 if e.is_press_event() {
373 on_press.call(e.map(PressEventData::Keyboard))
374 }
375 })
376 }
377
378 fn on_secondary_down(
382 self,
383 on_secondary_down: impl Into<EventHandler<Event<PressEventData>>>,
384 ) -> Self {
385 let on_secondary_down = on_secondary_down.into();
386 self.on_pointer_down(move |e: Event<PointerEventData>| {
387 let event = e.try_map(|d| match d {
388 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Right) => {
389 Some(PressEventData::Mouse(m))
390 }
391 _ => None,
392 });
393 if let Some(event) = event {
394 on_secondary_down.call(event);
395 }
396 })
397 }
398
399 fn on_all_press(self, on_press: impl Into<EventHandler<Event<PressEventData>>>) -> Self {
404 let on_press = on_press.into();
405 self.on_pointer_press({
406 let on_press = on_press.clone();
407 move |e: Event<PointerEventData>| {
408 let event = e.map(|d| match d {
409 PointerEventData::Mouse(m) => PressEventData::Mouse(m),
410 PointerEventData::Touch(t) => PressEventData::Touch(t),
411 });
412 on_press.call(event);
413 }
414 })
415 .on_key_down(move |e: Event<KeyboardEventData>| {
416 if e.is_press_event() {
417 on_press.call(e.map(PressEventData::Keyboard))
418 }
419 })
420 }
421 fn on_focus_press(
427 self,
428 on_focus_press: impl Into<EventHandler<Event<FocusPressEventData>>>,
429 ) -> Self {
430 let on_focus_press = on_focus_press.into();
431 if cfg!(target_os = "android") {
432 self.on_pointer_press(move |e: Event<PointerEventData>| {
433 let event = e.try_map(|d| match d {
434 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
435 Some(FocusPressEventData::Mouse(m))
436 }
437 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
438 _ => None,
439 });
440 if let Some(event) = event {
441 on_focus_press.call(event);
442 }
443 })
444 } else {
445 self.on_pointer_down(move |e: Event<PointerEventData>| {
446 let event = e.try_map(|d| match d {
447 PointerEventData::Mouse(m) if m.button == Some(MouseButton::Left) => {
448 Some(FocusPressEventData::Mouse(m))
449 }
450 PointerEventData::Touch(t) => Some(FocusPressEventData::Touch(t)),
451 _ => None,
452 });
453 if let Some(event) = event {
454 on_focus_press.call(event);
455 }
456 })
457 }
458 }
459}
460
461#[derive(Debug, Clone, PartialEq)]
463pub enum FocusPressEventData {
464 Mouse(MouseEventData),
465 Touch(TouchEventData),
466}
467
468impl FocusPressEventData {
469 pub fn global_location(&self) -> CursorPoint {
470 match self {
471 Self::Mouse(m) => m.global_location,
472 Self::Touch(t) => t.global_location,
473 }
474 }
475
476 pub fn element_location(&self) -> CursorPoint {
477 match self {
478 Self::Mouse(m) => m.element_location,
479 Self::Touch(t) => t.element_location,
480 }
481 }
482
483 pub fn button(&self) -> Option<MouseButton> {
484 match self {
485 Self::Mouse(m) => m.button,
486 Self::Touch(_) => None,
487 }
488 }
489}
490
491#[derive(Debug, Clone, PartialEq)]
493pub enum PressEventData {
494 Mouse(MouseEventData),
495 Keyboard(KeyboardEventData),
496 Touch(TouchEventData),
497}
498
499pub trait ContainerWithContentExt
501where
502 Self: LayoutExt,
503{
504 fn direction(mut self, direction: Direction) -> Self {
506 self.get_layout().layout.direction = direction;
507 self
508 }
509 fn main_align(mut self, main_align: impl Into<Alignment>) -> Self {
511 self.get_layout().layout.main_alignment = main_align.into();
512 self
513 }
514
515 fn cross_align(mut self, cross_align: impl Into<Alignment>) -> Self {
517 self.get_layout().layout.cross_alignment = cross_align.into();
518 self
519 }
520
521 fn spacing(mut self, spacing: f32) -> Self {
523 self.get_layout().layout.spacing = Length::new(spacing);
524 self
525 }
526
527 fn content(mut self, content: Content) -> Self {
529 self.get_layout().layout.content = content;
530 self
531 }
532 fn center(mut self) -> Self {
534 self.get_layout().layout.main_alignment = Alignment::Center;
535 self.get_layout().layout.cross_alignment = Alignment::Center;
536
537 self
538 }
539
540 fn offset_x(mut self, offset_x: f32) -> Self {
542 self.get_layout().layout.offset_x = Length::new(offset_x);
543 self
544 }
545
546 fn offset_y(mut self, offset_y: f32) -> Self {
548 self.get_layout().layout.offset_y = Length::new(offset_y);
549 self
550 }
551
552 fn vertical(mut self) -> Self {
554 self.get_layout().layout.direction = Direction::vertical();
555 self
556 }
557
558 fn horizontal(mut self) -> Self {
560 self.get_layout().layout.direction = Direction::horizontal();
561 self
562 }
563}
564
565pub trait ContainerSizeExt
567where
568 Self: LayoutExt,
569{
570 fn width(mut self, width: impl Into<Size>) -> Self {
572 self.get_layout().layout.width = width.into();
573 self
574 }
575
576 fn height(mut self, height: impl Into<Size>) -> Self {
578 self.get_layout().layout.height = height.into();
579 self
580 }
581
582 fn expanded(mut self) -> Self {
584 self.get_layout().layout.width = Size::fill();
585 self.get_layout().layout.height = Size::fill();
586 self
587 }
588}
589
590impl<T: ContainerExt> ContainerSizeExt for T {}
591
592pub trait ContainerPositionExt
594where
595 Self: LayoutExt,
596{
597 fn position(mut self, position: impl Into<Position>) -> Self {
599 self.get_layout().layout.position = position.into();
600 self
601 }
602
603 fn margin(mut self, margin: impl Into<Gaps>) -> Self {
605 self.get_layout().layout.margin = margin.into();
606 self
607 }
608}
609
610impl<T: ContainerExt> ContainerPositionExt for T {}
611
612pub trait ContainerExt
614where
615 Self: LayoutExt,
616{
617 fn padding(mut self, padding: impl Into<Gaps>) -> Self {
619 self.get_layout().layout.padding = padding.into();
620 self
621 }
622}
623
624pub trait ContainerConstraintsExt
626where
627 Self: LayoutExt,
628{
629 fn min_width(mut self, minimum_width: impl Into<Size>) -> Self {
631 self.get_layout().layout.minimum_width = minimum_width.into();
632 self
633 }
634
635 fn min_height(mut self, minimum_height: impl Into<Size>) -> Self {
637 self.get_layout().layout.minimum_height = minimum_height.into();
638 self
639 }
640
641 fn max_width(mut self, maximum_width: impl Into<Size>) -> Self {
643 self.get_layout().layout.maximum_width = maximum_width.into();
644 self
645 }
646
647 fn max_height(mut self, maximum_height: impl Into<Size>) -> Self {
649 self.get_layout().layout.maximum_height = maximum_height.into();
650 self
651 }
652
653 fn visible_width(mut self, visible_width: impl Into<VisibleSize>) -> Self {
655 self.get_layout().layout.visible_width = visible_width.into();
656 self
657 }
658
659 fn visible_height(mut self, visible_height: impl Into<VisibleSize>) -> Self {
661 self.get_layout().layout.visible_height = visible_height.into();
662 self
663 }
664}
665
666impl<T: ContainerExt> ContainerConstraintsExt for T {}
667
668pub trait LayoutExt
670where
671 Self: Sized,
672{
673 fn get_layout(&mut self) -> &mut LayoutData;
675
676 fn layout(mut self, layout: LayoutData) -> Self {
678 *self.get_layout() = layout;
679 self
680 }
681}
682
683pub trait ImageExt
685where
686 Self: LayoutExt,
687{
688 fn get_image_data(&mut self) -> &mut ImageData;
690
691 fn image_data(mut self, image_data: ImageData) -> Self {
693 *self.get_image_data() = image_data;
694 self
695 }
696
697 fn sampling_mode(mut self, sampling_mode: SamplingMode) -> Self {
699 self.get_image_data().sampling_mode = sampling_mode;
700 self
701 }
702
703 fn aspect_ratio(mut self, aspect_ratio: AspectRatio) -> Self {
705 self.get_image_data().aspect_ratio = aspect_ratio;
706 self
707 }
708
709 fn image_cover(mut self, image_cover: ImageCover) -> Self {
711 self.get_image_data().image_cover = image_cover;
712 self
713 }
714
715 fn snap_to_grid(mut self, snap_to_grid: bool) -> Self {
717 self.get_image_data().snap_to_grid = snap_to_grid;
718 self
719 }
720
721 fn blur(mut self, blur: f32) -> Self {
723 self.get_image_data().blur = blur;
724 self
725 }
726}
727
728pub trait AccessibilityExt: Sized {
730 fn get_accessibility_data(&mut self) -> &mut AccessibilityData;
732
733 fn accessibility(mut self, accessibility: AccessibilityData) -> Self {
735 *self.get_accessibility_data() = accessibility;
736 self
737 }
738
739 fn a11y_id(mut self, a11y_id: impl Into<Option<AccessibilityId>>) -> Self {
741 self.get_accessibility_data().a11y_id = a11y_id.into();
742 self
743 }
744
745 fn a11y_focusable(mut self, a11y_focusable: impl Into<Focusable>) -> Self {
747 self.get_accessibility_data().a11y_focusable = a11y_focusable.into();
748 self
749 }
750
751 fn a11y_auto_focus(mut self, a11y_auto_focus: impl Into<bool>) -> Self {
753 self.get_accessibility_data().a11y_auto_focus = a11y_auto_focus.into();
754 self
755 }
756
757 fn a11y_member_of(mut self, a11y_member_of: impl Into<AccessibilityId>) -> Self {
759 self.get_accessibility_data()
760 .builder
761 .set_member_of(a11y_member_of.into());
762 self
763 }
764
765 fn a11y_role(mut self, a11y_role: impl Into<AccessibilityRole>) -> Self {
767 self.get_accessibility_data()
768 .builder
769 .set_role(a11y_role.into());
770 self
771 }
772
773 fn a11y_alt(mut self, value: impl Into<Box<str>>) -> Self {
775 self.get_accessibility_data().builder.set_label(value);
776 self
777 }
778
779 fn a11y_builder(mut self, with: impl FnOnce(&mut accesskit::Node)) -> Self {
781 with(&mut self.get_accessibility_data().builder);
782 self
783 }
784}
785
786pub trait TextStyleExt
788where
789 Self: Sized,
790{
791 fn get_text_style_data(&mut self) -> &mut TextStyleData;
793
794 fn text_style(mut self, data: TextStyleData) -> Self {
796 *self.get_text_style_data() = data;
797 self
798 }
799
800 fn color(mut self, color: impl Into<Fill>) -> Self {
802 self.get_text_style_data().color = Some(color.into());
803 self
804 }
805
806 fn text_align(mut self, text_align: impl Into<TextAlign>) -> Self {
808 self.get_text_style_data().text_align = Some(text_align.into());
809 self
810 }
811
812 fn font_size(mut self, font_size: impl Into<FontSize>) -> Self {
814 self.get_text_style_data().font_size = Some(font_size.into());
815 self
816 }
817
818 fn letter_spacing(mut self, letter_spacing: impl Into<LetterSpacing>) -> Self {
820 self.get_text_style_data().letter_spacing = Some(letter_spacing.into());
821 self
822 }
823
824 fn font_feature(mut self, font_feature: impl Into<FontFeature>) -> Self {
826 self.get_text_style_data()
827 .font_features
828 .push(font_feature.into());
829 self
830 }
831
832 fn font_tabular(self) -> Self {
834 self.font_feature(FontFeature::TABULAR_NUMBERS)
835 }
836
837 fn font_small_caps(self) -> Self {
839 self.font_feature(FontFeature::SMALL_CAPS)
840 }
841
842 fn font_slashed_zero(self) -> Self {
844 self.font_feature(FontFeature::SLASHED_ZERO)
845 }
846
847 fn font_fractions(self) -> Self {
849 self.font_feature(FontFeature::FRACTIONS)
850 }
851
852 fn font_no_ligatures(self) -> Self {
854 self.font_feature(FontFeature::NO_LIGATURES)
855 }
856
857 fn font_family(mut self, font_family: impl Into<Cow<'static, str>>) -> Self {
859 self.get_text_style_data()
860 .font_families
861 .push(font_family.into());
862 self
863 }
864
865 fn font_slant(mut self, font_slant: impl Into<FontSlant>) -> Self {
867 self.get_text_style_data().font_slant = Some(font_slant.into());
868 self
869 }
870
871 fn font_weight(mut self, font_weight: impl Into<FontWeight>) -> Self {
873 self.get_text_style_data().font_weight = Some(font_weight.into());
874 self
875 }
876
877 fn font_width(mut self, font_width: impl Into<FontWidth>) -> Self {
879 self.get_text_style_data().font_width = Some(font_width.into());
880 self
881 }
882
883 fn text_height(mut self, text_height: impl Into<TextHeightBehavior>) -> Self {
885 self.get_text_style_data().text_height = Some(text_height.into());
886 self
887 }
888
889 fn text_overflow(mut self, text_overflow: impl Into<TextOverflow>) -> Self {
891 self.get_text_style_data().text_overflow = Some(text_overflow.into());
892 self
893 }
894
895 fn text_shadow(mut self, text_shadow: impl Into<TextShadow>) -> Self {
897 self.get_text_style_data()
898 .text_shadows
899 .push(text_shadow.into());
900 self
901 }
902
903 fn text_decoration(mut self, text_decoration: impl Into<TextDecoration>) -> Self {
905 self.get_text_style_data().text_decoration = Some(text_decoration.into());
906 self
907 }
908}
909
910pub trait BackgroundExt: StyleExt {
912 fn background(mut self, background: impl Into<Fill>) -> Self {
914 self.get_style().background = background.into();
915 self
916 }
917}
918
919pub trait StyleExt
921where
922 Self: Sized,
923{
924 fn get_style(&mut self) -> &mut StyleState;
926
927 fn style(mut self, style: StyleState) -> Self {
929 *self.get_style() = style;
930 self
931 }
932}
933
934pub trait DecorationExt: StyleExt {
936 fn border(mut self, border: impl Into<Option<Border>>) -> Self {
938 if let Some(border) = border.into() {
939 self.get_style().borders.push(border);
940 }
941 self
942 }
943
944 fn shadow(mut self, shadow: impl Into<Shadow>) -> Self {
946 self.get_style().shadows.push(shadow.into());
947 self
948 }
949
950 fn corner_radius(mut self, corner_radius: impl Into<CornerRadius>) -> Self {
952 self.get_style().corner_radius = corner_radius.into();
953 self
954 }
955}
956
957impl<T: DecorationExt> CornerRadiusExt for T {
958 fn with_corner_radius(mut self, corner_radius: f32) -> Self {
959 self.get_style().corner_radius = CornerRadius::new_all(corner_radius);
960 self
961 }
962}
963
964pub trait CornerRadiusExt: Sized {
966 fn with_corner_radius(self, corner_radius: f32) -> Self;
968
969 fn rounded_none(self) -> Self {
971 self.with_corner_radius(0.)
972 }
973
974 fn rounded(self) -> Self {
976 self.with_corner_radius(6.)
977 }
978
979 fn rounded_sm(self) -> Self {
981 self.with_corner_radius(4.)
982 }
983
984 fn rounded_md(self) -> Self {
986 self.with_corner_radius(6.)
987 }
988
989 fn rounded_lg(self) -> Self {
991 self.with_corner_radius(8.)
992 }
993
994 fn rounded_xl(self) -> Self {
996 self.with_corner_radius(12.)
997 }
998
999 fn rounded_2xl(self) -> Self {
1001 self.with_corner_radius(16.)
1002 }
1003
1004 fn rounded_3xl(self) -> Self {
1006 self.with_corner_radius(24.)
1007 }
1008
1009 fn rounded_4xl(self) -> Self {
1011 self.with_corner_radius(32.)
1012 }
1013
1014 fn rounded_full(self) -> Self {
1016 self.with_corner_radius(99.)
1017 }
1018}
1019
1020pub trait MaybeExt
1022where
1023 Self: Sized,
1024{
1025 fn maybe(self, bool: impl Into<bool>, then: impl FnOnce(Self) -> Self) -> Self {
1027 if bool.into() { then(self) } else { self }
1028 }
1029
1030 fn map<T>(self, data: Option<T>, then: impl FnOnce(Self, T) -> Self) -> Self {
1032 if let Some(data) = data {
1033 then(self, data)
1034 } else {
1035 self
1036 }
1037 }
1038}
1039
1040pub trait LayerExt
1042where
1043 Self: Sized,
1044{
1045 fn get_layer(&mut self) -> &mut Layer;
1047
1048 fn layer(mut self, layer: impl Into<Layer>) -> Self {
1050 *self.get_layer() = layer.into();
1051 self
1052 }
1053}
1054
1055pub trait ScrollableExt
1056where
1057 Self: Sized,
1058{
1059 fn get_effect(&mut self) -> &mut EffectData;
1061
1062 fn scrollable(mut self, scrollable: impl Into<bool>) -> Self {
1065 self.get_effect().scrollable = scrollable.into();
1066 self
1067 }
1068}
1069
1070pub trait InteractiveExt
1072where
1073 Self: Sized,
1074{
1075 fn get_effect(&mut self) -> &mut EffectData;
1077
1078 fn interactive(mut self, interactive: impl Into<Interactive>) -> Self {
1080 self.get_effect().interactive = interactive.into();
1081 self
1082 }
1083}
1084
1085pub trait EffectExt: Sized {
1087 fn get_effect(&mut self) -> &mut EffectData;
1089
1090 fn cursor(mut self, cursor: impl Into<Option<CursorIcon>>) -> Self {
1095 self.get_effect().cursor = cursor.into();
1096 self
1097 }
1098
1099 fn effect(mut self, effect: EffectData) -> Self {
1101 *self.get_effect() = effect;
1102 self
1103 }
1104
1105 fn overflow(mut self, overflow: impl Into<Overflow>) -> Self {
1107 self.get_effect().overflow = overflow.into();
1108 self
1109 }
1110
1111 fn backdrop_blur(mut self, blur: f32) -> Self {
1113 self.get_effect().blur = Some(blur);
1114 self
1115 }
1116
1117 fn rotation(mut self, rotation: f32) -> Self {
1119 self.get_effect().rotation = Some(rotation);
1120 self
1121 }
1122
1123 fn opacity(mut self, opacity: f32) -> Self {
1125 self.get_effect().opacity = Some(opacity);
1126 self
1127 }
1128
1129 fn scale(mut self, scale: impl Into<Scale>) -> Self {
1131 self.get_effect().scale = Some(scale.into());
1132 self
1133 }
1134
1135 fn transform_origin(mut self, transform_origin: impl Into<TransformOrigin>) -> Self {
1139 self.get_effect().transform_origin = transform_origin.into();
1140 self
1141 }
1142}