Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/window/window_drag_move.rs
6595 views
1
//! This example illustrates drag move and drag resize without window
2
//! decorations.
3
//!
4
//! When window decorations are not present, the user cannot drag a window by
5
//! its titlebar to change its position. The `start_drag_move()` function
6
//! permits a user to drag a window by left clicking anywhere in the window;
7
//! left click must be pressed and other constraints can be imposed. For
8
//! instance an application could require a user to hold down alt and left click
9
//! to drag a window.
10
//!
11
//! The `start_drag_resize()` function behaves similarly but permits a window to
12
//! be resized.
13
use bevy::{math::CompassOctant, prelude::*};
14
15
/// Determine what do on left click.
16
#[derive(Resource, Debug)]
17
enum LeftClickAction {
18
/// Do nothing.
19
Nothing,
20
/// Move the window on left click.
21
Move,
22
/// Resize the window on left click.
23
Resize,
24
}
25
26
/// What direction index should the window resize toward.
27
#[derive(Resource)]
28
struct ResizeDir(usize);
29
30
/// Directions that the drag resizes the window toward.
31
const 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
42
fn 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
58
fn setup(mut commands: Commands) {
59
// Camera
60
commands.spawn(Camera3d::default());
61
62
// UI
63
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
89
fn 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
122
fn 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
// Both `start_drag_move()` and `start_drag_resize()` must be called after a
129
// left mouse button press as done here.
130
//
131
// winit 0.30.5 may panic when initiated without a left mouse button press.
132
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
}
145
146