Skip to content

Commit 62de587

Browse files
committed
fix: guard picker taps during touch scroll
1 parent e04cef2 commit 62de587

2 files changed

Lines changed: 61 additions & 18 deletions

File tree

vizmat-core/src/ui.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ pub(crate) use picker::{
3939
set_structure_picker_keyboard_active, setup_structure_picker_panel,
4040
structure_picker_keyboard_search, structure_picker_result_buttons, structure_picker_scroll,
4141
structure_picker_toggle_button, update_structure_picker_scroll_indicator,
42-
StructurePickerCaretState, StructurePickerResultsScroll, StructurePickerState,
43-
StructurePickerToggleButton,
42+
StructurePickerCaretState, StructurePickerResultsScroll, StructurePickerSelectionState,
43+
StructurePickerState, StructurePickerToggleButton,
4444
};
4545

4646
const LAYER_GIZMO: RenderLayers = RenderLayers::layer(1);
@@ -1146,6 +1146,7 @@ pub(crate) fn setup_file_ui(mut commands: Commands, mut font_assets: ResMut<Asse
11461146
visible: false,
11471147
});
11481148
commands.insert_resource(StructurePickerCaretState::default());
1149+
commands.insert_resource(StructurePickerSelectionState::default());
11491150
let p = theme_palette(theme.mode);
11501151
let is_mobile = {
11511152
#[cfg(target_arch = "wasm32")]

vizmat-core/src/ui/picker.rs

Lines changed: 58 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ pub(crate) struct StructurePickerState {
5858
pub(crate) visible: bool,
5959
}
6060

61+
#[derive(Resource, Default)]
62+
pub(crate) struct StructurePickerSelectionState {
63+
pending: Option<(Entity, String)>,
64+
suppress_click: bool,
65+
}
66+
6167
#[derive(Resource)]
6268
pub(crate) struct StructurePickerCaretState {
6369
timer: Timer,
@@ -640,22 +646,30 @@ pub(crate) fn update_structure_picker_scroll_indicator(
640646
*visibility = Visibility::Inherited;
641647
}
642648

649+
#[allow(clippy::too_many_arguments)]
643650
pub(crate) fn structure_picker_scroll(
644651
mut mouse_wheel_events: EventReader<MouseWheel>,
645652
hover_map: Res<HoverMap>,
646653
scroll_nodes: Query<Entity, With<StructurePickerResultsScroll>>,
654+
panel_nodes: Query<Entity, With<StructurePickerPanel>>,
647655
mut scroll_positions: Query<&mut ScrollPosition>,
648656
parents: Query<&ChildOf>,
649657
touch_gesture_state: Res<TouchGestureState>,
650658
keyboard_input: Res<ButtonInput<KeyCode>>,
659+
mut picker_selection_state: ResMut<StructurePickerSelectionState>,
651660
) {
652-
let picker_hovered = scroll_nodes.iter().any(|scroll_root| {
653-
hover_map.iter().any(|(_, pointer_map)| {
654-
pointer_map
655-
.iter()
656-
.any(|(hovered, _)| is_descendant_or_self(*hovered, scroll_root, &parents))
657-
})
658-
});
661+
picker_selection_state.suppress_click = false;
662+
663+
let picker_hovered = panel_nodes
664+
.iter()
665+
.chain(scroll_nodes.iter())
666+
.any(|picker_root| {
667+
hover_map.iter().any(|(_, pointer_map)| {
668+
pointer_map
669+
.iter()
670+
.any(|(hovered, _)| is_descendant_or_self(*hovered, picker_root, &parents))
671+
})
672+
});
659673

660674
for mouse_wheel in mouse_wheel_events.read() {
661675
let (mut dx, mut dy) = match mouse_wheel.unit {
@@ -692,7 +706,9 @@ pub(crate) fn structure_picker_scroll(
692706
}
693707
}
694708

695-
if picker_hovered && touch_gesture_state.rotate.length_squared() > 0.0004 {
709+
let rotate_drag = touch_gesture_state.rotate.length_squared() > 0.0004;
710+
if picker_hovered && rotate_drag {
711+
picker_selection_state.suppress_click = true;
696712
for scroll_root in scroll_nodes.iter() {
697713
if let Ok(mut scroll_position) = scroll_positions.get_mut(scroll_root) {
698714
scroll_position.offset_x -= touch_gesture_state.rotate.x;
@@ -719,6 +735,7 @@ fn is_descendant_or_self(mut entity: Entity, ancestor: Entity, parents: &Query<&
719735
pub(crate) fn structure_picker_result_buttons(
720736
mut interaction_query: Query<
721737
(
738+
Entity,
722739
&Interaction,
723740
&StructurePickerResultButton,
724741
&mut BackgroundColor,
@@ -729,27 +746,52 @@ pub(crate) fn structure_picker_result_buttons(
729746
mut file_drag_drop: ResMut<crate::io::FileDragDrop>,
730747
catalog_channel: Option<Res<CatalogLoadChannel>>,
731748
theme: Res<UiTheme>,
749+
mut picker_selection_state: ResMut<StructurePickerSelectionState>,
732750
) {
733-
for (interaction, selected, mut background) in &mut interaction_query {
751+
let mut selected_path = None;
752+
753+
for (entity, interaction, selected, mut background) in &mut interaction_query {
734754
match *interaction {
735755
Interaction::Pressed => {
736756
*background = BackgroundColor(themed_button_bg(theme.mode, Interaction::Pressed));
737-
super::load_structure_from_catalog_path(
738-
&selected.path,
739-
&mut file_drag_drop,
740-
catalog_channel.as_deref(),
741-
);
742-
picker.visible = false;
743-
set_structure_picker_keyboard_active(false);
757+
if !picker_selection_state.suppress_click {
758+
picker_selection_state.pending = Some((entity, selected.path.clone()));
759+
}
744760
}
745761
Interaction::Hovered => {
746762
*background = BackgroundColor(themed_button_bg(theme.mode, Interaction::Hovered));
763+
764+
if let Some((pending_entity, pending_path)) = picker_selection_state.pending.take()
765+
{
766+
if pending_entity == entity {
767+
if !picker_selection_state.suppress_click {
768+
selected_path = Some(pending_path);
769+
}
770+
} else {
771+
picker_selection_state.pending = Some((pending_entity, pending_path));
772+
}
773+
}
747774
}
748775
Interaction::None => {
749776
*background = BackgroundColor(themed_button_bg(theme.mode, Interaction::None));
777+
if let Some((pending_entity, _)) = picker_selection_state.pending.as_ref() {
778+
if *pending_entity == entity {
779+
picker_selection_state.pending = None;
780+
}
781+
}
750782
}
751783
}
752784
}
785+
786+
if let Some(path) = selected_path {
787+
super::load_structure_from_catalog_path(
788+
&path,
789+
&mut file_drag_drop,
790+
catalog_channel.as_deref(),
791+
);
792+
picker.visible = false;
793+
set_structure_picker_keyboard_active(false);
794+
}
753795
}
754796

755797
fn structure_matches_query(path: &str, query: &str) -> bool {

0 commit comments

Comments
 (0)