diff options
Diffstat (limited to 'native')
-rw-r--r-- | native/src/command/action.rs | 8 | ||||
-rw-r--r-- | native/src/event.rs | 2 | ||||
-rw-r--r-- | native/src/subscription.rs | 2 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 2 | ||||
-rw-r--r-- | native/src/widget/tree.rs | 2 | ||||
-rw-r--r-- | native/src/window.rs | 23 | ||||
-rw-r--r-- | native/src/window/action.rs | 11 | ||||
-rw-r--r-- | native/src/window/icon.rs | 12 | ||||
-rw-r--r-- | native/src/window/id.rs | 28 | ||||
-rw-r--r-- | native/src/window/position.rs | 22 | ||||
-rw-r--r-- | native/src/window/settings.rs | 52 |
11 files changed, 154 insertions, 10 deletions
diff --git a/native/src/command/action.rs b/native/src/command/action.rs index a51b8c21..dcb79672 100644 --- a/native/src/command/action.rs +++ b/native/src/command/action.rs @@ -20,7 +20,7 @@ pub enum Action<T> { Clipboard(clipboard::Action<T>), /// Run a window action. - Window(window::Action<T>), + Window(window::Id, window::Action<T>), /// Run a system action. System(system::Action<T>), @@ -46,7 +46,7 @@ impl<T> Action<T> { match self { Self::Future(future) => Action::Future(Box::pin(future.map(f))), Self::Clipboard(action) => Action::Clipboard(action.map(f)), - Self::Window(window) => Action::Window(window.map(f)), + Self::Window(id, window) => Action::Window(id, window.map(f)), Self::System(system) => Action::System(system.map(f)), Self::Widget(widget) => Action::Widget(widget.map(f)), } @@ -60,7 +60,9 @@ impl<T> fmt::Debug for Action<T> { Self::Clipboard(action) => { write!(f, "Action::Clipboard({action:?})") } - Self::Window(action) => write!(f, "Action::Window({action:?})"), + Self::Window(id, action) => { + write!(f, "Action::Window({id:?}, {action:?})") + } Self::System(action) => write!(f, "Action::System({action:?})"), Self::Widget(_action) => write!(f, "Action::Widget"), } diff --git a/native/src/event.rs b/native/src/event.rs index bcfaf891..eb826399 100644 --- a/native/src/event.rs +++ b/native/src/event.rs @@ -19,7 +19,7 @@ pub enum Event { Mouse(mouse::Event), /// A window event - Window(window::Event), + Window(window::Id, window::Event), /// A touch event Touch(touch::Event), diff --git a/native/src/subscription.rs b/native/src/subscription.rs index 8c92efad..f517fc70 100644 --- a/native/src/subscription.rs +++ b/native/src/subscription.rs @@ -70,7 +70,7 @@ where events.filter_map(move |(event, status)| { future::ready(match event { - Event::Window(window::Event::RedrawRequested(_)) => None, + Event::Window(_, window::Event::RedrawRequested(_)) => None, _ => f(event, status), }) }) diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index ee0473ea..00e871e7 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -778,7 +778,7 @@ where state.keyboard_modifiers = modifiers; } - Event::Window(window::Event::RedrawRequested(now)) => { + Event::Window(_, window::Event::RedrawRequested(now)) => { let state = state(); if let Some(focus) = &mut state.is_focused { diff --git a/native/src/widget/tree.rs b/native/src/widget/tree.rs index 0af40c33..da269632 100644 --- a/native/src/widget/tree.rs +++ b/native/src/widget/tree.rs @@ -67,7 +67,7 @@ impl Tree { } } - /// Reconciliates the children of the tree with the provided list of widgets. + /// Reconciles the children of the tree with the provided list of widgets. pub fn diff_children<'a, Message, Renderer>( &mut self, new_children: &[impl Borrow<dyn Widget<Message, Renderer> + 'a>], diff --git a/native/src/window.rs b/native/src/window.rs index a5cdc8ce..a8f8b10f 100644 --- a/native/src/window.rs +++ b/native/src/window.rs @@ -1,14 +1,22 @@ //! Build window-based GUI applications. mod action; mod event; +mod icon; +mod id; mod mode; +mod position; mod redraw_request; +mod settings; mod user_attention; pub use action::Action; pub use event::Event; +pub use icon::Icon; +pub use id::Id; pub use mode::Mode; +pub use position::Position; pub use redraw_request::RedrawRequest; +pub use settings::Settings; pub use user_attention::UserAttention; use crate::subscription::{self, Subscription}; @@ -22,9 +30,20 @@ use crate::time::Instant; /// /// In any case, this [`Subscription`] is useful to smoothly draw application-driven /// animations without missing any frames. -pub fn frames() -> Subscription<Instant> { +pub fn frames() -> Subscription<Frame> { subscription::raw_events(|event, _status| match event { - crate::Event::Window(Event::RedrawRequested(at)) => Some(at), + crate::Event::Window(id, Event::RedrawRequested(at)) => { + Some(Frame { id, at }) + } _ => None, }) } + +/// The returned `Frame` for a framerate subscription. +#[derive(Debug)] +pub struct Frame { + /// The `window::Id` that the `Frame` was produced in. + pub id: Id, + /// The `Instant` at which the frame was produced. + pub at: Instant, +} diff --git a/native/src/window/action.rs b/native/src/window/action.rs index ce36d129..5751bf97 100644 --- a/native/src/window/action.rs +++ b/native/src/window/action.rs @@ -1,4 +1,4 @@ -use crate::window::{Mode, UserAttention}; +use crate::window::{Mode, UserAttention, Settings}; use iced_futures::MaybeSend; use std::fmt; @@ -13,6 +13,11 @@ pub enum Action<T> { /// There’s no guarantee that this will work unless the left mouse /// button was pressed immediately before this function is called. Drag, + /// Spawns a new window with the provided [`window::Settings`]. + Spawn { + /// The settings of the [`Window`]. + settings: Settings, + }, /// Resize the window. Resize { /// The new logical width of the window @@ -90,6 +95,7 @@ impl<T> Action<T> { T: 'static, { match self { + Self::Spawn { settings } => Action::Spawn { settings }, Self::Close => Action::Close, Self::Drag => Action::Drag, Self::Resize { width, height } => Action::Resize { width, height }, @@ -117,6 +123,9 @@ impl<T> fmt::Debug for Action<T> { match self { Self::Close => write!(f, "Action::Close"), Self::Drag => write!(f, "Action::Drag"), + Self::Spawn { settings } => { + write!(f, "Action::Spawn {{ settings: {:?} }}", settings) + } Self::Resize { width, height } => write!( f, "Action::Resize {{ widget: {width}, height: {height} }}" diff --git a/native/src/window/icon.rs b/native/src/window/icon.rs new file mode 100644 index 00000000..08a6acfd --- /dev/null +++ b/native/src/window/icon.rs @@ -0,0 +1,12 @@ +//! Attach an icon to the window of your application. + +/// The icon of a window. +#[derive(Debug, Clone)] +pub struct Icon { + /// The __rgba__ color data of the window [`Icon`]. + pub rgba: Vec<u8>, + /// The width of the window [`Icon`]. + pub width: u32, + /// The height of the window [`Icon`]. + pub height: u32, +} diff --git a/native/src/window/id.rs b/native/src/window/id.rs new file mode 100644 index 00000000..fa9761f5 --- /dev/null +++ b/native/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. +/// +/// This is not necessarily the same as the window ID fetched from `winit::window::Window`. +pub struct Id(u64); + +impl Id { + /// TODO(derezzedex): maybe change `u64` to an enum `Type::{Single, Multi(u64)}` + 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/native/src/window/position.rs b/native/src/window/position.rs new file mode 100644 index 00000000..c260c29e --- /dev/null +++ b/native/src/window/position.rs @@ -0,0 +1,22 @@ +/// The position of a window in a given screen. +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum Position { + /// The platform-specific default position for a new window. + Default, + /// The window is completely centered on the screen. + Centered, + /// The window is positioned with specific coordinates: `(X, Y)`. + /// + /// When the decorations of the window are enabled, Windows 10 will add some + /// invisible padding to the window. This padding gets included in the + /// position. So if you have decorations enabled and want the window to be + /// at (0, 0) you would have to set the position to + /// `(PADDING_X, PADDING_Y)`. + Specific(i32, i32), +} + +impl Default for Position { + fn default() -> Self { + Self::Default + } +} diff --git a/native/src/window/settings.rs b/native/src/window/settings.rs new file mode 100644 index 00000000..67798fbe --- /dev/null +++ b/native/src/window/settings.rs @@ -0,0 +1,52 @@ +use crate::window::{Icon, Position}; + +/// 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, + + /// Whether the window will always be on top of other windows. + pub always_on_top: bool, + + /// The icon of the window. + pub icon: Option<Icon>, +} + +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, + always_on_top: false, + icon: None, + } + } +} |