Add descriptions, touch basic support

This commit is contained in:
Piotr Siuszko 2024-02-29 16:23:30 +01:00
parent eff6b3b06f
commit a2643d1cae
7 changed files with 115 additions and 4339 deletions

5
CHANGELOG.md Normal file
View File

@ -0,0 +1,5 @@
# CHANGELOG
## [0.1.0]
- Initial version

4303
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,11 @@
name = "bevy_simple_scroll_view"
version = "0.1.0"
edition = "2021"
exclude = [".github/","wasm/"]
exclude = [".github/","wasm/", "record.gif"]
categories = ["game-development", "gui"]
keywords = ["bevy","ui"]
repository = "https://github.com/Leinnan/bevy_simple_scroll_view"
homepage = "https://github.com/Leinnan/bevy_simple_scroll_view"
license = "MIT OR Apache-2.0"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -12,12 +14,9 @@ license = "MIT OR Apache-2.0"
[dependencies.bevy]
version = "0.13"
default-features = false
features = ["bevy_ui", "bevy_asset", "bevy_text"]
features = ["bevy_ui", "bevy_asset", "bevy_text", "bevy_winit"]
[dev-dependencies.bevy]
version = "0.13"
default-features = true
[dev-dependencies]
bevy_egui = "0.25"
bevy-inspector-egui = "0.23"
default-features = false
features = ["bevy_ui", "bevy_asset", "bevy_text", "bevy_winit", "default_font"]

View File

