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:
commit
633f405f3f
394 changed files with 17278 additions and 13290 deletions
58
core/src/window/event.rs
Normal file
58
core/src/window/event.rs
Normal 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
80
core/src/window/icon.rs
Normal 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
28
core/src/window/id.rs
Normal 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
19
core/src/window/level.rs
Normal 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
12
core/src/window/mode.rs
Normal 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,
|
||||
}
|
||||
0
core/src/window/position.rs
Normal file
0
core/src/window/position.rs
Normal file
38
core/src/window/redraw_request.rs
Normal file
38
core/src/window/redraw_request.rs
Normal 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));
|
||||
}
|
||||
}
|
||||
76
core/src/window/settings.rs
Normal file
76
core/src/window/settings.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
21
core/src/window/user_attention.rs
Normal file
21
core/src/window/user_attention.rs
Normal 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,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue