@effindomv2/fui-rs 0.1.22 → 0.1.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.toml +1 -1
- package/README.md +12 -0
- package/package.json +1 -1
- package/src/controls/anti_selection_area.rs +0 -18
- package/src/controls/button.rs +14 -42
- package/src/controls/checkbox.rs +7 -0
- package/src/controls/combobox.rs +7 -6
- package/src/controls/context_menu.rs +38 -5
- package/src/controls/dialog.rs +41 -3
- package/src/controls/dropdown.rs +2 -2
- package/src/controls/form.rs +16 -20
- package/src/controls/internal/button_presenter.rs +5 -5
- package/src/controls/internal/checkbox_indicator_presenter.rs +1 -1
- package/src/controls/internal/pressable_labeled_control.rs +21 -7
- package/src/controls/internal/selectable_popup_list.rs +2 -2
- package/src/controls/internal/text_input_core.rs +38 -68
- package/src/controls/internal/text_input_presenter.rs +4 -4
- package/src/controls/mod.rs +11 -4
- package/src/controls/popup.rs +35 -20
- package/src/controls/radio_button.rs +7 -0
- package/src/controls/radio_group.rs +17 -0
- package/src/controls/selection_area.rs +0 -18
- package/src/controls/shared.rs +2 -17
- package/src/controls/switch.rs +7 -0
- package/src/controls/tests.rs +230 -6
- package/src/controls/text_area.rs +28 -142
- package/src/controls/text_editor_surface.rs +167 -0
- package/src/controls/text_input.rs +30 -144
- package/src/lib.rs +26 -20
- package/src/mobile_text_selection_toolbar.rs +2 -2
- package/src/node/core.rs +451 -60
- package/src/node/custom_drawable.rs +20 -0
- package/src/node/flex_box.rs +39 -47
- package/src/node/grid.rs +43 -128
- package/src/node/helpers.rs +34 -43
- package/src/node/image.rs +47 -56
- package/src/node/mod.rs +398 -73
- package/src/node/scroll_bar.rs +6 -0
- package/src/node/scroll_box.rs +8 -21
- package/src/node/scroll_view.rs +144 -13
- package/src/node/svg_node.rs +47 -66
- package/src/node/text_node.rs +358 -79
- package/src/node/virtual_list.rs +17 -0
- package/src/popup_presenter.rs +31 -0
- package/src/text.rs +59 -0
- package/src/text_indices.rs +48 -0
package/src/node/core.rs
CHANGED
|
@@ -84,6 +84,8 @@ impl NodeKind {
|
|
|
84
84
|
#[derive(Clone, Default)]
|
|
85
85
|
pub(crate) struct EventHandlers {
|
|
86
86
|
pub(crate) pointer_click: Option<PointerCallback>,
|
|
87
|
+
pub(crate) pointer_double_click: Option<PointerCallback>,
|
|
88
|
+
pub(crate) pointer_triple_click: Option<PointerCallback>,
|
|
87
89
|
pub(crate) pointer_down: Option<PointerCallback>,
|
|
88
90
|
pub(crate) pointer_move: Option<PointerCallback>,
|
|
89
91
|
pub(crate) pointer_up: Option<PointerCallback>,
|
|
@@ -114,6 +116,29 @@ impl EventHandlers {
|
|
|
114
116
|
..Self::default()
|
|
115
117
|
}
|
|
116
118
|
}
|
|
119
|
+
|
|
120
|
+
fn has_pointer_click_handler(&self) -> bool {
|
|
121
|
+
self.pointer_click.is_some()
|
|
122
|
+
|| self.pointer_double_click.is_some()
|
|
123
|
+
|| self.pointer_triple_click.is_some()
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
fn dispatch_pointer_click(&self, event: &mut PointerEventArgs, click_count: i32) {
|
|
127
|
+
let click_count = click_count.max(1);
|
|
128
|
+
event.click_count = click_count;
|
|
129
|
+
if let Some(handler) = self.pointer_click.as_ref() {
|
|
130
|
+
handler(event);
|
|
131
|
+
}
|
|
132
|
+
if click_count == 2 {
|
|
133
|
+
if let Some(handler) = self.pointer_double_click.as_ref() {
|
|
134
|
+
handler(event);
|
|
135
|
+
}
|
|
136
|
+
} else if click_count == 3 {
|
|
137
|
+
if let Some(handler) = self.pointer_triple_click.as_ref() {
|
|
138
|
+
handler(event);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
117
142
|
}
|
|
118
143
|
#[derive(Clone)]
|
|
119
144
|
pub(crate) struct NodeBehavior {
|
|
@@ -130,6 +155,7 @@ pub(crate) struct NodeBehavior {
|
|
|
130
155
|
pub(crate) semantic_disabled: Option<bool>,
|
|
131
156
|
pub(crate) semantic_checked: Option<SemanticCheckedState>,
|
|
132
157
|
pub(crate) semantic_selected: Option<bool>,
|
|
158
|
+
pub(crate) semantic_expanded: Option<bool>,
|
|
133
159
|
pub(crate) semantic_value_range: Option<(f32, f32, f32)>,
|
|
134
160
|
pub(crate) semantic_orientation: Option<Orientation>,
|
|
135
161
|
pub(crate) selectable_text: bool,
|
|
@@ -143,7 +169,6 @@ pub(crate) struct NodeBehavior {
|
|
|
143
169
|
pub(crate) context_menu_handler: Option<ContextMenuCallback>,
|
|
144
170
|
pub(crate) tool_tip: Option<ToolTip>,
|
|
145
171
|
pub(crate) track_semantic_disabled_from_enabled: bool,
|
|
146
|
-
pub(crate) request_semantic_announcement: bool,
|
|
147
172
|
pub(crate) visibility: Option<Visibility>,
|
|
148
173
|
pub(crate) is_portal: bool,
|
|
149
174
|
pub(crate) fill_width: bool,
|
|
@@ -188,6 +213,7 @@ impl Default for NodeBehavior {
|
|
|
188
213
|
semantic_disabled: None,
|
|
189
214
|
semantic_checked: None,
|
|
190
215
|
semantic_selected: None,
|
|
216
|
+
semantic_expanded: None,
|
|
191
217
|
semantic_value_range: None,
|
|
192
218
|
semantic_orientation: None,
|
|
193
219
|
selectable_text: false,
|
|
@@ -201,7 +227,6 @@ impl Default for NodeBehavior {
|
|
|
201
227
|
context_menu_handler: None,
|
|
202
228
|
tool_tip: None,
|
|
203
229
|
track_semantic_disabled_from_enabled: false,
|
|
204
|
-
request_semantic_announcement: false,
|
|
205
230
|
visibility: None,
|
|
206
231
|
is_portal: false,
|
|
207
232
|
fill_width: false,
|
|
@@ -266,6 +291,10 @@ pub(crate) struct LinearGradient {
|
|
|
266
291
|
pub(crate) struct FlexBoxProps {
|
|
267
292
|
pub(crate) width: Option<(f32, Unit)>,
|
|
268
293
|
pub(crate) height: Option<(f32, Unit)>,
|
|
294
|
+
pub(crate) min_width: Option<(f32, Unit)>,
|
|
295
|
+
pub(crate) max_width: Option<(f32, Unit)>,
|
|
296
|
+
pub(crate) min_height: Option<(f32, Unit)>,
|
|
297
|
+
pub(crate) max_height: Option<(f32, Unit)>,
|
|
269
298
|
pub(crate) bg_color: Option<u32>,
|
|
270
299
|
pub(crate) padding: Option<(f32, f32, f32, f32)>,
|
|
271
300
|
pub(crate) flex_direction: Option<FlexDirection>,
|
|
@@ -283,6 +312,10 @@ pub(crate) struct TextProps {
|
|
|
283
312
|
pub(crate) content: String,
|
|
284
313
|
pub(crate) width: Option<(f32, Unit)>,
|
|
285
314
|
pub(crate) height: Option<(f32, Unit)>,
|
|
315
|
+
pub(crate) min_width: Option<(f32, Unit)>,
|
|
316
|
+
pub(crate) max_width: Option<(f32, Unit)>,
|
|
317
|
+
pub(crate) min_height: Option<(f32, Unit)>,
|
|
318
|
+
pub(crate) max_height: Option<(f32, Unit)>,
|
|
286
319
|
pub(crate) font_id: u32,
|
|
287
320
|
pub(crate) font_size: f32,
|
|
288
321
|
pub(crate) has_font: bool,
|
|
@@ -307,14 +340,13 @@ pub(crate) struct TextProps {
|
|
|
307
340
|
pub(crate) editor_accepts_tab: Option<bool>,
|
|
308
341
|
pub(crate) obscured: Option<bool>,
|
|
309
342
|
pub(crate) caret_color: Option<u32>,
|
|
343
|
+
pub(crate) selection_range_bytes: Option<(u32, u32)>,
|
|
344
|
+
pub(crate) selection_start: u32,
|
|
345
|
+
pub(crate) selection_end: u32,
|
|
310
346
|
}
|
|
311
347
|
|
|
312
348
|
#[derive(Clone, Default)]
|
|
313
349
|
pub(crate) struct GridProps {
|
|
314
|
-
pub(crate) width: Option<(f32, Unit)>,
|
|
315
|
-
pub(crate) height: Option<(f32, Unit)>,
|
|
316
|
-
pub(crate) bg_color: Option<u32>,
|
|
317
|
-
pub(crate) padding: Option<(f32, f32, f32, f32)>,
|
|
318
350
|
pub(crate) columns: Vec<f32>,
|
|
319
351
|
pub(crate) column_types: Vec<GridUnit>,
|
|
320
352
|
pub(crate) rows: Vec<f32>,
|
|
@@ -324,8 +356,6 @@ pub(crate) struct GridProps {
|
|
|
324
356
|
}
|
|
325
357
|
#[derive(Clone)]
|
|
326
358
|
pub(crate) struct ImageProps {
|
|
327
|
-
pub(crate) width: Option<(f32, Unit)>,
|
|
328
|
-
pub(crate) height: Option<(f32, Unit)>,
|
|
329
359
|
pub(crate) texture_id: u32,
|
|
330
360
|
pub(crate) source_url: Option<String>,
|
|
331
361
|
pub(crate) object_fit: ObjectFit,
|
|
@@ -336,22 +366,17 @@ pub(crate) struct ImageProps {
|
|
|
336
366
|
|
|
337
367
|
#[derive(Clone)]
|
|
338
368
|
pub(crate) struct SvgProps {
|
|
339
|
-
pub(crate) width: Option<(f32, Unit)>,
|
|
340
|
-
pub(crate) height: Option<(f32, Unit)>,
|
|
341
369
|
pub(crate) svg_id: u32,
|
|
342
370
|
pub(crate) source_url: Option<String>,
|
|
343
371
|
pub(crate) tint_color: u32,
|
|
344
372
|
pub(crate) sampling_kind: ImageSamplingKind,
|
|
345
373
|
pub(crate) max_aniso: u32,
|
|
346
|
-
pub(crate) opacity: Option<f32>,
|
|
347
374
|
}
|
|
348
375
|
|
|
349
376
|
#[derive(Clone)]
|
|
350
377
|
pub(crate) struct ScrollViewProps {
|
|
351
378
|
pub(crate) width: Option<(f32, Unit)>,
|
|
352
379
|
pub(crate) height: Option<(f32, Unit)>,
|
|
353
|
-
pub(crate) bg_color: Option<u32>,
|
|
354
|
-
pub(crate) padding: Option<(f32, f32, f32, f32)>,
|
|
355
380
|
pub(crate) enable_scroll_x: bool,
|
|
356
381
|
pub(crate) enable_scroll_y: bool,
|
|
357
382
|
pub(crate) friction: Option<f32>,
|
|
@@ -490,6 +515,18 @@ impl WeakFlexBox {
|
|
|
490
515
|
}
|
|
491
516
|
|
|
492
517
|
impl NodeRef {
|
|
518
|
+
pub(crate) fn set_shared_size_scope(&self, enabled: bool) {
|
|
519
|
+
let handle = {
|
|
520
|
+
let mut core = self.inner.borrow_mut();
|
|
521
|
+
core.behavior.is_shared_size_scope = enabled;
|
|
522
|
+
core.handle
|
|
523
|
+
};
|
|
524
|
+
if handle != NodeHandle::INVALID {
|
|
525
|
+
ui::set_is_shared_size_scope(handle.raw(), enabled);
|
|
526
|
+
crate::frame_scheduler::mark_needs_commit();
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
493
530
|
pub(crate) fn from_core(inner: Rc<RefCell<NodeCore>>) -> Self {
|
|
494
531
|
Self {
|
|
495
532
|
inner,
|
|
@@ -580,6 +617,7 @@ impl NodeRef {
|
|
|
580
617
|
self.inner.borrow_mut().children.push(child.clone());
|
|
581
618
|
self.inner.borrow_mut().children_built = false;
|
|
582
619
|
child.set_inherited_enabled(self.is_enabled_for_routing());
|
|
620
|
+
child.refresh_effective_visibility();
|
|
583
621
|
if self.handle() != NodeHandle::INVALID {
|
|
584
622
|
child.build();
|
|
585
623
|
ui::add_child(self.handle().raw(), child.handle().raw());
|
|
@@ -628,6 +666,7 @@ impl NodeRef {
|
|
|
628
666
|
};
|
|
629
667
|
removed.inner.borrow_mut().parent = Weak::new();
|
|
630
668
|
removed.set_inherited_enabled(true);
|
|
669
|
+
removed.refresh_effective_visibility();
|
|
631
670
|
parent.inner.borrow_mut().children_built = false;
|
|
632
671
|
if parent.handle() != NodeHandle::INVALID && self.handle() != NodeHandle::INVALID {
|
|
633
672
|
ui::remove_child(parent.handle().raw(), self.handle().raw());
|
|
@@ -644,14 +683,27 @@ impl NodeRef {
|
|
|
644
683
|
}
|
|
645
684
|
|
|
646
685
|
pub(crate) fn is_effectively_visible_for_routing(&self) -> bool {
|
|
686
|
+
self.effective_visibility_for_routing() == Visibility::Normal
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
fn effective_visibility_for_routing(&self) -> Visibility {
|
|
690
|
+
let mut result = Visibility::Normal;
|
|
647
691
|
let mut node = Some(self.clone());
|
|
648
692
|
while let Some(current) = node {
|
|
649
|
-
|
|
650
|
-
|
|
693
|
+
match current
|
|
694
|
+
.inner
|
|
695
|
+
.borrow()
|
|
696
|
+
.behavior
|
|
697
|
+
.visibility
|
|
698
|
+
.unwrap_or(Visibility::Normal)
|
|
699
|
+
{
|
|
700
|
+
Visibility::Collapsed => return Visibility::Collapsed,
|
|
701
|
+
Visibility::Hidden => result = Visibility::Hidden,
|
|
702
|
+
Visibility::Normal => {}
|
|
651
703
|
}
|
|
652
704
|
node = current.parent();
|
|
653
705
|
}
|
|
654
|
-
|
|
706
|
+
result
|
|
655
707
|
}
|
|
656
708
|
|
|
657
709
|
pub(crate) fn is_enabled_for_routing(&self) -> bool {
|
|
@@ -681,6 +733,20 @@ impl NodeRef {
|
|
|
681
733
|
self.apply_enabled_changed();
|
|
682
734
|
}
|
|
683
735
|
|
|
736
|
+
pub(crate) fn set_own_visibility(&self, visibility: Visibility) {
|
|
737
|
+
{
|
|
738
|
+
let mut core = self.inner.borrow_mut();
|
|
739
|
+
if core.behavior.visibility == Some(visibility) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
core.behavior.visibility = Some(visibility);
|
|
743
|
+
}
|
|
744
|
+
if visibility != Visibility::Normal {
|
|
745
|
+
self.cancel_drag_state();
|
|
746
|
+
}
|
|
747
|
+
self.refresh_effective_visibility();
|
|
748
|
+
}
|
|
749
|
+
|
|
684
750
|
pub(crate) fn set_inherited_enabled(&self, enabled: bool) {
|
|
685
751
|
{
|
|
686
752
|
let mut core = self.inner.borrow_mut();
|
|
@@ -700,6 +766,7 @@ impl NodeRef {
|
|
|
700
766
|
}
|
|
701
767
|
|
|
702
768
|
fn apply_enabled_changed(&self) {
|
|
769
|
+
let effectively_visible = self.is_effectively_visible_for_routing();
|
|
703
770
|
let (
|
|
704
771
|
effective,
|
|
705
772
|
handle,
|
|
@@ -721,10 +788,7 @@ impl NodeRef {
|
|
|
721
788
|
core.handle,
|
|
722
789
|
core.behavior.interactive,
|
|
723
790
|
core.behavior.focusable,
|
|
724
|
-
|
|
725
|
-
core.behavior.visibility,
|
|
726
|
-
Some(Visibility::Hidden | Visibility::Collapsed)
|
|
727
|
-
),
|
|
791
|
+
effectively_visible,
|
|
728
792
|
core.behavior.track_semantic_disabled_from_enabled,
|
|
729
793
|
core.effective_enabled_changed_callbacks.clone(),
|
|
730
794
|
core.children.clone(),
|
|
@@ -765,15 +829,52 @@ impl NodeRef {
|
|
|
765
829
|
.unwrap_or(CursorStyle::Default)
|
|
766
830
|
}
|
|
767
831
|
|
|
832
|
+
fn refresh_effective_visibility(&self) {
|
|
833
|
+
let effective_visibility = self.effective_visibility_for_routing();
|
|
834
|
+
let effective_visible = effective_visibility == Visibility::Normal;
|
|
835
|
+
let (handle, visibility, enabled, interactive, focusable, children) = {
|
|
836
|
+
let core = self.inner.borrow();
|
|
837
|
+
(
|
|
838
|
+
core.handle,
|
|
839
|
+
effective_visibility,
|
|
840
|
+
core.behavior.enabled && core.behavior.inherited_enabled,
|
|
841
|
+
core.behavior.interactive,
|
|
842
|
+
core.behavior.focusable,
|
|
843
|
+
core.children.clone(),
|
|
844
|
+
)
|
|
845
|
+
};
|
|
846
|
+
if handle != NodeHandle::INVALID {
|
|
847
|
+
ui::set_visibility(handle.raw(), visibility as u32);
|
|
848
|
+
ui::set_interactive(handle.raw(), enabled && effective_visible && interactive);
|
|
849
|
+
if let Some((focusable, tab_index)) = focusable {
|
|
850
|
+
ui::set_focusable(
|
|
851
|
+
handle.raw(),
|
|
852
|
+
enabled && effective_visible && focusable,
|
|
853
|
+
tab_index,
|
|
854
|
+
);
|
|
855
|
+
}
|
|
856
|
+
crate::frame_scheduler::mark_needs_commit();
|
|
857
|
+
}
|
|
858
|
+
for child in children {
|
|
859
|
+
child.refresh_effective_visibility();
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
768
863
|
pub(crate) fn require_interactive(&self) {
|
|
769
|
-
let
|
|
864
|
+
let visible = self.is_effectively_visible_for_routing();
|
|
865
|
+
let (handle, enabled, visible, changed) = {
|
|
770
866
|
let mut inner = self.inner.borrow_mut();
|
|
771
867
|
let changed = !inner.behavior.interactive;
|
|
772
868
|
inner.behavior.interactive = true;
|
|
773
|
-
(
|
|
869
|
+
(
|
|
870
|
+
inner.handle,
|
|
871
|
+
inner.behavior.enabled && inner.behavior.inherited_enabled,
|
|
872
|
+
visible,
|
|
873
|
+
changed,
|
|
874
|
+
)
|
|
774
875
|
};
|
|
775
876
|
if handle != NodeHandle::INVALID {
|
|
776
|
-
ui::set_interactive(handle.raw(), enabled);
|
|
877
|
+
ui::set_interactive(handle.raw(), enabled && visible);
|
|
777
878
|
if changed {
|
|
778
879
|
crate::frame_scheduler::mark_needs_commit();
|
|
779
880
|
}
|
|
@@ -1053,7 +1154,7 @@ impl NodeRef {
|
|
|
1053
1154
|
match event.event_type {
|
|
1054
1155
|
crate::ffi::PointerEventType::Down => {
|
|
1055
1156
|
crate::tool_tip_manager::ToolTipManager::handle_pointer_down(self);
|
|
1056
|
-
if let Some(handler) = handlers.pointer_down {
|
|
1157
|
+
if let Some(handler) = handlers.pointer_down.as_ref() {
|
|
1057
1158
|
handler(event);
|
|
1058
1159
|
}
|
|
1059
1160
|
if event.handled {
|
|
@@ -1074,7 +1175,7 @@ impl NodeRef {
|
|
|
1074
1175
|
matches!(event.pointer_type, PointerType::Touch | PointerType::Pen),
|
|
1075
1176
|
);
|
|
1076
1177
|
let mut core = self.inner.borrow_mut();
|
|
1077
|
-
core.drag_click_pending = handlers.
|
|
1178
|
+
core.drag_click_pending = handlers.has_pointer_click_handler();
|
|
1078
1179
|
core.drag_click_pending_count = event.click_count;
|
|
1079
1180
|
core.click_pending = false;
|
|
1080
1181
|
core.click_pending_count = 0;
|
|
@@ -1085,7 +1186,7 @@ impl NodeRef {
|
|
|
1085
1186
|
core.drag_click_pending = false;
|
|
1086
1187
|
core.drag_click_pending_count = 0;
|
|
1087
1188
|
core.click_pending =
|
|
1088
|
-
handlers.
|
|
1189
|
+
handlers.has_pointer_click_handler() && is_primary_activation_pointer(event);
|
|
1089
1190
|
core.click_pending_count = event.click_count;
|
|
1090
1191
|
}
|
|
1091
1192
|
crate::ffi::PointerEventType::Move => {
|
|
@@ -1115,7 +1216,7 @@ impl NodeRef {
|
|
|
1115
1216
|
}
|
|
1116
1217
|
}
|
|
1117
1218
|
crate::ffi::PointerEventType::Up => {
|
|
1118
|
-
if let Some(handler) = handlers.pointer_up {
|
|
1219
|
+
if let Some(handler) = handlers.pointer_up.as_ref() {
|
|
1119
1220
|
handler(event);
|
|
1120
1221
|
}
|
|
1121
1222
|
if event.handled {
|
|
@@ -1156,21 +1257,11 @@ impl NodeRef {
|
|
|
1156
1257
|
}
|
|
1157
1258
|
}
|
|
1158
1259
|
if can_fire_click {
|
|
1159
|
-
|
|
1160
|
-
event.click_count = if click_count > 0 { click_count } else { 1 };
|
|
1161
|
-
handler(event);
|
|
1162
|
-
}
|
|
1260
|
+
handlers.dispatch_pointer_click(event, click_count);
|
|
1163
1261
|
}
|
|
1164
1262
|
self.clear_click_pending_state();
|
|
1165
1263
|
if can_fire_pending_click {
|
|
1166
|
-
|
|
1167
|
-
event.click_count = if pending_click_count > 0 {
|
|
1168
|
-
pending_click_count
|
|
1169
|
-
} else {
|
|
1170
|
-
1
|
|
1171
|
-
};
|
|
1172
|
-
handler(event);
|
|
1173
|
-
}
|
|
1264
|
+
handlers.dispatch_pointer_click(event, pending_click_count);
|
|
1174
1265
|
}
|
|
1175
1266
|
self.clear_drag_click_pending_state();
|
|
1176
1267
|
}
|
|
@@ -1560,6 +1651,12 @@ impl NodeRef {
|
|
|
1560
1651
|
}
|
|
1561
1652
|
}
|
|
1562
1653
|
|
|
1654
|
+
/// Universal retained-node capabilities shared by every visual node and control.
|
|
1655
|
+
///
|
|
1656
|
+
/// Rust controls use composition rather than FUI-AS class inheritance, but this
|
|
1657
|
+
/// trait preserves the common retained identity, state, semantics, focus,
|
|
1658
|
+
/// routed-input, gesture, geometry, and child-inspection contract. Layout and
|
|
1659
|
+
/// appearance are exposed separately through the cohesive surface traits.
|
|
1563
1660
|
pub trait Node: Clone {
|
|
1564
1661
|
#[doc(hidden)]
|
|
1565
1662
|
fn node_ref(&self) -> NodeRef {
|
|
@@ -1579,15 +1676,67 @@ pub trait Node: Clone {
|
|
|
1579
1676
|
Vec::new()
|
|
1580
1677
|
}
|
|
1581
1678
|
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
Self: Sized,
|
|
1585
|
-
{
|
|
1679
|
+
#[doc(hidden)]
|
|
1680
|
+
fn apply_node_id(&self, node_id: String) {
|
|
1586
1681
|
let node_ref = self.node_ref();
|
|
1587
1682
|
node_ref.set_node_id(node_id);
|
|
1588
1683
|
if self.has_built_handle() {
|
|
1589
1684
|
self.notify_retained_mutation();
|
|
1590
1685
|
}
|
|
1686
|
+
}
|
|
1687
|
+
|
|
1688
|
+
#[doc(hidden)]
|
|
1689
|
+
fn apply_semantic_label(&self, label: String) {
|
|
1690
|
+
let node_ref = self.node_ref();
|
|
1691
|
+
node_ref.inner.borrow_mut().behavior.semantic_label = Some(label.clone());
|
|
1692
|
+
let handle = node_ref.handle();
|
|
1693
|
+
if handle != NodeHandle::INVALID {
|
|
1694
|
+
ui::set_semantic_label(handle.raw(), &label);
|
|
1695
|
+
self.notify_retained_mutation();
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
#[doc(hidden)]
|
|
1700
|
+
fn apply_focusable(&self, enabled: bool, tab_index: i32) {
|
|
1701
|
+
let node_ref = self.node_ref();
|
|
1702
|
+
if enabled {
|
|
1703
|
+
node_ref.require_interactive();
|
|
1704
|
+
}
|
|
1705
|
+
let visible = node_ref.is_effectively_visible_for_routing();
|
|
1706
|
+
let mut core = node_ref.inner.borrow_mut();
|
|
1707
|
+
core.behavior.focusable = Some((enabled, tab_index));
|
|
1708
|
+
let interactive = core.behavior.enabled && core.behavior.inherited_enabled && visible;
|
|
1709
|
+
let handle = core.handle;
|
|
1710
|
+
drop(core);
|
|
1711
|
+
if handle != NodeHandle::INVALID {
|
|
1712
|
+
ui::set_focusable(handle.raw(), interactive && enabled, tab_index);
|
|
1713
|
+
self.notify_retained_mutation();
|
|
1714
|
+
}
|
|
1715
|
+
}
|
|
1716
|
+
|
|
1717
|
+
#[doc(hidden)]
|
|
1718
|
+
fn apply_focus_now(&self) {
|
|
1719
|
+
let handle = self.node_ref().handle();
|
|
1720
|
+
if handle != NodeHandle::INVALID {
|
|
1721
|
+
ui::request_focus(handle.raw());
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
#[doc(hidden)]
|
|
1726
|
+
fn apply_enabled(&self, enabled: bool) {
|
|
1727
|
+
self.node_ref().set_own_enabled(enabled);
|
|
1728
|
+
}
|
|
1729
|
+
|
|
1730
|
+
#[doc(hidden)]
|
|
1731
|
+
fn apply_focus_changed_handler(&self, handler: Rc<dyn Fn(FocusChangedEventArgs)>) {
|
|
1732
|
+
self.node_ref().inner.borrow_mut().handlers.focus_changed = Some(handler);
|
|
1733
|
+
}
|
|
1734
|
+
|
|
1735
|
+
fn node_id(&self, node_id: impl Into<String>) -> &Self
|
|
1736
|
+
where
|
|
1737
|
+
Self: Sized,
|
|
1738
|
+
{
|
|
1739
|
+
self.apply_node_id(node_id.into());
|
|
1591
1740
|
self
|
|
1592
1741
|
}
|
|
1593
1742
|
|
|
@@ -1608,16 +1757,199 @@ pub trait Node: Clone {
|
|
|
1608
1757
|
where
|
|
1609
1758
|
Self: Sized,
|
|
1610
1759
|
{
|
|
1611
|
-
|
|
1760
|
+
self.apply_semantic_label(label.into());
|
|
1761
|
+
self
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
fn semantic_checked(&self, state: SemanticCheckedState) -> &Self
|
|
1765
|
+
where
|
|
1766
|
+
Self: Sized,
|
|
1767
|
+
{
|
|
1612
1768
|
let node_ref = self.node_ref();
|
|
1613
|
-
node_ref.inner.borrow_mut().behavior.
|
|
1769
|
+
node_ref.inner.borrow_mut().behavior.semantic_checked = Some(state);
|
|
1770
|
+
if self.has_built_handle() {
|
|
1771
|
+
ui::set_semantic_checked(self.handle().raw(), state as u32);
|
|
1772
|
+
self.notify_retained_mutation();
|
|
1773
|
+
}
|
|
1774
|
+
self
|
|
1775
|
+
}
|
|
1776
|
+
|
|
1777
|
+
fn semantic_disabled(&self, disabled: bool) -> &Self
|
|
1778
|
+
where
|
|
1779
|
+
Self: Sized,
|
|
1780
|
+
{
|
|
1781
|
+
let node_ref = self.node_ref();
|
|
1782
|
+
let mut core = node_ref.inner.borrow_mut();
|
|
1783
|
+
core.behavior.track_semantic_disabled_from_enabled = false;
|
|
1784
|
+
core.behavior.semantic_disabled = Some(disabled);
|
|
1785
|
+
drop(core);
|
|
1786
|
+
if self.has_built_handle() {
|
|
1787
|
+
ui::set_semantic_disabled(self.handle().raw(), true, disabled);
|
|
1788
|
+
self.notify_retained_mutation();
|
|
1789
|
+
}
|
|
1790
|
+
self
|
|
1791
|
+
}
|
|
1792
|
+
|
|
1793
|
+
fn clear_semantic_disabled(&self) -> &Self
|
|
1794
|
+
where
|
|
1795
|
+
Self: Sized,
|
|
1796
|
+
{
|
|
1797
|
+
let node_ref = self.node_ref();
|
|
1798
|
+
let mut core = node_ref.inner.borrow_mut();
|
|
1799
|
+
core.behavior.track_semantic_disabled_from_enabled = false;
|
|
1800
|
+
core.behavior.semantic_disabled = None;
|
|
1801
|
+
drop(core);
|
|
1802
|
+
if self.has_built_handle() {
|
|
1803
|
+
ui::set_semantic_disabled(self.handle().raw(), false, false);
|
|
1804
|
+
self.notify_retained_mutation();
|
|
1805
|
+
}
|
|
1806
|
+
self
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
fn semantic_selected(&self, selected: bool) -> &Self
|
|
1810
|
+
where
|
|
1811
|
+
Self: Sized,
|
|
1812
|
+
{
|
|
1813
|
+
self.node_ref()
|
|
1814
|
+
.inner
|
|
1815
|
+
.borrow_mut()
|
|
1816
|
+
.behavior
|
|
1817
|
+
.semantic_selected = Some(selected);
|
|
1818
|
+
if self.has_built_handle() {
|
|
1819
|
+
ui::set_semantic_selected(self.handle().raw(), true, selected);
|
|
1820
|
+
self.notify_retained_mutation();
|
|
1821
|
+
}
|
|
1822
|
+
self
|
|
1823
|
+
}
|
|
1824
|
+
|
|
1825
|
+
fn clear_semantic_selected(&self) -> &Self
|
|
1826
|
+
where
|
|
1827
|
+
Self: Sized,
|
|
1828
|
+
{
|
|
1829
|
+
self.node_ref()
|
|
1830
|
+
.inner
|
|
1831
|
+
.borrow_mut()
|
|
1832
|
+
.behavior
|
|
1833
|
+
.semantic_selected = None;
|
|
1834
|
+
if self.has_built_handle() {
|
|
1835
|
+
ui::set_semantic_selected(self.handle().raw(), false, false);
|
|
1836
|
+
self.notify_retained_mutation();
|
|
1837
|
+
}
|
|
1838
|
+
self
|
|
1839
|
+
}
|
|
1840
|
+
|
|
1841
|
+
fn semantic_expanded(&self, expanded: bool) -> &Self
|
|
1842
|
+
where
|
|
1843
|
+
Self: Sized,
|
|
1844
|
+
{
|
|
1845
|
+
self.node_ref()
|
|
1846
|
+
.inner
|
|
1847
|
+
.borrow_mut()
|
|
1848
|
+
.behavior
|
|
1849
|
+
.semantic_expanded = Some(expanded);
|
|
1850
|
+
if self.has_built_handle() {
|
|
1851
|
+
ui::set_semantic_expanded(self.handle().raw(), true, expanded);
|
|
1852
|
+
self.notify_retained_mutation();
|
|
1853
|
+
}
|
|
1854
|
+
self
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
fn clear_semantic_expanded(&self) -> &Self
|
|
1858
|
+
where
|
|
1859
|
+
Self: Sized,
|
|
1860
|
+
{
|
|
1861
|
+
self.node_ref()
|
|
1862
|
+
.inner
|
|
1863
|
+
.borrow_mut()
|
|
1864
|
+
.behavior
|
|
1865
|
+
.semantic_expanded = None;
|
|
1866
|
+
if self.has_built_handle() {
|
|
1867
|
+
ui::set_semantic_expanded(self.handle().raw(), false, false);
|
|
1868
|
+
self.notify_retained_mutation();
|
|
1869
|
+
}
|
|
1870
|
+
self
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
fn semantic_value_range(&self, value_now: f32, value_min: f32, value_max: f32) -> &Self
|
|
1874
|
+
where
|
|
1875
|
+
Self: Sized,
|
|
1876
|
+
{
|
|
1877
|
+
self.node_ref()
|
|
1878
|
+
.inner
|
|
1879
|
+
.borrow_mut()
|
|
1880
|
+
.behavior
|
|
1881
|
+
.semantic_value_range = Some((value_now, value_min, value_max));
|
|
1882
|
+
if self.has_built_handle() {
|
|
1883
|
+
ui::set_semantic_value_range(
|
|
1884
|
+
self.handle().raw(),
|
|
1885
|
+
true,
|
|
1886
|
+
value_now,
|
|
1887
|
+
value_min,
|
|
1888
|
+
value_max,
|
|
1889
|
+
);
|
|
1890
|
+
self.notify_retained_mutation();
|
|
1891
|
+
}
|
|
1892
|
+
self
|
|
1893
|
+
}
|
|
1894
|
+
|
|
1895
|
+
fn clear_semantic_value_range(&self) -> &Self
|
|
1896
|
+
where
|
|
1897
|
+
Self: Sized,
|
|
1898
|
+
{
|
|
1899
|
+
self.node_ref()
|
|
1900
|
+
.inner
|
|
1901
|
+
.borrow_mut()
|
|
1902
|
+
.behavior
|
|
1903
|
+
.semantic_value_range = None;
|
|
1904
|
+
if self.has_built_handle() {
|
|
1905
|
+
ui::set_semantic_value_range(self.handle().raw(), false, 0.0, 0.0, 0.0);
|
|
1906
|
+
self.notify_retained_mutation();
|
|
1907
|
+
}
|
|
1908
|
+
self
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
fn semantic_orientation(&self, orientation: Orientation) -> &Self
|
|
1912
|
+
where
|
|
1913
|
+
Self: Sized,
|
|
1914
|
+
{
|
|
1915
|
+
self.node_ref()
|
|
1916
|
+
.inner
|
|
1917
|
+
.borrow_mut()
|
|
1918
|
+
.behavior
|
|
1919
|
+
.semantic_orientation = Some(orientation);
|
|
1614
1920
|
if self.has_built_handle() {
|
|
1615
|
-
ui::
|
|
1921
|
+
ui::set_semantic_orientation(self.handle().raw(), orientation as u32);
|
|
1616
1922
|
self.notify_retained_mutation();
|
|
1617
1923
|
}
|
|
1618
1924
|
self
|
|
1619
1925
|
}
|
|
1620
1926
|
|
|
1927
|
+
fn request_semantic_announcement(&self) -> &Self
|
|
1928
|
+
where
|
|
1929
|
+
Self: Sized,
|
|
1930
|
+
{
|
|
1931
|
+
if self.has_built_handle() {
|
|
1932
|
+
ui::request_semantic_announcement(self.handle().raw());
|
|
1933
|
+
}
|
|
1934
|
+
self
|
|
1935
|
+
}
|
|
1936
|
+
|
|
1937
|
+
fn child_count(&self) -> usize {
|
|
1938
|
+
self.node_ref().children().len()
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
fn is_enabled(&self) -> bool {
|
|
1942
|
+
self.node_ref().is_enabled_for_routing()
|
|
1943
|
+
}
|
|
1944
|
+
|
|
1945
|
+
fn is_visible(&self) -> bool {
|
|
1946
|
+
self.node_ref().is_effectively_visible_for_routing()
|
|
1947
|
+
}
|
|
1948
|
+
|
|
1949
|
+
fn cursor_style(&self) -> CursorStyle {
|
|
1950
|
+
self.node_ref().cursor_style_for_routing()
|
|
1951
|
+
}
|
|
1952
|
+
|
|
1621
1953
|
fn persist_state(&self, adapter: Rc<dyn PersistedStateAdapter>) -> &Self
|
|
1622
1954
|
where
|
|
1623
1955
|
Self: Sized,
|
|
@@ -1670,7 +2002,11 @@ pub trait Node: Clone {
|
|
|
1670
2002
|
self
|
|
1671
2003
|
}
|
|
1672
2004
|
|
|
1673
|
-
|
|
2005
|
+
/// Handles the low-level routed pointer-click event.
|
|
2006
|
+
///
|
|
2007
|
+
/// This is not control activation. Use [`Button::on_click`](crate::Button::on_click)
|
|
2008
|
+
/// for a button action that also supports keyboard activation.
|
|
2009
|
+
fn on_pointer_click(&self, handler: impl Fn(&mut PointerEventArgs) + 'static) -> &Self
|
|
1674
2010
|
where
|
|
1675
2011
|
Self: Sized,
|
|
1676
2012
|
{
|
|
@@ -1680,6 +2016,28 @@ pub trait Node: Clone {
|
|
|
1680
2016
|
self
|
|
1681
2017
|
}
|
|
1682
2018
|
|
|
2019
|
+
/// Handles a low-level routed pointer double-click after the ordinary pointer-click callback.
|
|
2020
|
+
fn on_pointer_double_click(&self, handler: impl Fn(&mut PointerEventArgs) + 'static) -> &Self
|
|
2021
|
+
where
|
|
2022
|
+
Self: Sized,
|
|
2023
|
+
{
|
|
2024
|
+
let node_ref = self.node_ref();
|
|
2025
|
+
node_ref.inner.borrow_mut().handlers.pointer_double_click = Some(Rc::new(handler));
|
|
2026
|
+
node_ref.require_interactive();
|
|
2027
|
+
self
|
|
2028
|
+
}
|
|
2029
|
+
|
|
2030
|
+
/// Handles a low-level routed pointer triple-click after the ordinary pointer-click callback.
|
|
2031
|
+
fn on_pointer_triple_click(&self, handler: impl Fn(&mut PointerEventArgs) + 'static) -> &Self
|
|
2032
|
+
where
|
|
2033
|
+
Self: Sized,
|
|
2034
|
+
{
|
|
2035
|
+
let node_ref = self.node_ref();
|
|
2036
|
+
node_ref.inner.borrow_mut().handlers.pointer_triple_click = Some(Rc::new(handler));
|
|
2037
|
+
node_ref.require_interactive();
|
|
2038
|
+
self
|
|
2039
|
+
}
|
|
2040
|
+
|
|
1683
2041
|
fn on_pointer_down(&self, handler: impl Fn(&mut PointerEventArgs) + 'static) -> &Self
|
|
1684
2042
|
where
|
|
1685
2043
|
Self: Sized,
|
|
@@ -1792,22 +2150,55 @@ pub trait Node: Clone {
|
|
|
1792
2150
|
where
|
|
1793
2151
|
Self: Sized,
|
|
1794
2152
|
{
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
2153
|
+
self.apply_focusable(enabled, tab_index);
|
|
2154
|
+
self
|
|
2155
|
+
}
|
|
2156
|
+
|
|
2157
|
+
fn focus_now(&self) -> &Self
|
|
2158
|
+
where
|
|
2159
|
+
Self: Sized,
|
|
2160
|
+
{
|
|
2161
|
+
self.apply_focus_now();
|
|
2162
|
+
self
|
|
2163
|
+
}
|
|
2164
|
+
|
|
2165
|
+
fn enabled(&self, enabled: bool) -> &Self
|
|
2166
|
+
where
|
|
2167
|
+
Self: Sized,
|
|
2168
|
+
{
|
|
2169
|
+
self.apply_enabled(enabled);
|
|
2170
|
+
self
|
|
2171
|
+
}
|
|
2172
|
+
|
|
2173
|
+
fn visibility(&self, visibility: Visibility) -> &Self
|
|
2174
|
+
where
|
|
2175
|
+
Self: Sized,
|
|
2176
|
+
{
|
|
2177
|
+
self.node_ref().set_own_visibility(visibility);
|
|
2178
|
+
if self.has_built_handle() {
|
|
2179
|
+
self.notify_retained_layout_mutation();
|
|
1807
2180
|
}
|
|
1808
2181
|
self
|
|
1809
2182
|
}
|
|
1810
2183
|
|
|
2184
|
+
fn cursor(&self, style: CursorStyle) -> &Self
|
|
2185
|
+
where
|
|
2186
|
+
Self: Sized,
|
|
2187
|
+
{
|
|
2188
|
+
self.node_ref().inner.borrow_mut().behavior.cursor = Some(style);
|
|
2189
|
+
crate::event::handle_cursor_style_changed(self.handle());
|
|
2190
|
+
self
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
fn clear_cursor(&self) -> &Self
|
|
2194
|
+
where
|
|
2195
|
+
Self: Sized,
|
|
2196
|
+
{
|
|
2197
|
+
self.node_ref().inner.borrow_mut().behavior.cursor = None;
|
|
2198
|
+
crate::event::handle_cursor_style_changed(self.handle());
|
|
2199
|
+
self
|
|
2200
|
+
}
|
|
2201
|
+
|
|
1811
2202
|
fn on_key_down(&self, handler: impl Fn(&mut KeyEventArgs) + 'static) -> &Self
|
|
1812
2203
|
where
|
|
1813
2204
|
Self: Sized,
|
|
@@ -1828,7 +2219,7 @@ pub trait Node: Clone {
|
|
|
1828
2219
|
where
|
|
1829
2220
|
Self: Sized,
|
|
1830
2221
|
{
|
|
1831
|
-
self.
|
|
2222
|
+
self.apply_focus_changed_handler(Rc::new(handler));
|
|
1832
2223
|
self
|
|
1833
2224
|
}
|
|
1834
2225
|
|