@ -1,11 +1,40 @@
# Bevy Simple Scroll View
[![crates.io](https://img.shields.io/crates/v/bevy_simple_scroll_view.svg)](https://crates.io/crates/bevy_simple_scroll_view)
[![docs](https://docs.rs/bevy_simple_scroll_view/badge.svg)](https://docs.rs/bevy_simple_scroll_view)
[![license](https://img.shields.io/crates/l/bevy_simple_scroll_view)](https://github.com/Leinnan/bevy_simple_scroll_view#license)
[![Following released Bevy versions](https://img.shields.io/badge/Bevy%20tracking-released%20version-lightblue)](https://bevyengine.org/learn/quick-start/plugin-development/#main-branch-tracking)
[![crates.io](https://img.shields.io/crates/d/bevy_simple_scroll_view.svg)](https://crates.io/crates/bevy_simple_scroll_view)
Simple to use plugin implementing ScrollView into Bevy engine. Supports scroll using dragging and scrolling.
![Gif with plugin in action](record.gif)
More details available in [simple.rs example](examples/simple.rs).
## Installation
```sh
cargo add --git https://github.com/Leinnan/bevy_simple_scroll_view.git
cargo add bevy_simple_scroll_view
```
## Contributing
Please feel free to open a PR, but keep in mind this project's goals. This is meant to be a simple scroll view widget.
The code should be simple enough for users to quickly understand and modify for their own purposes.
Please keep PRs small and scoped to a single feature or fix.
## Planned features
- one big thing missing is support for the [TouchInput events](https://docs.rs/bevy/latest/bevy/input/touch/struct.TouchInput.html) so the mobile platforms would work well.
- horizontal scroll, should be pretty simple.
- **DOCS**
- _optional_ if there would be simple enough implementation I would consider adding scrollbars.
## Bevy compatibility table
Bevy version | crate version
--- | ---
0.13 | 0.1

View File

@ -1,17 +1,14 @@
use bevy::prelude::*;
use bevy_inspector_egui::quick::WorldInspectorPlugin;
use bevy_simple_scroll_view::*;
const BORDER_COLOR_ACTIVE: Color = Color::rgb(0.75, 0.52, 0.99);
const BACKGROUND_COLOR: Color = Color::rgb(0.15, 0.15, 0.15);
const CLR_1: Color = Color::rgb(0.168, 0.168, 0.168);
const CLR_2: Color = Color::rgb(0.109, 0.109, 0.109);
const CLR_3: Color = Color::rgb(0.569, 0.592, 0.647);
const CLR_4: Color = Color::rgb(0.902, 0.4, 0.004);
fn main() {
App::new()
.add_plugins((
DefaultPlugins,
ScrollViewPlugin,
WorldInspectorPlugin::new(),
))
.add_plugins((DefaultPlugins, ScrollViewPlugin))
.add_systems(Startup, prepare)
.add_systems(Update, reset_scroll)
.run();
@ -24,20 +21,24 @@ fn prepare(mut commands: Commands) {
style: Style {
width: Val::Percent(100.0),
height: Val::Percent(100.0),
margin: UiRect::all(Val::Px(15.0)),
padding: UiRect::all(Val::Px(15.0)),
..default()
},
background_color: Color::rgb(0.05, 0.05, 0.05).into(),
background_color: CLR_1.into(),
..default()
})
.with_children(|p| {
p.spawn(ButtonBundle {
style: Style {
margin: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(5.0)),
margin: UiRect::all(Val::Px(15.0)),
padding: UiRect::all(Val::Px(15.0)),
max_height: Val::Px(100.0),
border: UiRect::all(Val::Px(3.0)),
align_items: AlignItems::Center,
..default()
},
background_color: BORDER_COLOR_ACTIVE.into(),
background_color: CLR_2.into(),
border_color: CLR_4.into(),
..default()
})
.with_children(|p| {
@ -45,7 +46,7 @@ fn prepare(mut commands: Commands) {
"Reset scroll",
TextStyle {
font_size: 25.0,
color: Color::ANTIQUE_WHITE,
color: CLR_4,
..default()
},
));
@ -54,11 +55,10 @@ fn prepare(mut commands: Commands) {
NodeBundle {
style: Style {
width: Val::Percent(80.0),
height: Val::Percent(50.0),
margin: UiRect::all(Val::Px(15.0)),
..default()
},
background_color: BACKGROUND_COLOR.into(),
background_color: CLR_2.into(),
..default()
},
ScrollView::default(),
@ -68,6 +68,7 @@ fn prepare(mut commands: Commands) {
NodeBundle {
style: Style {
flex_direction: bevy::ui::FlexDirection::Column,
width: Val::Percent(100.0),
..default()
},
..default()
@ -75,18 +76,17 @@ fn prepare(mut commands: Commands) {
ScrollableContent::default(),
))
.with_children(|scroll_area| {
for i in 0..10 {
for i in 0..21 {
scroll_area
.spawn(NodeBundle {
style: Style {
width: Val::Percent(150.0),
margin: UiRect::all(Val::Px(5.0)),
border: UiRect::all(Val::Px(3.0)),
padding: UiRect::all(Val::Px(25.0)),
min_width: Val::Px(200.0),
margin: UiRect::all(Val::Px(15.0)),
border: UiRect::all(Val::Px(5.0)),
padding: UiRect::all(Val::Px(30.0)),
..default()
},
border_color: BORDER_COLOR_ACTIVE.into(),
background_color: BACKGROUND_COLOR.into(),
border_color: CLR_3.into(),
..default()
})
.with_children(|p| {
@ -95,7 +95,7 @@ fn prepare(mut commands: Commands) {
format!("Nr {}", i),
TextStyle {
font_size: 25.0,
color: Color::ANTIQUE_WHITE,
color: CLR_3,
..default()
},
)

BIN
record.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 KiB

View File

@ -1,9 +1,21 @@
#![doc = include_str!("../README.md")]
use bevy::{
input::mouse::{MouseMotion, MouseWheel},
prelude::*,
};
/// A `Plugin` providing the systems and components required to make a ScrollView work.
///
/// # Example
/// ```
/// use bevy::prelude::*;
/// use bevy_simple_scroll_view::;
///
/// App::new()
/// .add_plugins((DefaultPlugins,ScrollViewPlugin))
/// .run();
/// ```
pub struct ScrollViewPlugin;
impl Plugin for ScrollViewPlugin {
@ -15,6 +27,7 @@ impl Plugin for ScrollViewPlugin {
(
create_scroll_view,
input_mouse_pressed_move,
input_touch_pressed_move,
scroll_events,
scroll_update,
)
@ -23,21 +36,27 @@ impl Plugin for ScrollViewPlugin {
}
}
/// Root component of scroll, it should have clipped style.
#[derive(Component, Debug, Reflect)]
pub struct ScrollView {
/// Field which control speed of the scrolling.
/// Could be negative number to implement invert scroll
pub scroll_speed: f32,
}
impl Default for ScrollView {
fn default() -> Self {
Self {
scroll_speed: 100.0,
scroll_speed: 200.0,
}
}
}
/// Component containing offset value of the scroll container to the parent.
/// It is possible to update the field `pos_y` manually to move scrollview to desired location.
#[derive(Component, Debug, Reflect, Default)]
pub struct ScrollableContent {
/// Scroll container offset to the `ScrollView`.
pub pos_y: f32,
}
@ -77,9 +96,30 @@ fn input_mouse_pressed_move(
}
}
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 input_touch_pressed_move(
touches: Res<Touches>,
mut q: Query<(&Children, &Interaction, &Node), With<ScrollView>>,
mut content_q: Query<(&mut ScrollableContent, &Node)>,
) {
for t in touches.iter() {
let Some(touch) = touches.get_pressed(t.id()) else {
continue;
};
for (children, &interaction, node) in q.iter_mut() {
if interaction != Interaction::Pressed {
continue;
}
let container_height = node.size().y;
for &child in children.iter() {
if let Ok(item) = content_q.get_mut(child) {
let mut scroll = item.0;
let max_scroll = (item.1.size().y - container_height).max(0.0);
scroll.pos_y += touch.delta().y;
scroll.pos_y = scroll.pos_y.clamp(-max_scroll, 0.);
}
}
}
}
}
@ -115,3 +155,9 @@ fn scroll_events(
}
}
}
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);
}
}