Merge remote-tracking branch 'origin/master' into feat/multi-window-support

# Conflicts:
#	Cargo.toml
#	core/src/window/icon.rs
#	core/src/window/id.rs
#	core/src/window/position.rs
#	core/src/window/settings.rs
#	examples/integration/src/main.rs
#	examples/integration_opengl/src/main.rs
#	glutin/src/application.rs
#	native/src/subscription.rs
#	native/src/window.rs
#	runtime/src/window/action.rs
#	src/lib.rs
#	src/window.rs
#	winit/Cargo.toml
#	winit/src/application.rs
#	winit/src/icon.rs
#	winit/src/settings.rs
#	winit/src/window.rs
This commit is contained in:
Bingus 2023-07-12 12:23:18 -07:00
commit 633f405f3f
No known key found for this signature in database
GPG key ID: 5F84D2AA40A9F170
394 changed files with 17278 additions and 13290 deletions

58
core/src/window/event.rs Normal file
View file

@ -0,0 +1,58 @@
use crate::time::Instant;
use std::path::PathBuf;
/// A window-related event.
#[derive(PartialEq, Eq, Clone, Debug)]
pub enum Event {
/// A window was moved.
Moved {
/// The new logical x location of the window
x: i32,
/// The new logical y location of the window
y: i32,
},
/// A window was resized.
Resized {
/// The new logical width of the window
width: u32,
/// The new logical height of the window
height: u32,
},
/// A window redraw was requested.
///
/// The [`Instant`] contains the current time.
RedrawRequested(Instant),
/// The user has requested for the window to close.
///
/// Usually, you will want to terminate the execution whenever this event
/// occurs.
CloseRequested,
/// A window was focused.
Focused,
/// A window was unfocused.
Unfocused,
/// A file is being hovered over the window.
///
/// When the user hovers multiple files at once, this event will be emitted
/// for each file separately.
FileHovered(PathBuf),
/// A file has beend dropped into the window.
///
/// When the user drops multiple files at once, this event will be emitted
/// for each file separately.
FileDropped(PathBuf),
/// A file was hovered, but has exited the window.
///
/// There will be a single `FilesHoveredLeft` event triggered even if
/// multiple files were hovered.
FilesHoveredLeft,
}

80
core/src/window/icon.rs Normal file
View file

@ -0,0 +1,80 @@
//! Change the icon of a window.
use crate::Size;
use std::mem;
/// Builds an [`Icon`] from its RGBA pixels in the sRGB color space.
pub fn from_rgba(
rgba: Vec<u8>,
width: u32,
height: u32,
) -> Result<Icon, Error> {
const PIXEL_SIZE: usize = mem::size_of::<u8>() * 4;
if rgba.len() % PIXEL_SIZE != 0 {
return Err(Error::ByteCountNotDivisibleBy4 {
byte_count: rgba.len(),
});
}
let pixel_count = rgba.len() / PIXEL_SIZE;
if pixel_count != (width * height) as usize {
return Err(Error::DimensionsVsPixelCount {
width,
height,
width_x_height: (width * height) as usize,
pixel_count,
});
}
Ok(Icon {
rgba,
size: Size::new(width, height),
})
}
/// An window icon normally used for the titlebar or taskbar.
#[derive(Debug, Clone)]
pub struct Icon {
rgba: Vec<u8>,
size: Size<u32>,
}
impl Icon {
/// Returns the raw data of the [`Icon`].
pub fn into_raw(self) -> (Vec<u8>, Size<u32>) {
(self.rgba, self.size)
}
}
#[derive(Debug, thiserror::Error)]
/// An error produced when using [`Icon::from_rgba`] with invalid arguments.
pub enum Error {
/// Produced when the length of the `rgba` argument isn't divisible by 4, thus `rgba` can't be
/// safely interpreted as 32bpp RGBA pixels.
#[error(
"The provided RGBA data (with length {byte_count}) isn't divisible \
by 4. Therefore, it cannot be safely interpreted as 32bpp RGBA pixels"
)]
ByteCountNotDivisibleBy4 {
/// The length of the provided RGBA data.
byte_count: usize,
},
/// Produced when the number of pixels (`rgba.len() / 4`) isn't equal to `width * height`.
/// At least one of your arguments is incorrect.
#[error(
"The number of RGBA pixels ({pixel_count}) does not match the \
provided dimensions ({width}x{height})."
)]
DimensionsVsPixelCount {
/// The provided width.
width: u32,
/// The provided height.
height: u32,
/// The product of `width` and `height`.
width_x_height: usize,
/// The amount of pixels of the provided RGBA data.
pixel_count: usize,
},
}

28
core/src/window/id.rs Normal file
View file

