Added set_minimized and set_position to Window (#1292)

Added `set_minimized` and `set_position` to `Window`
This commit is contained in:
Toniman20 2021-01-25 05:06:06 +01:00 committed by GitHub
parent 7e368e0b78
commit 32acbfb632
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 6 deletions

View file

@ -1,7 +1,7 @@
use std::path::PathBuf;
use super::{WindowDescriptor, WindowId};
use bevy_math::Vec2;
use bevy_math::{IVec2, Vec2};
/// A window event that is sent whenever a window has been resized.
#[derive(Debug, Clone)]
@ -89,3 +89,10 @@ pub enum FileDragAndDrop {
HoveredFileCancelled { id: WindowId },
}
/// An event that is sent when a window is repositioned in physical pixels.
#[derive(Debug, Clone)]
pub struct WindowMoved {
pub id: WindowId,
pub position: IVec2,
}

View file

@ -12,7 +12,7 @@ pub use windows::*;
pub mod prelude {
pub use crate::{
CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter, Window,
WindowDescriptor, Windows,
WindowDescriptor, WindowMoved, Windows,
};
}
@ -47,6 +47,7 @@ impl Plugin for WindowPlugin {
.add_event::<WindowScaleFactorChanged>()
.add_event::<WindowBackendScaleFactorChanged>()
.add_event::<FileDragAndDrop>()
.add_event::<WindowMoved>()
.init_resource::<Windows>();
if self.add_primary_window {

View file

@ -1,4 +1,4 @@
use bevy_math::Vec2;
use bevy_math::{IVec2, Vec2};
use bevy_utils::Uuid;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
@ -54,6 +54,7 @@ pub struct Window {
requested_height: f32,
physical_width: u32,
physical_height: u32,
position: Option<IVec2>,
scale_factor_override: Option<f64>,
backend_scale_factor: f64,
title: String,
@ -106,6 +107,12 @@ pub enum WindowCommand {
SetMaximized {
maximized: bool,
},
SetMinimized {
minimized: bool,
},
SetPosition {
position: IVec2,
},
}
/// Defines the way a window is displayed
@ -127,11 +134,13 @@ impl Window {
physical_width: u32,
physical_height: u32,
scale_factor: f64,
position: Option<IVec2>,
) -> Self {
Window {
id,
requested_width: window_descriptor.width,
requested_height: window_descriptor.height,
position,
physical_width,
physical_height,
scale_factor_override: window_descriptor.scale_factor_override,
@ -199,12 +208,46 @@ impl Window {
self.physical_height
}
/// The window's client position in physical pixels.
#[inline]
pub fn position(&self) -> Option<IVec2> {
self.position
}
#[inline]
pub fn set_maximized(&mut self, maximized: bool) {
self.command_queue
.push(WindowCommand::SetMaximized { maximized });
}
/// Sets the window to minimized or back.
///
/// # Platform-specific
/// - iOS / Android / Web: Unsupported.
/// - Wayland: Un-minimize is unsupported.
#[inline]
pub fn set_minimized(&mut self, minimized: bool) {
self.command_queue
.push(WindowCommand::SetMinimized { minimized });
}
/// Modifies the position of the window in physical pixels.
///
/// Note that the top-left hand corner of the desktop is not necessarily the same as the screen. If the user uses a desktop with multiple monitors,
/// the top-left hand corner of the desktop is the top-left hand corner of the monitor at the top-left of the desktop. This automatically un-maximizes
/// the window if it's maximized.
///
/// # Platform-specific
///
/// - iOS: Can only be called on the main thread. Sets the top left coordinates of the window in the screen space coordinate system.
/// - Web: Sets the top-left coordinates relative to the viewport.
/// - Android / Wayland: Unsupported.
#[inline]
pub fn set_position(&mut self, position: IVec2) {
self.command_queue
.push(WindowCommand::SetPosition { position })
}
/// Request the OS to resize the window such the the client area matches the
/// specified width and height.
#[allow(clippy::float_cmp)]
@ -250,6 +293,12 @@ impl Window {
self.physical_height = physical_height;
}
#[allow(missing_docs)]
#[inline]
pub fn update_actual_position_from_backend(&mut self, position: IVec2) {
self.position = Some(position);
}
/// The ratio of physical pixels to logical pixels
///
/// `physical_pixels = logical_pixels * scale_factor`

View file

@ -12,14 +12,15 @@ pub use winit_windows::*;
use bevy_app::{prelude::*, AppExit, ManualEventReader};
use bevy_ecs::{IntoSystem, Resources, World};
use bevy_math::Vec2;
use bevy_math::{ivec2, Vec2};
use bevy_utils::tracing::{error, trace, warn};
use bevy_window::{
CreateWindow, CursorEntered, CursorLeft, CursorMoved, FileDragAndDrop, ReceivedCharacter,
WindowBackendScaleFactorChanged, WindowCloseRequested, WindowCreated, WindowFocused,
WindowResized, WindowScaleFactorChanged, Windows,
WindowMoved, WindowResized, WindowScaleFactorChanged, Windows,
};
use winit::{
dpi::PhysicalPosition,
event::{self, DeviceEvent, Event, WindowEvent},
event_loop::{ControlFlow, EventLoop, EventLoopWindowTarget},
};
@ -127,6 +128,17 @@ fn change_window(_: &mut World, resources: &mut Resources) {
let window = winit_windows.get_window(id).unwrap();
window.set_maximized(maximized)
}
bevy_window::WindowCommand::SetMinimized { minimized } => {
let window = winit_windows.get_window(id).unwrap();
window.set_minimized(minimized)
}
bevy_window::WindowCommand::SetPosition { position } => {
let window = winit_windows.get_window(id).unwrap();
window.set_outer_position(PhysicalPosition {
x: position[0],
y: position[1],
});
}
}
}
}
@ -423,6 +435,15 @@ pub fn winit_runner_with(mut app: App, mut event_loop: EventLoop<()>) {
app.resources.get_mut::<Events<FileDragAndDrop>>().unwrap();
events.send(FileDragAndDrop::HoveredFileCancelled { id: window_id });
}
WindowEvent::Moved(position) => {
let position = ivec2(position.x, position.y);
window.update_actual_position_from_backend(position);
let mut events = app.resources.get_mut::<Events<WindowMoved>>().unwrap();
events.send(WindowMoved {
id: window_id,
position,
});
}
_ => {}
}
}

View file

@ -1,3 +1,4 @@
use bevy_math::IVec2;
use bevy_utils::HashMap;
use bevy_window::{Window, WindowDescriptor, WindowId, WindowMode};
@ -110,16 +111,20 @@ impl WinitWindows {
}
}
let position = winit_window
.outer_position()
.ok()
.map(|position| IVec2::new(position.x, position.y));
let inner_size = winit_window.inner_size();
let scale_factor = winit_window.scale_factor();
self.windows.insert(winit_window.id(), winit_window);
Window::new(
window_id,
&window_descriptor,
inner_size.width,
inner_size.height,
scale_factor,
position,
)
}