ui_drag_and_drop/
ui_drag_and_drop.rs1use bevy::prelude::*;
4
5fn main() {
6 App::new()
7 .add_plugins(DefaultPlugins)
8 .add_systems(Startup, setup)
9 .run();
10}
11
12const COLUMNS: i16 = 10;
13const ROWS: i16 = 10;
14const TILE_SIZE: f32 = 40.;
15
16fn setup(mut commands: Commands) {
17 commands.spawn(Camera2d);
18 commands
19 .spawn((Node {
20 display: Display::Grid,
21 align_self: AlignSelf::Center,
22 justify_self: JustifySelf::Center,
23 ..Default::default()
24 }, Pickable::IGNORE, BackgroundColor(Color::srgb(0.4, 0.4, 0.4))))
25 .with_children(|parent| {
26 let tile_colors = [
27 Color::srgb(0.2, 0.2, 0.8),
28 Color::srgb(0.8, 0.2, 0.2)
29 ];
30 for column in 0..COLUMNS {
31 for row in 0..ROWS {
32 let i = column + row * COLUMNS;
33 let tile_color = tile_colors[((row % 2) + column) as usize % tile_colors.len()];
34 let tile_border_color = tile_color.darker(0.025);
35 parent
36 .spawn((
37 Node {
38 width: Val::Px(TILE_SIZE),
39 height: Val::Px(TILE_SIZE),
40 border: UiRect::all(Val::Px(4.)),
41 grid_row: GridPlacement::start(row + 1),
42 grid_column: GridPlacement::start(column + 1),
43 align_items: AlignItems::Center,
44 justify_content: JustifyContent::Center,
45 ..Default::default()
46 },
47 BorderColor::all(tile_border_color),
48 BackgroundColor(tile_color),
49 Outline {
50 width: Val::Px(2.),
51 offset: Val::ZERO,
52 color: Color::NONE,
53 },
54 Pickable {
55 should_block_lower: false,
56 is_hoverable: true,
57 },
58 GlobalZIndex::default()
59 ))
60 .observe(move |on_over: On<Pointer<Over>>, mut query: Query<(&mut BackgroundColor, &mut BorderColor)>| {
61 if let Ok((mut background_color, mut border_color)) = query.get_mut(on_over.event_target()) {
62 background_color.0 = tile_color.lighter(0.1);
63 border_color.set_all(tile_border_color.lighter(0.1));
64 }
65 })
66 .observe(move |on_out: On<Pointer<Out>>, mut query: Query<(&mut BackgroundColor, &mut BorderColor)>| {
67 if let Ok((mut background_color, mut border_color)) = query.get_mut(on_out.event_target()) {
68 background_color.0 = tile_color;
69 border_color.set_all(tile_border_color);
70 }
71 })
72 .observe(|on_drag_start: On<Pointer<DragStart>>, mut query: Query<(&mut Outline, &mut GlobalZIndex)>| {
73 if let Ok((mut outline, mut global_zindex, )) = query.get_mut(on_drag_start.event_target()) {
74 outline.color = Color::WHITE;
75 global_zindex.0 = 1;
76 }
77 })
78 .observe(|on_drag: On<Pointer<Drag>>, mut query: Query<&mut UiTransform>| {
79 if let Ok(mut transform) = query.get_mut(on_drag.event_target()) {
80 transform.translation = Val2::px(on_drag.distance.x, on_drag.distance.y);
81 }
82 })
83 .observe(move |on_drag_end: On<Pointer<DragEnd>>, mut query: Query<(&mut UiTransform, &mut Outline, &mut GlobalZIndex)>| {
84 if let Ok((mut transform, mut outline, mut global_zindex)) = query.get_mut(on_drag_end.event_target()) {
85 transform.translation = Val2::ZERO;
86 outline.color = Color::NONE;
87 global_zindex.0 = 0;
88 }
89 })
90 .observe(|on_drag_drop: On<Pointer<DragDrop>>, mut query: Query<&mut Node>| {
91 if let Ok([mut a, mut b]) = query.get_many_mut([on_drag_drop.event_target(), on_drag_drop.dropped]) {
92 core::mem::swap(&mut a.grid_row, &mut b.grid_row);
93 core::mem::swap(&mut a.grid_column, &mut b.grid_column);
94 }
95 })
96 .with_child((Text::new(format!("{i}")), Pickable::IGNORE));
97 }
98 }
99 });
100}