summaryrefslogtreecommitdiffstats
path: root/core/src/window
diff options
context:
space:
mode:
Diffstat (limited to 'core/src/window')
-rw-r--r--core/src/window/event.rs58
-rw-r--r--core/src/window/icon.rs80
-rw-r--r--core/src/window/id.rs28
-rw-r--r--core/src/window/level.rs19
-rw-r--r--core/src/window/mode.rs12
-rw-r--r--core/src/window/position.rs0
-rw-r--r--core/src/window/redraw_request.rs38
-rw-r--r--core/src/window/settings.rs76
-rw-r--r--core/src/window/user_attention.rs21
9 files changed, 332 insertions, 0 deletions
diff --git a/core/src/window/event.rs b/core/src/window/event.rs
new file mode 100644
index 00000000..e2fb5e66
--- /dev/null
+++ b/core/src/window/event.rs
@@ -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,
+}
diff --git a/core/src/window/icon.rs b/core/src/window/icon.rs
new file mode 100644
index 00000000..31868ecf
--- /dev/null
+++ b/core/src/window/icon.rs
@@ -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,
+ },
+}
diff --git a/core/src/window/id.rs b/core/src/window/id.rs
new file mode 100644
index 00000000..0a11b1aa
--- /dev/null
+++ b/core/src/window/id.rs
@@ -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)
+ }
+}
diff --git a/core/src/window/level.rs b/core/src/window/level.rs
new file mode 100644
index 00000000..3878ecac
--- /dev/null
+++ b/core/src/window/level.rs
@@ -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,
+}
diff --git a/core/src/window/mode.rs b/core/src/window/mode.rs
new file mode 100644
index 00000000..fdce8e23
--- /dev/null
+++ b/core/src/window/mode.rs
@@ -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,
+}
diff --git a/core/src/window/position.rs b/core/src/window/position.rs
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/core/src/window/position.rs
diff --git a/core/src/window/redraw_request.rs b/core/src/window/redraw_request.rs
new file mode 100644
index 00000000..3b4f0fd3
--- /dev/null
+++ b/core/src/window/redraw_request.rs
@@ -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));
+ }
+}
diff --git a/core/src/window/settings.rs b/core/src/window/settings.rs
new file mode 100644
index 00000000..458b9232
--- /dev/null
+++ b/core/src/window/settings.rs
@@ -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,
+ }
+ }
+}
diff --git a/core/src/window/user_attention.rs b/core/src/window/user_attention.rs
new file mode 100644
index 00000000..b03dfeef
--- /dev/null
+++ b/core/src/window/user_attention.rs
@@ -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,
+}