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, 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_tokens;
121pub mod dialog;
122pub mod dropdown;
123pub mod form;
124pub mod nav_link;
125pub mod popup;
126pub mod progress_bar;
127pub mod radio_button;
128pub mod radio_group;
129pub mod selection_area;
130pub mod slider;
131pub mod switch;
132pub mod tab_view;
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_tokens::{
153    ButtonColors, DropdownColors, DropdownSizing, LabeledControlColors, LabeledControlSizing,
154    ProgressBarColors, ProgressBarSizing, SliderColors, SliderSizing, TextInputColors,
155};
156pub use dialog::{Dialog, DialogShownEventArgs};
157pub use dropdown::{Dropdown, DropdownItem};
158pub use form::Form;
159pub use nav_link::{NavLink, NavLinkInteractionState, NavigateEventArgs};
160pub use popup::Popup;
161pub use progress_bar::ProgressBar;
162pub use radio_button::RadioButton;
163pub use radio_group::RadioGroup;
164pub use selection_area::SelectionArea;
165pub use slider::Slider;
166pub use switch::Switch;
167pub use tab_view::{tab_view, TabContentFactory, TabItem, TabSelectionChangedEventArgs, TabView};
168
169pub fn tab_item(label: impl Into<String>) -> TabItem {
170    TabItem::new(label)
171}
172pub use templating::{
173    create_default_button_presenter, create_default_checkbox_indicator_presenter,
174    create_default_dropdown_chevron_presenter, create_default_dropdown_field_presenter,
175    create_default_dropdown_option_row_presenter, create_default_radio_indicator_presenter,
176    create_default_slider_presenter, create_default_switch_indicator_presenter,
177    create_default_text_input_presenter, ButtonPresenter, ButtonTemplate, ButtonVisualState,
178    CheckboxIndicatorPresenter, CheckboxIndicatorTemplate, CheckboxIndicatorVisualState,
179    DefaultButtonTemplate, DefaultCheckboxIndicatorTemplate, DefaultDropdownChevronTemplate,
180    DefaultDropdownFieldTemplate, DefaultDropdownOptionRowTemplate, DefaultRadioIndicatorTemplate,
181    DefaultSliderTemplate, DefaultSwitchIndicatorTemplate, DefaultTextInputTemplate,
182    DropdownChevronMetrics, DropdownChevronPresenter, DropdownChevronTemplate,
183    DropdownChevronVisualState, DropdownFieldMetrics, DropdownFieldPresenter,
184    DropdownFieldTemplate, DropdownFieldVisualState, DropdownOptionRowMetrics,
185    DropdownOptionRowPresenter, DropdownOptionRowTemplate, DropdownOptionRowVisualState,
186    PressableIndicatorMetrics, PressableIndicatorPresenter, PressableIndicatorVisualState,
187    RadioIndicatorPresenter, RadioIndicatorTemplate, RadioIndicatorVisualState, SliderPresenter,
188    SliderPresenterMetrics, SliderTemplate, SliderVisualState, SwitchIndicatorPresenter,
189    SwitchIndicatorTemplate, SwitchIndicatorVisualState, TextInputPresenter, TextInputTemplate,
190    TextInputVisualState, DEFAULT_BUTTON_TEMPLATE, DEFAULT_CHECKBOX_INDICATOR_TEMPLATE,
191    DEFAULT_DROPDOWN_CHEVRON_TEMPLATE, DEFAULT_DROPDOWN_FIELD_TEMPLATE,
192    DEFAULT_DROPDOWN_OPTION_ROW_TEMPLATE, DEFAULT_RADIO_INDICATOR_TEMPLATE,
193    DEFAULT_SLIDER_TEMPLATE, DEFAULT_SWITCH_INDICATOR_TEMPLATE, DEFAULT_TEXT_INPUT_TEMPLATE,
194};
195pub use text_area::TextArea;
196pub use text_editor_surface::TextEditorSurface;
197pub use text_input::TextInput;
198
199pub fn button(label: impl Into<String>) -> Button {
200    Button::new(label)
201}
202
203pub fn selection_area() -> SelectionArea {
204    SelectionArea::new()
205}
206
207pub fn anti_selection_area() -> AntiSelectionArea {
208    AntiSelectionArea::new()
209}
210
211pub fn checkbox(label: impl Into<String>) -> Checkbox {
212    Checkbox::new(label)
213}
214
215pub fn combo_box() -> ComboBox {
216    ComboBox::new()
217}
218
219pub fn context_menu<I>(items: I) -> ContextMenu
220where
221    I: IntoIterator<Item = MenuItem>,
222{
223    let menu = ContextMenu::new();
224    menu.items(items);
225    menu
226}
227
228pub fn popup() -> Popup {
229    Popup::new()
230}
231
232pub fn dialog(title: impl Into<String>, body: impl Into<String>) -> Dialog {
233    Dialog::new(title, body)
234}
235
236pub fn dropdown() -> Dropdown {
237    Dropdown::new()
238}
239
240pub fn form() -> Form {
241    Form::new()
242}
243
244pub fn nav_link(href: impl Into<String>) -> NavLink {
245    NavLink::new(href)
246}
247
248pub fn radio_button(label: impl Into<String>) -> RadioButton {
249    RadioButton::new(label)
250}
251
252pub fn radio_group() -> RadioGroup {
253    RadioGroup::new()
254}
255
256pub fn switch(label: impl Into<String>) -> Switch {
257    Switch::new(label)
258}
259
260pub fn progress_bar() -> ProgressBar {
261    ProgressBar::new()
262}
263
264pub fn slider() -> Slider {
265    Slider::new()
266}
267
268pub fn text_input() -> TextInput {
269    TextInput::new()
270}
271
272pub fn text_area() -> TextArea {
273    TextArea::new()
274}