Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added convenience functions for window::icon::Icon #1174

Merged
merged 1 commit into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ default = ["wgpu"]
# Enables the `iced_wgpu` renderer
wgpu = ["iced_wgpu"]
# Enables the `Image` widget
image = ["iced_wgpu/image"]
image = ["iced_wgpu/image", "image_rs"]
# Enables the `Svg` widget
svg = ["iced_wgpu/svg"]
# Enables the `Canvas` widget
Expand Down Expand Up @@ -98,6 +98,11 @@ iced_glutin = { version = "0.2", path = "glutin", optional = true }
iced_glow = { version = "0.2", path = "glow", optional = true }
thiserror = "1.0"

[dependencies.image_rs]
version = "0.23"
package = "image"
optional = true

[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
iced_wgpu = { version = "0.4", path = "wgpu", optional = true }

Expand Down
57 changes: 57 additions & 0 deletions src/window/icon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
use std::fmt;
use std::io;

#[cfg(feature = "image_rs")]
use std::path::Path;

/// The icon of a window.
#[derive(Debug, Clone)]
pub struct Icon(iced_winit::winit::window::Icon);
Expand All @@ -18,6 +21,39 @@ impl Icon {

Ok(Icon(raw))
}

/// Creates an icon from an image file.
///
/// This will return an error in case the file is missing at run-time. You may prefer [`Self::from_file_data`] instead.
#[cfg(feature = "image_rs")]
pub fn from_file<P: AsRef<Path>>(icon_path: P) -> Result<Self, Error> {
let icon = image_rs::io::Reader::open(icon_path)?.decode()?.to_rgba8();

Self::from_rgba(icon.to_vec(), icon.width(), icon.height())
}

/// Creates an icon from the content of an image file.
///
/// This content can be included in your application at compile-time, e.g. using the `include_bytes!` macro. \
/// You can pass an explicit file format. Otherwise, the file format will be guessed at runtime.
#[cfg(feature = "image_rs")]
pub fn from_file_data(
data: &[u8],
explicit_format: Option<image_rs::ImageFormat>,
) -> Result<Self, Error> {
let mut icon = image_rs::io::Reader::new(std::io::Cursor::new(data));
let icon_with_format = match explicit_format {
Some(format) => {
icon.set_format(format);
icon
}
None => icon.with_guessed_format()?,
};

let pixels = icon_with_format.decode()?.to_rgba8();

Self::from_rgba(pixels.to_vec(), pixels.width(), pixels.height())
}
}

/// An error produced when using `Icon::from_rgba` with invalid arguments.
Expand All @@ -43,6 +79,16 @@ pub enum Error {

/// The underlying OS failed to create the icon.
OsError(io::Error),

/// The `image` crate reported an error
#[cfg(feature = "image_rs")]
ImageError(image_rs::error::ImageError),
}

impl From<std::io::Error> for Error {
fn from(os_error: std::io::Error) -> Self {
Error::OsError(os_error)
}
}

impl From<iced_winit::winit::window::BadIcon> for Error {
Expand Down Expand Up @@ -74,6 +120,13 @@ impl From<Icon> for iced_winit::winit::window::Icon {
}
}

#[cfg(feature = "image_rs")]
impl From<image_rs::error::ImageError> for Error {
fn from(image_error: image_rs::error::ImageError) -> Self {
Self::ImageError(image_error)
}
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Expand Down Expand Up @@ -104,6 +157,10 @@ impl fmt::Display for Error {
icon: {:?}",
e
),
#[cfg(feature = "image_rs")]
Error::ImageError(e) => {
write!(f, "Unable to create icon from a file: {:?}", e)
}
}
}
}
Expand Down