forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdrag_to_scroll.rs
More file actions
115 lines (107 loc) · 4.18 KB
/
drag_to_scroll.rs
File metadata and controls
115 lines (107 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
//! This example tests scale factor, dragging and scrolling
use bevy::color::palettes::css::RED;
use bevy::prelude::*;
#[derive(Component)]
struct ScrollableNode;
#[derive(Component)]
struct TileColor(Color);
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.run();
}
#[derive(Component)]
struct ScrollStart(Vec2);
fn setup(mut commands: Commands) {
let w = 60;
let h = 40;
commands.spawn(Camera2d);
commands.insert_resource(UiScale(0.5));
commands
.spawn((
Node {
width: percent(100),
height: percent(100),
overflow: Overflow::scroll(),
..Default::default()
},
ScrollPosition(Vec2::ZERO),
ScrollableNode,
ScrollStart(Vec2::ZERO),
))
.observe(
|drag: On<Pointer<Drag>>,
ui_scale: Res<UiScale>,
mut scroll_position_query: Query<
(&mut ScrollPosition, &ScrollStart),
With<ScrollableNode>,
>| {
if let Ok((mut scroll_position, start)) = scroll_position_query.single_mut() {
scroll_position.0 = (start.0 - drag.distance / ui_scale.0).max(Vec2::ZERO);
}
},
)
.observe(
|_: On<Pointer<DragStart>>,
mut scroll_position_query: Query<
(&ComputedNode, &mut ScrollStart),
With<ScrollableNode>,
>| {
if let Ok((computed_node, mut start)) = scroll_position_query.single_mut() {
start.0 = computed_node.scroll_position * computed_node.inverse_scale_factor;
}
},
)
.with_children(|commands| {
commands
.spawn((
Node {
display: Display::Grid,
grid_template_rows: RepeatedGridTrack::px(w as i32, 100.),
grid_template_columns: RepeatedGridTrack::px(h as i32, 100.),
..default()
},
Pickable {
is_hoverable: false,
should_block_lower: true,
}
))
.with_children(|commands| {
for y in 0..h {
for x in 0..w {
let tile_color = if (x + y) % 2 == 1 {
let hue = ((x as f32 / w as f32) * 270.0)
+ ((y as f32 / h as f32) * 90.0);
Color::hsl(hue, 1., 0.5)
} else {
Color::BLACK
};
commands.spawn((
Node {
grid_row: GridPlacement::start(y + 1),
grid_column: GridPlacement::start(x + 1),
..default()
},
Pickable {
should_block_lower: false,
is_hoverable: true,
},
TileColor(tile_color),
BackgroundColor(tile_color),
))
.observe(|over: On<Pointer<Over>>, mut query: Query<&mut BackgroundColor>,| {
if let Ok(mut background_color) = query.get_mut(over.entity) {
background_color.0 = RED.into();
}
})
.observe(|out: On<Pointer<Out>>, mut query: Query<(&mut BackgroundColor, &TileColor)>| {
if let Ok((mut background_color, tile_color)) = query.get_mut(out.entity) {
background_color.0 = tile_color.0;
}
});
}
}
});
});
}