Add descriptions, touch basic support
This commit is contained in:
parent
eff6b3b06f
commit
a2643d1cae
|
|
@ -0,0 +1,5 @@
|
|||
# CHANGELOG
|
||||
|
||||
## [0.1.0]
|
||||
|
||||
- Initial version
|
||||
File diff suppressed because it is too large
Load Diff
13
Cargo.toml
13
Cargo.toml
|
|
@ -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"]
|
||||
|
|
|
|||
31
README.md
31
README.md
|
|
@ -1,11 +1,40 @@
|
|||
# Bevy Simple Scroll View
|
||||
|
||||
[](https://crates.io/crates/bevy_simple_scroll_view)
|
||||
[](https://docs.rs/bevy_simple_scroll_view)
|
||||
[](https://github.com/Leinnan/bevy_simple_scroll_view#license)
|
||||
[](https://bevyengine.org/learn/quick-start/plugin-development/#main-branch-tracking)
|
||||
[](https://crates.io/crates/bevy_simple_scroll_view)
|
||||
|
||||
Simple to use plugin implementing ScrollView into Bevy engine. Supports scroll using dragging and scrolling.
|
||||
|
||||

|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 340 KiB |
54
src/lib.rs
54
src/lib.rs
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue