diff options
| -rw-r--r-- | src/settings.rs | 2 | ||||
| -rw-r--r-- | src/window.rs | 3 | ||||
| -rw-r--r-- | src/window/icon.rs | 132 | ||||
| -rw-r--r-- | src/window/settings.rs | 9 | ||||
| -rw-r--r-- | winit/src/settings.rs | 9 | 
5 files changed, 151 insertions, 4 deletions
diff --git a/src/settings.rs b/src/settings.rs index d7ff4cab..40b1b1ea 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -2,7 +2,7 @@  use crate::window;  /// The settings of an application. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone)]  pub struct Settings<Flags> {      /// The window settings.      /// diff --git a/src/window.rs b/src/window.rs index 54ea2a02..a2883b62 100644 --- a/src/window.rs +++ b/src/window.rs @@ -2,5 +2,8 @@  mod mode;  mod settings; +pub mod icon; + +pub use icon::Icon;  pub use mode::Mode;  pub use settings::Settings; diff --git a/src/window/icon.rs b/src/window/icon.rs new file mode 100644 index 00000000..15e0312d --- /dev/null +++ b/src/window/icon.rs @@ -0,0 +1,132 @@ +//! Attach an icon to the window of your application. +use std::fmt; +use std::io; + +/// The icon of a window. +#[cfg(not(target_arch = "wasm32"))] +#[derive(Debug, Clone)] +pub struct Icon(iced_winit::winit::window::Icon); + +/// The icon of a window. +#[cfg(target_arch = "wasm32")] +#[derive(Debug, Clone)] +pub struct Icon; + +impl Icon { +    /// Creates an icon from 32bpp RGBA data. +    #[cfg(not(target_arch = "wasm32"))] +    pub fn from_rgba( +        rgba: Vec<u8>, +        width: u32, +        height: u32, +    ) -> Result<Self, Error> { +        let raw = +            iced_winit::winit::window::Icon::from_rgba(rgba, width, height)?; + +        Ok(Icon(raw)) +    } + +    /// Creates an icon from 32bpp RGBA data. +    #[cfg(target_arch = "wasm32")] +    pub fn from_rgba( +        _rgba: Vec<u8>, +        _width: u32, +        _height: u32, +    ) -> Result<Self, Error> { +        Ok(Icon) +    } +} + +/// An error produced when using `Icon::from_rgba` with invalid arguments. +#[derive(Debug)] +pub enum Error { +    /// The provided RGBA data isn't divisble by 4. +    /// +    /// Therefore, it cannot be safely interpreted as 32bpp RGBA pixels. +    InvalidData { +        /// The length of the provided RGBA data. +        byte_count: usize, +    }, + +    /// The number of RGBA pixels does not match the provided dimensions. +    DimensionsMismatch { +        /// The provided width. +        width: u32, +        /// The provided height. +        height: u32, +        /// The amount of pixels of the provided RGBA data. +        pixel_count: usize, +    }, + +    /// The underlying OS failed to create the icon. +    OsError(io::Error), +} + +#[cfg(not(target_arch = "wasm32"))] +impl From<iced_winit::winit::window::BadIcon> for Error { +    fn from(error: iced_winit::winit::window::BadIcon) -> Self { +        use iced_winit::winit::window::BadIcon; + +        match error { +            BadIcon::ByteCountNotDivisibleBy4 { byte_count } => { +                Error::InvalidData { byte_count } +            } +            BadIcon::DimensionsVsPixelCount { +                width, +                height, +                pixel_count, +                .. +            } => Error::DimensionsMismatch { +                width, +                height, +                pixel_count, +            }, +            BadIcon::OsError(os_error) => Error::OsError(os_error), +        } +    } +} + +#[cfg(not(target_arch = "wasm32"))] +impl From<Icon> for iced_winit::winit::window::Icon { +    fn from(icon: Icon) -> Self { +        icon.0 +    } +} + +impl fmt::Display for Error { +    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +        match self { +            Error::InvalidData { byte_count } => { +                write!(f, +                "The provided RGBA data (with length {:?}) isn't divisble by \ +                4. Therefore, it cannot be safely interpreted as 32bpp RGBA \ +                pixels.", +                byte_count, +            ) +            } +            Error::DimensionsMismatch { +                width, +                height, +                pixel_count, +            } => { +                write!(f, +                "The number of RGBA pixels ({:?}) does not match the provided \ +                dimensions ({:?}x{:?}).", +                width, height, pixel_count, +            ) +            } +            Error::OsError(e) => write!( +                f, +                "The underlying OS failed to create the window \ +                icon: {:?}", +                e +            ), +        } +    } +} + +impl std::error::Error for Error { +    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { +        Some(self) +    } +} diff --git a/src/window/settings.rs b/src/window/settings.rs index eb997899..2046f2d9 100644 --- a/src/window/settings.rs +++ b/src/window/settings.rs @@ -1,5 +1,7 @@ +use crate::window::Icon; +  /// The window settings of an application. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone)]  pub struct Settings {      /// The initial size of the window.      pub size: (u32, u32), @@ -15,6 +17,9 @@ pub struct Settings {      /// Whether the window should have a border, a title bar, etc. or not.      pub decorations: bool, + +    /// The icon of the window. +    pub icon: Option<Icon>,  }  impl Default for Settings { @@ -25,6 +30,7 @@ impl Default for Settings {              max_size: None,              resizable: true,              decorations: true, +            icon: None,          }      }  } @@ -38,6 +44,7 @@ impl From<Settings> for iced_winit::settings::Window {              max_size: settings.max_size,              resizable: settings.resizable,              decorations: settings.decorations, +            icon: settings.icon.map(Icon::into),              platform_specific: Default::default(),          }      } diff --git a/winit/src/settings.rs b/winit/src/settings.rs index 6799f23f..4155bf7d 100644 --- a/winit/src/settings.rs +++ b/winit/src/settings.rs @@ -14,7 +14,7 @@ use winit::monitor::MonitorHandle;  use winit::window::WindowBuilder;  /// The settings of an application. -#[derive(Debug, Clone, Copy, PartialEq, Default)] +#[derive(Debug, Clone, Default)]  pub struct Settings<Flags> {      /// The [`Window`] settings      /// @@ -28,7 +28,7 @@ pub struct Settings<Flags> {  }  /// The window settings of an application. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone)]  pub struct Window {      /// The size of the window.      pub size: (u32, u32), @@ -45,6 +45,9 @@ pub struct Window {      /// Whether the window should have a border, a title bar, etc.      pub decorations: bool, +    /// The window icon, which is also usually used in the taskbar +    pub icon: Option<winit::window::Icon>, +      /// Platform specific settings.      pub platform_specific: platform::PlatformSpecific,  } @@ -66,6 +69,7 @@ impl Window {              .with_inner_size(winit::dpi::LogicalSize { width, height })              .with_resizable(self.resizable)              .with_decorations(self.decorations) +            .with_window_icon(self.icon)              .with_fullscreen(conversion::fullscreen(primary_monitor, mode));          if let Some((width, height)) = self.min_size { @@ -99,6 +103,7 @@ impl Default for Window {              max_size: None,              resizable: true,              decorations: true, +            icon: None,              platform_specific: Default::default(),          }      }  | 
