Rename components, move scroll offset update to separate method

This commit is contained in:
Piotr Siuszko 2024-02-28 21:47:13 +01:00
parent 0a1c5494d6
commit 50823c3c39
2 changed files with 30 additions and 22 deletions

View File

@ -42,12 +42,12 @@ fn prepare(mut commands: Commands) {
background_color: BackgroundColor(Color::YELLOW), background_color: BackgroundColor(Color::YELLOW),
..default() ..default()
}, },
ScrollViewport::default(), ScrollView::default(),
)); ));
}); });
} }
fn add_content(mut commands: Commands, q: Query<Entity, Added<ScrollViewContent>>) { fn add_content(mut commands: Commands, q: Query<Entity, Added<ScrollableContent>>) {
for e in q.iter() { for e in q.iter() {
commands.entity(e).with_children(|parent| { commands.entity(e).with_children(|parent| {
for _ in 0..10 { for _ in 0..10 {

View File

@ -8,21 +8,27 @@ pub struct ScrollViewPlugin;
impl Plugin for ScrollViewPlugin { impl Plugin for ScrollViewPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.register_type::<ScrollViewport>() app.register_type::<ScrollView>()
.register_type::<ScrollViewContent>() .register_type::<ScrollableContent>()
.add_systems( .add_systems(
Update, Update,
(create_scroll_view, input_mouse_pressed_move, scroll_events), (
create_scroll_view,
input_mouse_pressed_move,
scroll_events,
scroll_update,
)
.chain(),
); );
} }
} }
#[derive(Component, Debug, Reflect)] #[derive(Component, Debug, Reflect)]
pub struct ScrollViewport { pub struct ScrollView {
pub scroll_speed: f32, pub scroll_speed: f32,
} }
impl Default for ScrollViewport { impl Default for ScrollView {
fn default() -> Self { fn default() -> Self {
Self { Self {
scroll_speed: 500.0, scroll_speed: 500.0,
@ -31,13 +37,13 @@ impl Default for ScrollViewport {
} }
#[derive(Component, Debug, Reflect)] #[derive(Component, Debug, Reflect)]
pub struct ScrollViewContent { pub struct ScrollableContent {
pub pos_y: f32, pub pos_y: f32,
} }
pub fn create_scroll_view( pub fn create_scroll_view(
mut commands: Commands, mut commands: Commands,
mut q: Query<(Entity, &mut Style), Added<ScrollViewport>>, mut q: Query<(Entity, &mut Style), Added<ScrollView>>,
) { ) {
for (e, mut style) in q.iter_mut() { for (e, mut style) in q.iter_mut() {
style.overflow = Overflow::clip(); style.overflow = Overflow::clip();
@ -55,7 +61,7 @@ pub fn create_scroll_view(
}, },
..default() ..default()
}, },
ScrollViewContent { pos_y: 0.0 }, ScrollableContent { pos_y: 0.0 },
)); ));
}); });
} }
@ -63,8 +69,8 @@ pub fn create_scroll_view(
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, &Node), With<ScrollViewport>>, mut q: Query<(&Children, &Interaction, &Node), With<ScrollView>>,
mut content_q: Query<(&mut Style, &mut ScrollViewContent, &Node)>, mut content_q: Query<(&mut ScrollableContent, &Node)>,
) { ) {
for evt in motion_evr.read() { for evt in motion_evr.read() {
for (children, &interaction, node) in q.iter_mut() { for (children, &interaction, node) in q.iter_mut() {
@ -74,23 +80,27 @@ fn input_mouse_pressed_move(
let container_height = node.size().y; let container_height = node.size().y;
for &child in children.iter() { for &child in children.iter() {
if let Ok(item) = content_q.get_mut(child) { if let Ok(item) = content_q.get_mut(child) {
let mut style = item.0; let mut scroll = item.0;
let mut scroll = item.1; let max_scroll = (item.1.size().y - container_height).max(0.0);
let max_scroll = (item.2.size().y - container_height).max(0.0);
scroll.pos_y += evt.delta.y; scroll.pos_y += evt.delta.y;
scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.); scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.);
style.top = Val::Px(scroll.pos_y);
} }
} }
} }
} }
} }
fn scroll_update(mut q: Query<(&ScrollableContent, &mut Style), Changed<ScrollableContent>>) {
for (scroll, mut style) in q.iter_mut() {
style.top = Val::Px(scroll.pos_y);
}
}
fn scroll_events( fn scroll_events(
mut scroll_evr: EventReader<MouseWheel>, mut scroll_evr: EventReader<MouseWheel>,
mut q: Query<(&Children, &Interaction, &ScrollViewport, &Node), With<ScrollViewport>>, mut q: Query<(&Children, &Interaction, &ScrollView, &Node), With<ScrollView>>,
time: Res<Time>, time: Res<Time>,
mut content_q: Query<(&mut Style, &mut ScrollViewContent, &Node)>, mut content_q: Query<(&mut ScrollableContent, &Node)>,
) { ) {
use bevy::input::mouse::MouseScrollUnit; use bevy::input::mouse::MouseScrollUnit;
for ev in scroll_evr.read() { for ev in scroll_evr.read() {
@ -109,12 +119,10 @@ fn scroll_events(
for &child in children.iter() { for &child in children.iter() {
if let Ok(item) = content_q.get_mut(child) { if let Ok(item) = content_q.get_mut(child) {
let y = y * time.delta().as_secs_f32() * scroll_view.scroll_speed; let y = y * time.delta().as_secs_f32() * scroll_view.scroll_speed;
let mut style = item.0; let mut scroll = item.0;
let mut scroll = item.1; let max_scroll = (item.1.size().y - container_height).max(0.0);
let max_scroll = (item.2.size().y - container_height).max(0.0);
scroll.pos_y += y; scroll.pos_y += y;
scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.); scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.);
style.top = Val::Px(scroll.pos_y);
} }
} }
} }