From ac7ae35cd5418c2b0b4a5fdb298175cedad28aaf Mon Sep 17 00:00:00 2001 From: Ben Frankel Date: Sat, 9 Dec 2023 22:09:12 -0800 Subject: [PATCH] Update scrollbar while scrolling --- src/simulation/sprite_pack.rs | 2 +- src/state/editor_screen/outline_panel.rs | 33 ++++++++++++++---------- src/ui/scroll.rs | 32 +++++++++++++---------- 3 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/simulation/sprite_pack.rs b/src/simulation/sprite_pack.rs index 870783e..8442e1b 100644 --- a/src/simulation/sprite_pack.rs +++ b/src/simulation/sprite_pack.rs @@ -348,7 +348,7 @@ impl SkinSet { // Make a reasonable attempt to prevent duplicates const MAX_ATTEMPTS: usize = 64; for _ in 0..MAX_ATTEMPTS { - let skin = self.sprite_pack.random(&atlas_list, &mut rng); + let skin = self.sprite_pack.random(atlas_list, &mut rng); if !self.skins.contains(&skin) { self.skins.push(skin); return true; diff --git a/src/state/editor_screen/outline_panel.rs b/src/state/editor_screen/outline_panel.rs index 9e7754a..bdc19df 100644 --- a/src/state/editor_screen/outline_panel.rs +++ b/src/state/editor_screen/outline_panel.rs @@ -123,38 +123,43 @@ pub fn spawn_outline_panel(commands: &mut Commands, theme: &EditorScreenTheme) - .set_parent(hbox) .id(); - commands + let scrollbar = commands .spawn(( - Name::new("OutlineContainer"), + Name::new("OutlineScrollbar"), NodeBundle { style: Style { - width: Percent(100.0), - flex_direction: FlexDirection::Column, + width: Px(8.0), + height: Percent(100.0), + justify_self: JustifySelf::End, ..default() }, + // TODO + background_color: theme.info_bar_background_color.into(), ..default() }, - ScrollContent::with_sensitivity(2.0), - IsOutlineContainer, )) - .set_parent(scroll_view); + .set_parent(hbox) + .id(); commands .spawn(( - Name::new("OutlineScrollbar"), + Name::new("OutlineContainer"), NodeBundle { style: Style { - width: Px(8.0), - height: Percent(100.0), - justify_self: JustifySelf::End, + width: Percent(100.0), + flex_direction: FlexDirection::Column, ..default() }, - // TODO - background_color: theme.info_bar_background_color.into(), ..default() }, + ScrollContent { + position: 0.0, + sensitivity: 1.5, + scrollbar, + }, + IsOutlineContainer, )) - .set_parent(hbox); + .set_parent(scroll_view); outline_panel } diff --git a/src/ui/scroll.rs b/src/ui/scroll.rs index d38ce8b..7396bc3 100644 --- a/src/ui/scroll.rs +++ b/src/ui/scroll.rs @@ -13,24 +13,17 @@ impl Plugin for ScrollPlugin { } } -#[derive(Component, Reflect, Default)] +#[derive(Component, Reflect)] pub struct ScrollContent { - position: f32, - sensitivity: f32, -} - -impl ScrollContent { - pub fn with_sensitivity(sensitivity: f32) -> Self { - Self { - sensitivity, - ..default() - } - } + pub position: f32, + pub sensitivity: f32, + pub scrollbar: Entity, } fn mouse_scroll( mut events: EventReader, mut scroll_query: Query<(&mut ScrollContent, &mut Style, &Parent, &Node)>, + mut scrollbar_query: Query<&mut Style, Without>, node_query: Query<&Node>, ) { let pixels = events @@ -49,9 +42,20 @@ fn mouse_scroll( let height = node.size().y; let parent_height = node_query.get(parent.get()).unwrap().size().y; - let max_scroll = (height - parent_height).max(0.0); - scroll.position = scroll.position.clamp(-max_scroll, 0.0); + if parent_height <= 0.0 { + return; + } + let overflow = (height - parent_height).max(0.0); + scroll.position = scroll.position.clamp(-overflow, 0.0); style.top = Val::Px(scroll.position); + + // Update scrollbar + if let Ok(mut style) = scrollbar_query.get_mut(scroll.scrollbar) { + let height = (1.0 - overflow / parent_height).max(0.1); + let top = (-scroll.position / parent_height).max(1.0 - height); + style.height = Val::Percent(100.0 * height); + style.top = Val::Percent(100.0 * top); + } } }