Skip to content

Instantly share code, notes, and snippets.

@IronGremlin
Created March 4, 2024 17:03
Show Gist options
  • Save IronGremlin/6fc92844eb9851c5100d14c50c3b56e2 to your computer and use it in GitHub Desktop.
Save IronGremlin/6fc92844eb9851c5100d14c50c3b56e2 to your computer and use it in GitHub Desktop.
Bevy scrollbar
#[derive(Component)]
struct ScrollableElement {
mask: Entity,
content_container: Entity,
scroll_bar_element: Entity,
scroll_bar_handle: Entity,
scroll_value: f32,
}
impl ScrollableElement {
fn new(
mask: Entity,
content_container: Entity,
scroll_bar_element: Entity,
scroll_bar_handle: Entity,
) -> Self {
Self {
mask,
content_container,
scroll_bar_element,
scroll_bar_handle,
scroll_value: 0.0,
}
}
}
//...
fn scroll_node_with_drag(
mut q: Query<&mut ScrollableElement>,
mut nodes_and_styles: Query<(&Node, &mut Style), Without<ScrollableElement>>,
interaction: Query<(&Interaction, &RelativeCursorPosition)>,
) {
q.iter_mut().for_each(|mut scroll_element| {
if let Ok((int, pos)) = interaction.get(scroll_element.scroll_bar_element) {
match int {
Interaction::Pressed => {
if let Ok(
[(window, _), (content, mut content_style), (handle, mut handle_style)],
) = nodes_and_styles.get_many_mut([
scroll_element.mask,
scroll_element.content_container,
scroll_element.scroll_bar_handle,
]) {
let max_offset = (content.size().y - window.size().y).max(0.);
let handle_max_offset = (window.size().y - handle.size().y).max(0.);
if let Some(position) = pos.normalized {
scroll_element.scroll_value = -1.0 * (max_offset * position.y);
scroll_element.scroll_value =
scroll_element.scroll_value.clamp(-max_offset, 0.0);
let handle_scroll =
(handle_max_offset * position.y).clamp(0., handle_max_offset);
content_style.top = px(scroll_element.scroll_value);
handle_style.top = px(handle_scroll);
}
}
}
_ => {}
}
}
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment