Skip to main content

swiftui_native/view/
controls.rs

1//! Styling the standard controls, and the lists and tabs that hold them.
2//!
3//! Part of [`crate::view::View`]'s chainable API; Rust allows a type's
4//! inherent methods to be split across modules, and 400 of them in one file
5//! was a file nobody could find anything in.
6
7use super::{Color, View};
8use crate::views;
9
10impl View {
11    // ── Control styles ──
12    //
13    // SwiftUI styles a control through the environment, so each of these is set
14    // on a container and applies to every control of that kind below it. They
15    // are one-liners over functions that were all already here.
16
17    /// `.toggleStyle(_:)`
18    pub fn toggle_style(self, style: views::ToggleStyle) -> Self {
19        Self::new(views::toggle_style(&self.handle, style))
20    }
21
22    /// `.pickerStyle(_:)`
23    pub fn picker_style(self, style: views::PickerStyle) -> Self {
24        Self::new(views::picker_style(&self.handle, style))
25    }
26
27    /// `.datePickerStyle(_:)`
28    pub fn date_picker_style(self, style: views::DatePickerStyle) -> Self {
29        Self::new(views::date_picker_style(&self.handle, style))
30    }
31
32    /// `.gaugeStyle(_:)`
33    pub fn gauge_style(self, style: views::GaugeStyle) -> Self {
34        Self::new(views::gauge_style(&self.handle, style))
35    }
36
37    /// `.formStyle(_:)`
38    pub fn form_style(self, style: views::FormStyle) -> Self {
39        Self::new(views::form_style(&self.handle, style))
40    }
41
42    /// `.groupBoxStyle(_:)`
43    pub fn group_box_style(self, style: views::GroupBoxStyle) -> Self {
44        Self::new(views::group_box_style(&self.handle, style))
45    }
46
47    /// `.controlGroupStyle(_:)`
48    pub fn control_group_style(self, style: views::ControlGroupStyle) -> Self {
49        Self::new(views::control_group_style(&self.handle, style))
50    }
51
52    /// `.disclosureGroupStyle(_:)`
53    pub fn disclosure_group_style(self, style: views::DisclosureGroupStyle) -> Self {
54        Self::new(views::disclosure_group_style(&self.handle, style))
55    }
56
57    /// `.tableStyle(_:)`
58    pub fn table_style(self, style: views::TableStyle) -> Self {
59        Self::new(views::table_style(&self.handle, style))
60    }
61
62    /// `.textEditorStyle(_:)`
63    pub fn text_editor_style(self, style: views::TextEditorStyle) -> Self {
64        Self::new(views::text_editor_style(&self.handle, style))
65    }
66
67    /// `.labeledContentStyle(_:)`
68    pub fn labeled_content_style(self, style: views::LabeledContentStyle) -> Self {
69        Self::new(views::labeled_content_style(&self.handle, style))
70    }
71
72    /// `.textSelection(_:)` — whether the user can select and copy the text.
73    pub fn text_selection(self, style: views::TextSelectability) -> Self {
74        Self::new(views::text_selection(&self.handle, style))
75    }
76
77    /// `.buttonRepeatBehavior(_:)` — whether holding repeats the action.
78    pub fn button_repeat_behavior(self, value: views::ButtonRepeatBehavior) -> Self {
79        Self::new(views::button_repeat_behavior(&self.handle, value))
80    }
81
82    /// `.buttonSizing(_:)`
83    pub fn button_sizing(self, value: views::ButtonSizing) -> Self {
84        Self::new(views::button_sizing(&self.handle, value))
85    }
86
87    /// `.menuButtonStyle(_:)`
88    pub fn menu_button_style(self, style: views::MenuButtonStyle) -> Self {
89        Self::new(views::menu_button_style(&self.handle, style))
90    }
91
92    /// `.menuActionDismissBehavior(_:)` — whether choosing an item closes the menu.
93    pub fn menu_action_dismiss_behavior(self, value: views::MenuActionDismissBehavior) -> Self {
94        Self::new(views::menu_action_dismiss_behavior(&self.handle, value))
95    }
96
97    /// `.sliderThumbVisibility(_:)`
98    pub fn slider_thumb_visibility(self, value: views::Visibility) -> Self {
99        Self::new(views::slider_thumb_visibility(&self.handle, value))
100    }
101
102    /// `.springLoadingBehavior(_:)` — whether hovering a drag over this opens it.
103    pub fn spring_loading_behavior(self, value: views::SpringLoadingBehavior) -> Self {
104        Self::new(views::spring_loading_behavior(&self.handle, value))
105    }
106
107    /// `.paletteSelectionEffect(_:)`
108    pub fn palette_selection_effect(self, value: views::PaletteSelectionEffect) -> Self {
109        Self::new(views::palette_selection_effect(&self.handle, value))
110    }
111
112    /// `.materialActiveAppearance(_:)`
113    pub fn material_active_appearance(self, value: views::MaterialActiveAppearance) -> Self {
114        Self::new(views::material_active_appearance(&self.handle, value))
115    }
116
117    /// `.progressViewStyle(.circular)`
118    pub fn progress_view_style_circular(self) -> Self {
119        Self::new(views::progress_view_style_circular(&self.handle))
120    }
121
122    // ── Menus, labels and badges ──
123
124    /// `.menuIndicator(_:)` — the chevron that says a control opens a menu.
125    pub fn menu_indicator(self, visibility: views::Visibility) -> Self {
126        Self::new(views::menu_indicator(&self.handle, visibility))
127    }
128
129    /// `.menuOrder(_:)`
130    pub fn menu_order(self, order: views::MenuOrder) -> Self {
131        Self::new(views::menu_order(&self.handle, order))
132    }
133
134    /// `.labelsVisibility(_:)` — hiding a label keeps it for VoiceOver while
135    /// taking it off the screen, which `.hidden()` does not.
136    pub fn labels_visibility(self, visibility: views::Visibility) -> Self {
137        Self::new(views::labels_visibility(&self.handle, visibility))
138    }
139
140    /// `.headerProminence(_:)`
141    pub fn header_prominence(self, prominence: views::Prominence) -> Self {
142        Self::new(views::header_prominence(&self.handle, prominence))
143    }
144
145    /// `.badgeProminence(_:)`
146    pub fn badge_prominence(self, prominence: views::BadgeProminence) -> Self {
147        Self::new(views::badge_prominence(&self.handle, prominence))
148    }
149
150    // ── Lists and tables ──
151
152    /// `.listStyle(_:)`
153    pub fn list_style(self, style: views::ListStyle) -> Self {
154        Self::new(views::list_style(&self.handle, style))
155    }
156
157    /// `.listRowInsets(_:)` as `[top, leading, bottom, trailing]`; `None`
158    /// restores the default inset.
159    pub fn list_row_insets(self, insets: Option<[f64; 4]>) -> Self {
160        Self::new(views::list_row_insets(&self.handle, insets))
161    }
162
163    /// `.listRowSeparator(_:edges:)`
164    pub fn list_row_separator(
165        self,
166        visibility: views::Visibility,
167        edges: views::VerticalEdgeSet,
168    ) -> Self {
169        Self::new(views::list_row_separator(&self.handle, visibility, edges))
170    }
171
172    /// `.listSectionSeparator(_:edges:)`
173    pub fn list_section_separator(
174        self,
175        visibility: views::Visibility,
176        edges: views::VerticalEdgeSet,
177    ) -> Self {
178        Self::new(views::list_section_separator(&self.handle, visibility, edges))
179    }
180
181    /// `.selectionDisabled(_:)` — a row that shows but cannot be picked.
182    pub fn selection_disabled(self, disabled: bool) -> Self {
183        Self::new(views::selection_disabled(&self.handle, disabled))
184    }
185
186    /// `.swipeActions(edge:allowsFullSwipe:content:)`
187    pub fn swipe_actions(
188        self,
189        edge: views::HorizontalEdge,
190        allows_full_swipe: bool,
191        content: View,
192    ) -> Self {
193        Self::new(views::swipe_actions(
194            &self.handle,
195            edge,
196            allows_full_swipe,
197            content.handle(),
198        ))
199    }
200
201    /// `.refreshable(action:)` — pull to refresh.
202    pub fn refreshable(self, action: impl Fn() + Send + Sync + 'static) -> Self {
203        Self::new(views::refreshable(&self.handle, action))
204    }
205
206    /// `.scrollDismissesKeyboard(_:)` — what scrolling does to an open keyboard.
207    pub fn scroll_dismisses_keyboard(self, mode: views::ScrollDismissesKeyboardMode) -> Self {
208        Self::new(views::scroll_dismisses_keyboard(&self.handle, mode))
209    }
210
211    /// `.listRowSeparatorTint(_:edges:)` — `None` restores the default.
212    pub fn list_row_separator_tint(
213        self,
214        color: Option<Color>,
215        edges: &[views::VerticalEdgeSet],
216    ) -> Self {
217        Self::new(views::list_row_separator_tint(&self.handle, color, edges))
218    }
219
220    /// `.listSectionSeparatorTint(_:edges:)`
221    pub fn list_section_separator_tint(
222        self,
223        color: Option<Color>,
224        edges: &[views::VerticalEdgeSet],
225    ) -> Self {
226        Self::new(views::list_section_separator_tint(&self.handle, color, edges))
227    }
228
229    /// `.listItemTint(.monochrome)`
230    pub fn list_item_tint_monochrome(self, tinted: bool) -> Self {
231        Self::new(views::list_item_tint_monochrome(&self.handle, tinted))
232    }
233
234    /// `.alternatingRowBackgrounds(_:)`
235    pub fn alternating_row_backgrounds(
236        self,
237        value: views::AlternatingRowBackgroundBehavior,
238    ) -> Self {
239        Self::new(views::alternating_row_backgrounds(&self.handle, value))
240    }
241
242    /// `.sectionActions(content:)` — controls in a section's header area.
243    pub fn section_actions(self, content: View) -> Self {
244        Self::new(views::section_actions(&self.handle, content.handle()))
245    }
246
247    /// `.sectionIndexLabel(_:)` — the letter this section shows in a scrubber.
248    pub fn section_index_label(self, label: &str) -> Self {
249        Self::new(views::section_index_label(&self.handle, label))
250    }
251
252    /// `.tableColumnHeaders(_:)`
253    pub fn table_column_headers(self, visibility: views::Visibility) -> Self {
254        Self::new(views::table_column_headers(&self.handle, visibility))
255    }
256
257    // ── Tab chrome ──
258
259    /// `.tabViewStyle(.automatic)`
260    pub fn tab_view_style_automatic(self) -> Self {
261        Self::new(views::tab_view_style_automatic(&self.handle))
262    }
263
264    /// `.tabViewCustomization(nil)`
265    pub fn tab_view_customization_none(self) -> Self {
266        Self::new(views::tab_view_customization_none(&self.handle))
267    }
268
269    /// `.tabViewSearchActivation(.automatic)`
270    pub fn tab_view_search_activation_automatic(self) -> Self {
271        Self::new(views::tab_view_search_activation_automatic(&self.handle))
272    }
273
274    /// `.tabViewSidebarHeader { … }`
275    pub fn tab_view_sidebar_header(self, content: View) -> Self {
276        Self::new(views::tab_view_sidebar_header(&self.handle, content.handle()))
277    }
278
279    /// `.tabViewSidebarFooter { … }`
280    pub fn tab_view_sidebar_footer(self, content: View) -> Self {
281        Self::new(views::tab_view_sidebar_footer(&self.handle, content.handle()))
282    }
283
284    /// `.tabViewSidebarBottomBar { … }`
285    pub fn tab_view_sidebar_bottom_bar(self, content: View) -> Self {
286        Self::new(views::tab_view_sidebar_bottom_bar(&self.handle, content.handle()))
287    }
288
289    /// `.tabBarMinimizeBehavior(_:)`
290    pub fn tab_bar_minimize_behavior(self, value: views::TabBarMinimizeBehavior) -> Self {
291        Self::new(views::tab_bar_minimize_behavior(&self.handle, value))
292    }
293
294}