@ -0,0 +1,28 @@
use std::collections::hash_map::DefaultHasher;
use std::fmt::{Display, Formatter};
use std::hash::{Hash, Hasher};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
/// The ID of the window.
///
/// Internally Iced uses `window::Id::MAIN` as the first window spawned.
pub struct Id(u64);
impl Id {
/// The reserved window ID for the primary window in an Iced application.
pub const MAIN: Self = Id(0);
/// Creates a new unique window ID.
pub fn new(id: impl Hash) -> Id {
let mut hasher = DefaultHasher::new();
id.hash(&mut hasher);
Id(hasher.finish())
}
}
impl Display for Id {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Id({})", self.0)
}
}

19
core/src/window/level.rs Normal file
View file

@ -0,0 +1,19 @@
/// A window level groups windows with respect to their z-position.
///
/// The relative ordering between windows in different window levels is fixed.
/// The z-order of a window within the same window level may change dynamically
/// on user interaction.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum Level {
/// The default behavior.
#[default]
Normal,
/// The window will always be below normal windows.
///
/// This is useful for a widget-based app.
AlwaysOnBottom,
/// The window will always be on top of normal windows.
AlwaysOnTop,
}

12
core/src/window/mode.rs Normal file
View file

@ -0,0 +1,12 @@
/// The mode of a window-based application.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Mode {
/// The application appears in its own window.
Windowed,
/// The application takes the whole screen of its current monitor.
Fullscreen,
/// The application is hidden
Hidden,
}

View file

View file

@ -0,0 +1,38 @@
use crate::time::Instant;
/// A request to redraw a window.
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum RedrawRequest {
/// Redraw the next frame.
NextFrame,
/// Redraw at the given time.
At(Instant),
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::{Duration, Instant};
#[test]
fn ordering() {
let now = Instant::now();
let later = now + Duration::from_millis(10);
assert_eq!(RedrawRequest::NextFrame, RedrawRequest::NextFrame);
assert_eq!(RedrawRequest::At(now), RedrawRequest::At(now));
assert!(RedrawRequest::NextFrame < RedrawRequest::At(now));
assert!(RedrawRequest::At(now) > RedrawRequest::NextFrame);
assert!(RedrawRequest::At(now) < RedrawRequest::At(later));
assert!(RedrawRequest::At(later) > RedrawRequest::At(now));
assert!(RedrawRequest::NextFrame <= RedrawRequest::NextFrame);
assert!(RedrawRequest::NextFrame <= RedrawRequest::At(now));
assert!(RedrawRequest::At(now) >= RedrawRequest::NextFrame);
assert!(RedrawRequest::At(now) <= RedrawRequest::At(now));
assert!(RedrawRequest::At(now) <= RedrawRequest::At(later));
assert!(RedrawRequest::At(later) >= RedrawRequest::At(now));
}
}

View file

@ -0,0 +1,76 @@
use crate::window::{Icon, Level, Position};
pub use iced_winit::settings::PlatformSpecific;
/// The window settings of an application.
#[derive(Debug, Clone)]
pub struct Settings {
/// The initial size of the window.
pub size: (u32, u32),
/// The initial position of the window.
pub position: Position,
/// The minimum size of the window.
pub min_size: Option<(u32, u32)>,
/// The maximum size of the window.
pub max_size: Option<(u32, u32)>,
/// Whether the window should be visible or not.
pub visible: bool,
/// Whether the window should be resizable or not.
pub resizable: bool,
/// Whether the window should have a border, a title bar, etc. or not.
pub decorations: bool,
/// Whether the window should be transparent.
pub transparent: bool,
/// The window [`Level`].
pub level: Level,
/// The icon of the window.
pub icon: Option<Icon>,
/// Platform specific settings.
pub platform_specific: PlatformSpecific,
}
impl Default for Settings {
fn default() -> Settings {
Settings {
size: (1024, 768),
position: Position::default(),
min_size: None,
max_size: None,
visible: true,
resizable: true,
decorations: true,
transparent: false,
level: Level::default(),
icon: None,
platform_specific: Default::default(),
}
}
}
impl From<Settings> for iced_winit::settings::Window {
fn from(settings: Settings) -> Self {
Self {
size: settings.size,
position: iced_winit::Position::from(settings.position),
min_size: settings.min_size,
max_size: settings.max_size,
visible: settings.visible,
resizable: settings.resizable,
decorations: settings.decorations,
transparent: settings.transparent,
level: settings.level,
icon: settings.icon.map(Icon::into),
platform_specific: settings.platform_specific,
}
}
}

View file

@ -0,0 +1,21 @@
/// The type of user attention to request.
///
/// ## Platform-specific
///
/// - **X11:** Sets the WM's `XUrgencyHint`. No distinction between [`Critical`] and [`Informational`].
///
/// [`Critical`]: Self::Critical
/// [`Informational`]: Self::Informational
#[derive(Debug, Clone, Copy)]
pub enum UserAttention {
/// ## Platform-specific
///
/// - **macOS:** Bounces the dock icon until the application is in focus.
/// - **Windows:** Flashes both the window and the taskbar button until the application is in focus.
Critical,
/// ## Platform-specific
///
/// - **macOS:** Bounces the dock icon once.
/// - **Windows:** Flashes the taskbar button until the application is in focus.
Informational,
}