fix(engine): settings panel scrollable via touch on Android
scroll_settings_panel only read MouseWheel, which is generated by desktop scroll wheels and two-finger OS-level scroll gestures. On Android, a single-finger swipe generates TouchInput, not MouseWheel, leaving the settings panel unscrollable on real touchscreen devices. Added touch_scroll_settings_panel: tracks touch start Y, applies the vertical delta from each Moved event to ScrollPosition, resets on lift. Registered TouchInput messages in SettingsPlugin::build so tests that use MinimalPlugins (which omit InputPlugin) don't fail with "Message not initialized". Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use bevy::input::mouse::{MouseScrollUnit, MouseWheel};
|
use bevy::input::mouse::{MouseScrollUnit, MouseWheel};
|
||||||
|
use bevy::input::touch::{TouchInput, TouchPhase};
|
||||||
use bevy::prelude::*;
|
use bevy::prelude::*;
|
||||||
use bevy::ui::{ComputedNode, UiGlobalTransform};
|
use bevy::ui::{ComputedNode, UiGlobalTransform};
|
||||||
use bevy::window::{WindowMoved, WindowResized};
|
use bevy::window::{WindowMoved, WindowResized};
|
||||||
@@ -357,6 +358,7 @@ impl Plugin for SettingsPlugin {
|
|||||||
.add_message::<ToggleSettingsRequestEvent>()
|
.add_message::<ToggleSettingsRequestEvent>()
|
||||||
.add_message::<InfoToastEvent>()
|
.add_message::<InfoToastEvent>()
|
||||||
.add_message::<bevy::input::mouse::MouseWheel>()
|
.add_message::<bevy::input::mouse::MouseWheel>()
|
||||||
|
.add_message::<bevy::input::touch::TouchInput>()
|
||||||
// `WindowResized` / `WindowMoved` are real Bevy window events
|
// `WindowResized` / `WindowMoved` are real Bevy window events
|
||||||
// and emitted by the windowing backend under `DefaultPlugins`,
|
// and emitted by the windowing backend under `DefaultPlugins`,
|
||||||
// but we register them explicitly here so the geometry watcher
|
// but we register them explicitly here so the geometry watcher
|
||||||
@@ -369,6 +371,7 @@ impl Plugin for SettingsPlugin {
|
|||||||
handle_volume_keys,
|
handle_volume_keys,
|
||||||
toggle_settings_screen,
|
toggle_settings_screen,
|
||||||
scroll_settings_panel,
|
scroll_settings_panel,
|
||||||
|
touch_scroll_settings_panel,
|
||||||
record_window_geometry_changes,
|
record_window_geometry_changes,
|
||||||
persist_window_geometry_after_debounce,
|
persist_window_geometry_after_debounce,
|
||||||
),
|
),
|
||||||
@@ -1367,6 +1370,43 @@ fn scroll_settings_panel(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Scrolls the settings panel in response to touch pan gestures (Android).
|
||||||
|
/// Tracks the most recent touch Y so each `Moved` event's delta can be
|
||||||
|
/// applied to `ScrollPosition`. `MouseWheel` handles desktop; this system
|
||||||
|
/// fills the gap for single-finger swipe on touchscreen devices.
|
||||||
|
fn touch_scroll_settings_panel(
|
||||||
|
mut touch_evr: MessageReader<TouchInput>,
|
||||||
|
screen: Res<SettingsScreen>,
|
||||||
|
mut scrollables: Query<&mut ScrollPosition, With<SettingsPanelScrollable>>,
|
||||||
|
mut last_y: Local<Option<f32>>,
|
||||||
|
) {
|
||||||
|
if !screen.0 {
|
||||||
|
touch_evr.clear();
|
||||||
|
*last_y = None;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for event in touch_evr.read() {
|
||||||
|
match event.phase {
|
||||||
|
TouchPhase::Started => {
|
||||||
|
*last_y = Some(event.position.y);
|
||||||
|
}
|
||||||
|
TouchPhase::Moved => {
|
||||||
|
if let Some(prev) = *last_y {
|
||||||
|
let delta = event.position.y - prev;
|
||||||
|
for mut sp in scrollables.iter_mut() {
|
||||||
|
// Swiping up (delta < 0) scrolls content down (sp.y increases).
|
||||||
|
sp.0.y = (sp.0.y - delta).max(0.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*last_y = Some(event.position.y);
|
||||||
|
}
|
||||||
|
TouchPhase::Ended | TouchPhase::Canceled => {
|
||||||
|
*last_y = None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Window geometry persistence
|
// Window geometry persistence
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user