Skip to main content

ferroui_controls/command_bar/
command_bar_button.rs

1use super::{CommandBarDefaultLabelPosition, ICommandBarElement};
2use crate::primitives::TemplatedControlImpl;
3use crate::Button;
4use crate::{ButtonImpl, ContentControlImpl, ControlImpl};
5use ferroui_base::input::InputElementImpl;
6use ferroui_base::interactivity::InteractiveImpl;
7use ferroui_base::layout::LayoutableImpl;
8use ferroui_base::{
9    ferro_class, ferro_class_info, ferro_impl_classes, ferro_properties, instantiate, BoxedValue, FerroObject,
10    FerroObjectImpl, FerroProperty, Ref, StyledElementImpl, StyledProperty, VisualImpl,
11};
12use std::rc::Rc;
13
14/// A button for use in a [`CommandBar`](super::CommandBar).
15#[repr(C)]
16pub struct CommandBarButton {
17    base: Button,
18}
19
20ferro_class!(CommandBarButton: Button);
21ferro_class_info!(CommandBarButton {
22    new: CommandBarButton::new,
23    interfaces: [
24        Rc<dyn ICommandBarElement> => |button: Ref<CommandBarButton>| button.as_command_bar_element(),
25    ],
26});
27ferro_impl_classes!(
28    CommandBarButton: FerroObjectImpl,
29    StyledElementImpl,
30    VisualImpl,
31    LayoutableImpl,
32    InteractiveImpl,
33    InputElementImpl,
34    ControlImpl,
35    TemplatedControlImpl,
36    ContentControlImpl,
37    ButtonImpl
38);
39
40/// Implements the command bar element contract for the button behind a
41/// class handle.
42struct CommandBarButtonElement(Ref<CommandBarButton>);
43
44impl ICommandBarElement for CommandBarButtonElement {
45    fn is_compact(&self) -> bool {
46        self.0.is_compact()
47    }
48
49    fn set_is_compact(&self, value: bool) {
50        self.0.set_is_compact(value)
51    }
52
53    fn is_in_overflow(&self) -> bool {
54        self.0.is_in_overflow()
55    }
56
57    fn set_is_in_overflow(&self, value: bool) {
58        self.0.set_is_in_overflow(value)
59    }
60
61    fn as_object(&self) -> Option<&FerroObject> {
62        let object: &FerroObject = &self.0;
63        Some(object)
64    }
65}
66
67ferro_properties! {
68    impl CommandBarButton {
69        /// Defines the `Label` property.
70        pub fn label_property() -> StyledProperty<Option<String>> {
71            FerroProperty::register::<CommandBarButton, _>("Label", None)
72        }
73
74        /// Defines the `Icon` property.
75        pub fn icon_property() -> StyledProperty<Option<BoxedValue>> {
76            FerroProperty::register::<CommandBarButton, _>("Icon", None)
77        }
78
79        /// Defines the `IsCompact` property.
80        pub fn is_compact_property() -> StyledProperty<bool> {
81            FerroProperty::register::<CommandBarButton, _>("IsCompact", false)
82        }
83
84        /// Defines the `DynamicOverflowOrder` property.
85        pub fn dynamic_overflow_order_property() -> StyledProperty<i32> {
86            FerroProperty::register::<CommandBarButton, _>("DynamicOverflowOrder", 0)
87        }
88
89        /// Defines the `LabelPosition` property.
90        pub fn label_position_property() -> StyledProperty<CommandBarDefaultLabelPosition> {
91            FerroProperty::register::<CommandBarButton, _>("LabelPosition", CommandBarDefaultLabelPosition::Bottom)
92        }
93
94        /// Defines the `IsInOverflow` property.
95        pub fn is_in_overflow_property() -> StyledProperty<bool> {
96            FerroProperty::register::<CommandBarButton, _>("IsInOverflow", false)
97        }
98    }
99}
100
101impl CommandBarButton {
102    /// Creates the class data; see [`ferroui_base::FerroObject::construct`].
103    pub fn construct() -> Self {
104        Self { base: Button::construct() }
105    }
106
107    /// Creates the button.
108    pub fn new() -> Ref<Self> {
109        instantiate(Self::construct())
110    }
111
112    /// The button as a command bar element.
113    pub fn as_command_bar_element(&self) -> Rc<dyn ICommandBarElement> {
114        Rc::new(CommandBarButtonElement(self.to_ref()))
115    }
116
117    /// Gets the text label for the button.
118    pub fn label(&self) -> Option<String> {
119        self.get_value(Self::label_property())
120    }
121
122    /// Sets the text label for the button.
123    pub fn set_label(&self, value: Option<&str>) {
124        self.set_value(Self::label_property(), value.map(str::to_string))
125    }
126
127    /// Gets the icon content for the button.
128    pub fn icon(&self) -> Option<BoxedValue> {
129        self.get_value(Self::icon_property())
130    }
131
132    /// Sets the icon content for the button.
133    pub fn set_icon(&self, value: Option<BoxedValue>) {
134        self.set_value(Self::icon_property(), value)
135    }
136
137    /// Gets whether the button is in compact mode (icon only, label
138    /// hidden).
139    pub fn is_compact(&self) -> bool {
140        self.get_value(Self::is_compact_property())
141    }
142
143    /// Sets whether the button is in compact mode (icon only, label
144    /// hidden).
145    pub fn set_is_compact(&self, value: bool) {
146        self.set_value(Self::is_compact_property(), value)
147    }
148
149    /// Gets the order in which this button moves to the overflow menu when
150    /// space is limited. Lower values have higher priority (stay visible
151    /// longer).
152    pub fn dynamic_overflow_order(&self) -> i32 {
153        self.get_value(Self::dynamic_overflow_order_property())
154    }
155
156    /// Sets the order in which this button moves to the overflow menu when
157    /// space is limited.
158    pub fn set_dynamic_overflow_order(&self, value: i32) {
159        self.set_value(Self::dynamic_overflow_order_property(), value)
160    }
161
162    /// Gets the label position. This is set automatically by the parent
163    /// command bar.
164    pub fn label_position(&self) -> CommandBarDefaultLabelPosition {
165        self.get_value(Self::label_position_property())
166    }
167
168    /// Sets the label position. This is set automatically by the parent
169    /// command bar.
170    pub fn set_label_position(&self, value: CommandBarDefaultLabelPosition) {
171        self.set_value(Self::label_position_property(), value)
172    }
173
174    /// Gets whether this button is displayed inside the overflow popup.
175    pub fn is_in_overflow(&self) -> bool {
176        self.get_value(Self::is_in_overflow_property())
177    }
178
179    /// Sets whether this button is displayed inside the overflow popup. Set
180    /// automatically by the command bar when moving items between primary
181    /// and overflow.
182    pub fn set_is_in_overflow(&self, value: bool) {
183        self.set_value(Self::is_in_overflow_property(), value)
184    }
185}