Boundaries

This commit is contained in:
Piotr Siuszko 2024-02-28 18:55:25 +01:00
parent 5bd8d79dda
commit cead07f3ab
1 changed files with 41 additions and 36 deletions

View File

@ -28,14 +28,14 @@ pub struct ScrollViewport {
impl Default for ScrollViewport { impl Default for ScrollViewport {
fn default() -> Self { fn default() -> Self {
Self { Self { scroll_speed: 500.0 }
scroll_speed: 500.0,
}
} }
} }
#[derive(Component, Debug, Reflect)] #[derive(Component, Debug, Reflect)]
pub struct ScrollViewContent(pub Entity); pub struct ScrollViewContent {
pub pos_y: f32,
}
pub fn create_scroll_view(mut commands: Commands, q: Query<Entity, Added<ScrollView>>) { pub fn create_scroll_view(mut commands: Commands, q: Query<Entity, Added<ScrollView>>) {
for e in q.iter() { for e in q.iter() {
@ -44,6 +44,9 @@ pub fn create_scroll_view(mut commands: Commands, q: Query<Entity, Added<ScrollV
NodeBundle { NodeBundle {
style: Style { style: Style {
overflow: Overflow::clip(), overflow: Overflow::clip(),
max_height: Val::Percent(100.0),
max_width: Val::Percent(100.0),
align_items: AlignItems::Start,
..default() ..default()
}, },
..Default::default() ..Default::default()
@ -60,7 +63,7 @@ pub fn create_scroll_view(mut commands: Commands, q: Query<Entity, Added<ScrollV
}, },
..default() ..default()
}, },
ScrollViewContent(e), ScrollViewContent { pos_y: 0.0 },
)); ));
}); });
}); });
@ -69,21 +72,23 @@ pub fn create_scroll_view(mut commands: Commands, q: Query<Entity, Added<ScrollV
fn input_mouse_pressed_move( fn input_mouse_pressed_move(
mut motion_evr: EventReader<MouseMotion>, mut motion_evr: EventReader<MouseMotion>,
mut q: Query<(&Children, &Interaction), With<ScrollViewport>>, mut q: Query<(&Children, &Interaction, &Node), With<ScrollViewport>>,
mut content_q: Query<&mut Style, With<ScrollViewContent>>, mut content_q: Query<(&mut Style, &mut ScrollViewContent, &Node)>,
) { ) {
for evt in motion_evr.read() { for evt in motion_evr.read() {
info!("{:?}", evt); for (children, &interaction, node) in q.iter_mut() {
for (children, &interaction) in q.iter_mut() {
if interaction != Interaction::Pressed { if interaction != Interaction::Pressed {
continue; continue;
} }
let container_height = node.size().y;
for &child in children.iter() { for &child in children.iter() {
if let Ok(mut style) = content_q.get_mut(child) { if let Ok(item) = content_q.get_mut(child) {
style.top = match style.top { let mut style = item.0;
Val::Px(px) => Val::Px(px + evt.delta.y), let mut scroll = item.1;
_ => Val::Px(0.0), let max_scroll = (item.2.size().y - container_height).max(0.0);
} scroll.pos_y += evt.delta.y;
scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.);
style.top = Val::Px(scroll.pos_y);
} }
} }
} }
@ -92,33 +97,33 @@ fn input_mouse_pressed_move(
fn scroll_events( fn scroll_events(
mut scroll_evr: EventReader<MouseWheel>, mut scroll_evr: EventReader<MouseWheel>,
mut q: Query<(&mut Style, &Interaction, &ScrollViewport), With<ScrollViewport>>, mut q: Query<(&Children, &Interaction, &ScrollViewport, &Node), With<ScrollViewport>>,
time: Res<Time>, time: Res<Time>,
mut content_q: Query<(&mut Style, &mut ScrollViewContent, &Node)>,
) { ) {
use bevy::input::mouse::MouseScrollUnit; use bevy::input::mouse::MouseScrollUnit;
for ev in scroll_evr.read() { for ev in scroll_evr.read() {
let y = match ev.unit { for (children, &interaction, scroll_view, node) in q.iter_mut() {
MouseScrollUnit::Line => { let y = match ev.unit {
println!( MouseScrollUnit::Line => {
"Scroll (line units): vertical: {}, horizontal: {}", ev.y * time.delta().as_secs_f32() * scroll_view.scroll_speed
ev.y, ev.x }
); MouseScrollUnit::Pixel => ev.y,
ev.y };
if interaction != Interaction::Hovered {
continue;
} }
MouseScrollUnit::Pixel => { let container_height = node.size().y;
println!(
"Scroll (pixel units): vertical: {}, horizontal: {}", for &child in children.iter() {
ev.y, ev.x if let Ok(item) = content_q.get_mut(child) {
); let y = y * time.delta().as_secs_f32() * scroll_view.scroll_speed;
ev.y let mut style = item.0;
} let mut scroll = item.1;
}; let max_scroll = (item.2.size().y - container_height).max(0.0);
for (mut style, &interaction, scroll_view) in q.iter_mut() { scroll.pos_y += y;
if interaction == Interaction::Hovered { scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.);
let y = y * time.delta().as_secs_f32() * scroll_view.scroll_speed; style.top = Val::Px(scroll.pos_y);
style.top = match style.top {
Val::Px(px) => Val::Px(px + y),
_ => Val::Px(0.0),
} }
} }
} }