window_drag_move/
window_drag_move.rs1use bevy::{math::CompassOctant, prelude::*};
14
15#[derive(Resource, Debug)]
17enum LeftClickAction {
18 Nothing,
20 Move,
22 Resize,
24}
25
26#[derive(Resource)]
28struct ResizeDir(usize);
29
30const DIRECTIONS: [CompassOctant; 8] = [
32 CompassOctant::North,
33 CompassOctant::NorthEast,
34 CompassOctant::East,
35 CompassOctant::SouthEast,
36 CompassOctant::South,
37 CompassOctant::SouthWest,
38 CompassOctant::West,
39 CompassOctant::NorthWest,
40];
41
42fn main() {
43 App::new()
44 .add_plugins(DefaultPlugins.set(WindowPlugin {
45 primary_window: Some(Window {
46 decorations: false,
47 ..default()
48 }),
49 ..default()
50 }))
51 .insert_resource(ResizeDir(7))
52 .insert_resource(LeftClickAction::Move)
53 .add_systems(Startup, setup)
54 .add_systems(Update, (handle_input, move_or_resize_windows))
55 .run();
56}
57
58fn setup(mut commands: Commands) {
59 commands.spawn(Camera3d::default());
61
62 commands.spawn((
64 Node {
65 position_type: PositionType::Absolute,
66 padding: UiRect::all(px(5)),
67 ..default()
68 },
69 BackgroundColor(Color::BLACK.with_alpha(0.75)),
70 GlobalZIndex(i32::MAX),
71 children![(
72 Text::default(),
73 children![
74 TextSpan::new(
75 "Demonstrate drag move and drag resize without window decorations.\n\n",
76 ),
77 TextSpan::new("Controls:\n"),
78 TextSpan::new("A - change left click action ["),
79 TextSpan::new("Move"),
80 TextSpan::new("]\n"),
81 TextSpan::new("S / D - change resize direction ["),
82 TextSpan::new("NorthWest"),
83 TextSpan::new("]\n"),
84 ]
85 )],
86 ));
87}
88
89fn handle_input(
90 input: Res<ButtonInput<KeyCode>>,
91 mut action: ResMut<LeftClickAction>,
92 mut dir: ResMut<ResizeDir>,
93 example_text: Query<Entity, With<Text>>,
94 mut writer: TextUiWriter,
95) -> Result {
96 use LeftClickAction::*;
97 if input.just_pressed(KeyCode::KeyA) {
98 *action = match *action {
99 Move => Resize,
100 Resize => Nothing,
101 Nothing => Move,
102 };
103 *writer.text(example_text.single()?, 4) = format!("{:?}", *action);
104 }
105
106 if input.just_pressed(KeyCode::KeyS) {
107 dir.0 = dir
108 .0
109 .checked_sub(1)
110 .unwrap_or(DIRECTIONS.len().saturating_sub(1));
111 *writer.text(example_text.single()?, 7) = format!("{:?}", DIRECTIONS[dir.0]);
112 }
113
114 if input.just_pressed(KeyCode::KeyD) {
115 dir.0 = (dir.0 + 1) % DIRECTIONS.len();
116 *writer.text(example_text.single()?, 7) = format!("{:?}", DIRECTIONS[dir.0]);
117 }
118
119 Ok(())
120}
121
122fn move_or_resize_windows(
123 mut windows: Query<&mut Window>,
124 action: Res<LeftClickAction>,
125 input: Res<ButtonInput<MouseButton>>,
126 dir: Res<ResizeDir>,
127) {
128 if input.just_pressed(MouseButton::Left) {
133 for mut window in windows.iter_mut() {
134 match *action {
135 LeftClickAction::Nothing => (),
136 LeftClickAction::Move => window.start_drag_move(),
137 LeftClickAction::Resize => {
138 let d = DIRECTIONS[dir.0];
139 window.start_drag_resize(d);
140 }
141 }
142 }
143 }
144}