ferroui_controls/notifications/
reversible_stack_panel.rs1use crate::{ControlImpl, PanelImpl, StackPanel, StackPanelImpl};
2use ferroui_base::input::InputElementImpl;
3use ferroui_base::interactivity::InteractiveImpl;
4use ferroui_base::layout::{
5 HorizontalAlignment, LayoutExtensions, Layoutable, LayoutableImpl, Orientation, VerticalAlignment,
6};
7use ferroui_base::{
8 ferro_class, ferro_impl_classes, ferro_property, instantiate, FerroObjectImpl, FerroProperty,
9 Rect, Ref, Size, StyledElementImpl, StyledProperty, VisualImpl,
10};
11
12#[repr(C)]
15pub struct ReversibleStackPanel {
16 base: StackPanel,
17}
18
19ferro_class!(ReversibleStackPanel: StackPanel);
20ferroui_base::ferro_class_info!(ReversibleStackPanel { new: ReversibleStackPanel::new });
21ferro_impl_classes!(
22 ReversibleStackPanel: StyledElementImpl,
23 VisualImpl,
24 InteractiveImpl,
25 InputElementImpl,
26 ControlImpl,
27 PanelImpl,
28 StackPanelImpl
29);
30
31ferroui_base::ferro_impl_classes!(ReversibleStackPanel: FerroObjectImpl);
32
33impl LayoutableImpl for ReversibleStackPanel {
34 fn arrange_override(this: &Self, final_size: Size) -> Size {
35 let orientation = this.orientation();
36 let spacing = this.spacing();
37 let final_rect = Rect::from_size(final_size);
38 let mut pos = 0.0;
39
40 let children = this.children().snapshot();
41 let reverse_order = this.reverse_order();
42
43 for index in 0..children.len() {
44 let child = &children[if reverse_order { children.len() - 1 - index } else { index }];
45
46 if !child.is_visible() {
47 continue;
48 }
49
50 let child_width = child.desired_size().width;
51 let child_height = child.desired_size().height;
52
53 if orientation == Orientation::Vertical {
54 let rect = LayoutExtensions::align(
55 Rect::new(0.0, pos, child_width, child_height),
56 final_rect,
57 child.horizontal_alignment(),
58 VerticalAlignment::Top,
59 );
60 this.arrange_child(child, rect, final_size, orientation);
61 pos += child_height + spacing;
62 } else {
63 let rect = LayoutExtensions::align(
64 Rect::new(pos, 0.0, child_width, child_height),
65 final_rect,
66 HorizontalAlignment::Left,
67 child.vertical_alignment(),
68 );
69 this.arrange_child(child, rect, final_size, orientation);
70 pos += child_width + spacing;
71 }
72 }
73
74 final_size
75 }
76}
77
78ferroui_base::ferro_properties! { impl ReversibleStackPanel {
79 ferro_property!(
80 pub fn reverse_order_property() -> StyledProperty<bool> {
82 FerroProperty::register::<ReversibleStackPanel, _>("ReverseOrder", false)
83 }
84 );
85} }
86
87impl ReversibleStackPanel {
88 fn static_constructor() {
89 Layoutable::affects_arrange::<ReversibleStackPanel>(&[Self::reverse_order_property().as_property()]);
90 }
91
92 pub fn construct() -> Self {
94 Self { base: StackPanel::construct() }
95 }
96
97 pub fn new() -> Ref<Self> {
98 instantiate(Self::construct())
99 }
100
101 pub fn reverse_order(&self) -> bool {
103 self.get_value(Self::reverse_order_property())
104 }
105
106 pub fn set_reverse_order(&self, value: bool) {
107 self.set_value(Self::reverse_order_property(), value)
108 }
109}