mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 12:43:34 +00:00
Add Window Resize Constraints (#1409)
You should be able to set the minimum and maximum desired resolution of a system window. This also fixes a bug on Windows operating system: When you try to resize to 0 on the height it crashes. Co-authored-by: Carter Anderson <mcanders1@gmail.com>
This commit is contained in:
parent
4c1bc33b52
commit
8dcba7f4a1
4 changed files with 120 additions and 1 deletions
|
@ -1,5 +1,5 @@
|
|||
use bevy_math::{IVec2, Vec2};
|
||||
use bevy_utils::Uuid;
|
||||
use bevy_utils::{tracing::warn, Uuid};
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub struct WindowId(Uuid);
|
||||
|
@ -32,6 +32,64 @@ impl Default for WindowId {
|
|||
}
|
||||
}
|
||||
|
||||
/// The size limits on a window.
|
||||
/// These values are measured in logical pixels, so the user's
|
||||
/// scale factor does affect the size limits on the window.
|
||||
/// Please note that if the window is resizable, then when the window is
|
||||
/// maximized it may have a size outside of these limits. The functionality
|
||||
/// required to disable maximizing is not yet exposed by winit.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct WindowResizeConstraints {
|
||||
pub min_width: f32,
|
||||
pub min_height: f32,
|
||||
pub max_width: f32,
|
||||
pub max_height: f32,
|
||||
}
|
||||
|
||||
impl Default for WindowResizeConstraints {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
min_width: 180.,
|
||||
min_height: 120.,
|
||||
max_width: f32::INFINITY,
|
||||
max_height: f32::INFINITY,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl WindowResizeConstraints {
|
||||
pub fn check_constraints(&self) -> WindowResizeConstraints {
|
||||
let WindowResizeConstraints {
|
||||
mut min_width,
|
||||
mut min_height,
|
||||
mut max_width,
|
||||
mut max_height,
|
||||
} = self;
|
||||
min_width = min_width.max(1.);
|
||||
min_height = min_height.max(1.);
|
||||
if max_width < min_width {
|
||||
warn!(
|
||||
"The given maximum width {} is smaller than the minimum width {}",
|
||||
max_width, min_width
|
||||
);
|
||||
max_width = min_width;
|
||||
}
|
||||
if max_height < min_height {
|
||||
warn!(
|
||||
"The given maximum height {} is smaller than the minimum height {}",
|
||||
max_height, min_height
|
||||
);
|
||||
max_height = min_height;
|
||||
}
|
||||
WindowResizeConstraints {
|
||||
min_width,
|
||||
min_height,
|
||||
max_width,
|
||||
max_height,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An operating system window that can present content and receive user input.
|
||||
///
|
||||
/// ## Window Sizes
|
||||
|
@ -54,6 +112,7 @@ pub struct Window {
|
|||
requested_height: f32,
|
||||
physical_width: u32,
|
||||
physical_height: u32,
|
||||
resize_constraints: WindowResizeConstraints,
|
||||
position: Option<IVec2>,
|
||||
scale_factor_override: Option<f64>,
|
||||
backend_scale_factor: f64,
|
||||
|
@ -114,6 +173,9 @@ pub enum WindowCommand {
|
|||
SetPosition {
|
||||
position: IVec2,
|
||||
},
|
||||
SetResizeConstraints {
|
||||
resize_constraints: WindowResizeConstraints,
|
||||
},
|
||||
}
|
||||
|
||||
/// Defines the way a window is displayed
|
||||
|
@ -144,6 +206,7 @@ impl Window {
|
|||
position,
|
||||
physical_width,
|
||||
physical_height,
|
||||
resize_constraints: window_descriptor.resize_constraints,
|
||||
scale_factor_override: window_descriptor.scale_factor_override,
|
||||
backend_scale_factor: scale_factor,
|
||||
title: window_descriptor.title.clone(),
|
||||
|
@ -210,6 +273,12 @@ impl Window {
|
|||
self.physical_height
|
||||
}
|
||||
|
||||
/// The window's client resize constraint in logical pixels.
|
||||
#[inline]
|
||||
pub fn resize_constraints(&self) -> WindowResizeConstraints {
|
||||
self.resize_constraints
|
||||
}
|
||||
|
||||
/// The window's client position in physical pixels.
|
||||
#[inline]
|
||||
pub fn position(&self) -> Option<IVec2> {
|
||||
|
@ -250,6 +319,13 @@ impl Window {
|
|||
.push(WindowCommand::SetPosition { position })
|
||||
}
|
||||
|
||||
/// Modifies the minimum and maximum window bounds for resizing in logical pixels.
|
||||
#[inline]
|
||||
pub fn set_resize_constraints(&mut self, resize_constraints: WindowResizeConstraints) {
|
||||
self.command_queue
|
||||
.push(WindowCommand::SetResizeConstraints { resize_constraints });
|
||||
}
|
||||
|
||||
/// Request the OS to resize the window such the the client area matches the
|
||||
/// specified width and height.
|
||||
#[allow(clippy::float_cmp)]
|
||||
|
@ -257,6 +333,7 @@ impl Window {
|
|||
if self.requested_width == width && self.requested_height == height {
|
||||
return;
|
||||
}
|
||||
|
||||
self.requested_width = width;
|
||||
self.requested_height = height;
|
||||
self.command_queue.push(WindowCommand::SetResolution {
|
||||
|
@ -437,6 +514,7 @@ impl Window {
|
|||
pub struct WindowDescriptor {
|
||||
pub width: f32,
|
||||
pub height: f32,
|
||||
pub resize_constraints: WindowResizeConstraints,
|
||||
pub scale_factor_override: Option<f64>,
|
||||
pub title: String,
|
||||
pub vsync: bool,
|
||||
|
@ -455,6 +533,7 @@ impl Default for WindowDescriptor {
|
|||
title: "bevy".to_string(),
|
||||
width: 1280.,
|
||||
height: 720.,
|
||||
resize_constraints: WindowResizeConstraints::default(),
|
||||
scale_factor_override: None,
|
||||
vsync: true,
|
||||
resizable: true,
|
||||
|
|
|
@ -21,6 +21,7 @@ x11 = ["winit/x11"]
|
|||
bevy_app = { path = "../bevy_app", version = "0.4.0" }
|
||||
bevy_ecs = { path = "../bevy_ecs", version = "0.4.0" }
|
||||
bevy_input = { path = "../bevy_input", version = "0.4.0" }
|
||||
bevy_log = { path = "../bevy_log", version = "0.4.0" }
|
||||
bevy_math = { path = "../bevy_math", version = "0.4.0" }
|
||||
bevy_window = { path = "../bevy_window", version = "0.4.0" }
|
||||
bevy_utils = { path = "../bevy_utils", version = "0.4.0" }
|
||||
|
|
|
@ -25,6 +25,7 @@ use winit::{
|
|||
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
|
||||
};
|
||||
|
||||
use winit::dpi::LogicalSize;
|
||||
#[cfg(any(
|
||||
target_os = "linux",
|
||||
target_os = "dragonfly",
|
||||
|
@ -139,6 +140,24 @@ fn change_window(_: &mut World, resources: &mut Resources) {
|
|||
y: position[1],
|
||||
});
|
||||
}
|
||||
bevy_window::WindowCommand::SetResizeConstraints { resize_constraints } => {
|
||||
let window = winit_windows.get_window(id).unwrap();
|
||||
let constraints = resize_constraints.check_constraints();
|
||||
let min_inner_size = LogicalSize {
|
||||
width: constraints.min_width,
|
||||
height: constraints.min_height,
|
||||
};
|
||||
let max_inner_size = LogicalSize {
|
||||
width: constraints.max_width,
|
||||
height: constraints.max_height,
|
||||
};
|
||||
if constraints.max_width.is_finite() && constraints.max_height.is_finite() {
|
||||
window.set_min_inner_size(Some(min_inner_size));
|
||||
window.set_max_inner_size(Some(max_inner_size));
|
||||
} else {
|
||||
window.set_min_inner_size(Some(min_inner_size));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use bevy_math::IVec2;
|
||||
use bevy_utils::HashMap;
|
||||
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
|
||||
use winit::dpi::LogicalSize;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct WinitWindows {
|
||||
|
@ -59,6 +60,25 @@ impl WinitWindows {
|
|||
.with_decorations(window_descriptor.decorations),
|
||||
};
|
||||
|
||||
let constraints = window_descriptor.resize_constraints.check_constraints();
|
||||
let min_inner_size = LogicalSize {
|
||||
width: constraints.min_width,
|
||||
height: constraints.min_height,
|
||||
};
|
||||
let max_inner_size = LogicalSize {
|
||||
width: constraints.max_width,
|
||||
height: constraints.max_height,
|
||||
};
|
||||
|
||||
let winit_window_builder =
|
||||
if constraints.max_width.is_finite() && constraints.max_height.is_finite() {
|
||||
winit_window_builder
|
||||
.with_min_inner_size(min_inner_size)
|
||||
.with_max_inner_size(max_inner_size)
|
||||
} else {
|
||||
winit_window_builder.with_min_inner_size(min_inner_size)
|
||||
};
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut winit_window_builder = winit_window_builder.with_title(&window_descriptor.title);
|
||||
|
||||
|
|
Loading…
Reference in a new issue