Skip to main content

fui/controls/
mod.rs

1use crate::bindings::ui;
2use crate::event::{KeyEventArgs, PointerEventArgs};
3use crate::ffi::{
4    AlignItems, CursorStyle, FlexDirection, JustifyContent, Orientation, PositionType,
5    SemanticCheckedState, SemanticRole, Unit,
6};
7use crate::node::{
8    flex_box, row, FlexBox, HasFlexBoxRoot, Node, NodeRef, TextNode, ThemeBindable, WeakNodeRef,
9};
10use crate::theme::{current_theme, subscribe};
11use std::cell::{Cell, RefCell};
12use std::rc::Rc;
13
14pub(crate) mod internal;
15mod shared;
16use internal::pressable_labeled_control::PressableLabeledControl;
17use radio_group::WeakRadioGroupEventTarget;
18pub(crate) use shared::*;
19
20#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
21pub struct ClickEventArgs;
22
23/// Semantic click activation for controls whose primary action can be invoked
24/// by pointer, keyboard, or another supported activation source.
25///
26/// Use [`Node::on_pointer_click`] when raw routed pointer data is required.
27pub trait Clickable: Sized {
28    fn on_click(&self, handler: impl Fn(ClickEventArgs) + 'static) -> &Self;
29}
30
31#[derive(Clone, Copy, Debug, PartialEq, Eq)]
32pub enum CheckState {
33    False,
34    True,
35    Mixed,
36}
37
38impl CheckState {
39    fn semantic(self) -> SemanticCheckedState {
40        match self {
41            Self::False => SemanticCheckedState::False,
42            Self::True => SemanticCheckedState::True,
43            Self::Mixed => SemanticCheckedState::Mixed,
44        }
45    }
46
47    pub fn is_checked(self) -> bool {
48        self == Self::True
49    }
50}
51
52#[derive(Clone, Copy, Debug, PartialEq, Eq)]
53pub struct CheckboxChangedEventArgs {
54    pub state: CheckState,
55    pub checked: bool,
56}
57
58#[derive(Clone, Copy, Debug, PartialEq, Eq)]
59pub struct RadioButtonChangedEventArgs {
60    pub checked: bool,
61}
62
63#[derive(Clone, Debug, PartialEq, Eq)]
64pub struct RadioGroupChangedEventArgs {
65    pub value: String,
66}
67
68#[derive(Clone, Copy, Debug, PartialEq, Eq)]
69pub struct SwitchChangedEventArgs {
70    pub checked: bool,
71}
72
73#[derive(Clone, Copy, Debug, PartialEq)]
74pub struct SliderChangedEventArgs {
75    pub value: f32,
76}
77
78pub trait LabeledControlTextStyle: Sized {
79    #[doc(hidden)]
80    fn set_label_font_family(&self, family: crate::FontFamily);
81    #[doc(hidden)]
82    fn set_label_font_size(&self, size: f32);
83    #[doc(hidden)]
84    fn set_label_text_color(&self, color: u32);
85
86    fn font_family(&self, family: crate::FontFamily) -> &Self {
87        self.set_label_font_family(family);
88        self
89    }
90
91    fn font_size(&self, size: f32) -> &Self {
92        self.set_label_font_size(size);
93        self
94    }
95
96    fn text_color(&self, color: u32) -> &Self {
97        self.set_label_text_color(color);
98        self
99    }
100}
101
102#[derive(Clone, Debug, PartialEq, Eq)]
103pub struct DropdownChangedEventArgs<T> {
104    pub item: T,
105    pub selected_index: i32,
106}
107
108#[derive(Clone, Debug, PartialEq, Eq)]
109pub struct ComboBoxChangedEventArgs<T> {
110    pub item: T,
111    pub selected_index: i32,
112}
113
114pub mod anti_selection_area;
115mod appearance;
116pub mod button;
117pub mod checkbox;
118pub mod combobox;
119pub mod context_menu;
120pub mod control_template_set;
121pub mod control_tokens;
122pub mod dialog;
123pub mod dropdown;
124pub mod form;
125pub mod nav_link;
126pub mod popup;
127pub mod progress_bar;
128pub mod radio_button;
129pub mod radio_group;
130pub mod selection_area;
131pub mod slider;
132pub mod switch;
133pub mod templating;
134#[cfg(test)]
135mod tests;
136pub mod text_area;
137mod text_editor_surface;
138pub mod text_input;
139
140pub use anti_selection_area::AntiSelectionArea;
141pub use appearance::{
142    ContextMenuAppearance, ContextMenuItemAppearance, DialogAppearance, OverlayBackdropAppearance,
143    PopupAppearance, SurfaceAppearance,
144};
145pub use button::Button;
146pub use checkbox::Checkbox;
147pub use combobox::{ComboBox, ComboBoxCommitMode, ComboBoxFilterMode, ComboBoxItem};
148pub use context_menu::{
149    run_context_menu_action, ContextMenu, ContextMenuAction, ContextMenuVisibilityChangedEventArgs,
150    MenuItem,
151};
152pub use control_template_set::{
153    clear_control_templates, get_control_templates, use_control_templates, ControlTemplateSet,
154};
155pub use control_tokens::{
156    ButtonColors, DropdownColors, DropdownSizing, LabeledControlColors, LabeledControlSizing,
157    ProgressBarColors, ProgressBarSizing, SliderColors, SliderSizing, TextInputColors,
158};
159pub use dialog::{Dialog, DialogShownEventArgs};
160pub use dropdown::{Dropdown, DropdownItem};
161pub use form::Form;
162pub use nav_link::{NavLink, NavigateEventArgs};
163pub use popup::Popup;
164pub use progress_bar::ProgressBar;
165pub use radio_button::RadioButton;
166pub use radio_group::RadioGroup;
167pub use selection_area::SelectionArea;
168pub use slider::Slider;
169pub use switch::Switch;
170pub use templating::{
171    create_default_button_presenter, create_default_checkbox_indicator_presenter,
172    create_default_dropdown_chevron_presenter, create_default_dropdown_field_presenter,
173    create_default_dropdown_option_row_presenter, create_default_radio_indicator_presenter,
174    create_default_slider_presenter, create_default_switch_indicator_presenter,
175    create_default_text_input_presenter, ButtonPresenter, ButtonTemplate, ButtonVisualState,
176    CheckboxIndicatorPresenter, CheckboxIndicatorTemplate, CheckboxIndicatorVisualState,
177    DefaultButtonTemplate, DefaultCheckboxIndicatorTemplate, DefaultDropdownChevronTemplate,
178    DefaultDropdownFieldTemplate, DefaultDropdownOptionRowTemplate, DefaultRadioIndicatorTemplate,
179    DefaultSliderTemplate, DefaultSwitchIndicatorTemplate, DefaultTextInputTemplate,
180    DropdownChevronMetrics, DropdownChevronPresenter, DropdownChevronTemplate,
181    DropdownChevronVisualState, DropdownFieldMetrics, DropdownFieldPresenter,
182    DropdownFieldTemplate, DropdownFieldVisualState, DropdownOptionRowMetrics,
183    DropdownOptionRowPresenter, DropdownOptionRowTemplate, DropdownOptionRowVisualState,
184    PressableIndicatorMetrics, PressableIndicatorPresenter, PressableIndicatorVisualState,
185    RadioIndicatorPresenter, RadioIndicatorTemplate, RadioIndicatorVisualState, SliderPresenter,
186    SliderPresenterMetrics, SliderTemplate, SliderVisualState, SwitchIndicatorPresenter,
187    SwitchIndicatorTemplate, SwitchIndicatorVisualState, TextInputPresenter, TextInputTemplate,
188    TextInputVisualState, DEFAULT_BUTTON_TEMPLATE, DEFAULT_CHECKBOX_INDICATOR_TEMPLATE,
189    DEFAULT_DROPDOWN_CHEVRON_TEMPLATE, DEFAULT_DROPDOWN_FIELD_TEMPLATE,
190    DEFAULT_DROPDOWN_OPTION_ROW_TEMPLATE, DEFAULT_RADIO_INDICATOR_TEMPLATE,
191    DEFAULT_SLIDER_TEMPLATE, DEFAULT_SWITCH_INDICATOR_TEMPLATE, DEFAULT_TEXT_INPUT_TEMPLATE,
192};
193pub use text_area::TextArea;
194pub use text_editor_surface::TextEditorSurface;
195pub use text_input::TextInput;
196
197pub fn button(label: impl Into<String>) -> Button {
198    Button::new(label)
199}
200
201pub fn selection_area() -> SelectionArea {
202    SelectionArea::new()
203}
204
205pub fn anti_selection_area() -> AntiSelectionArea {
206    AntiSelectionArea::new()
207}
208
209pub fn checkbox(label: impl Into<String>) -> Checkbox {
210    Checkbox::new(label)
211}
212
213pub fn combo_box() -> ComboBox {
214    ComboBox::new()
215}
216
217pub fn context_menu<I>(items: I) -> ContextMenu
218where
219    I: IntoIterator<Item = MenuItem>,
220{
221    let menu = ContextMenu::new();
222    menu.items(items);
223    menu
224}
225
226pub fn popup() -> Popup {
227    Popup::new()
228}
229
230pub fn dialog(title: impl Into<String>, body: impl Into<String>) -> Dialog {
231    Dialog::new(title, body)
232}
233
234pub fn dropdown() -> Dropdown {
235    Dropdown::new()
236}
237
238pub fn form() -> Form {
239    Form::new()
240}
241
242pub fn nav_link(href: impl Into<String>) -> NavLink {
243    NavLink::new(href)
244}
245
246pub fn radio_button(label: impl Into<String>) -> RadioButton {
247    RadioButton::new(label)
248}
249
250pub fn radio_group() -> RadioGroup {
251    RadioGroup::new()
252}
253
254pub fn switch(label: impl Into<String>) -> Switch {
255    Switch::new(label)
256}
257
258pub fn progress_bar() -> ProgressBar {
259    ProgressBar::new()
260}
261
262pub fn slider() -> Slider {
263    Slider::new()
264}
265
266pub fn text_input() -> TextInput {
267    TextInput::new()
268}
269
270pub fn text_area() -> TextArea {
271    TextArea::new()
272}