2022-12-30 14:23:40 +02:00
// Copyright 2022-2022 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
// taken from https://github.com/rust-windowing/winit/blob/92fdf5ba85f920262a61cee4590f4a11ad5738d1/src/icon.rs
use crate ::platform_impl ::PlatformIcon ;
use std ::{ error ::Error , fmt , io , mem } ;
#[ repr(C) ]
#[ derive(Debug) ]
pub ( crate ) struct Pixel {
pub ( crate ) r : u8 ,
pub ( crate ) g : u8 ,
pub ( crate ) b : u8 ,
pub ( crate ) a : u8 ,
}
pub ( crate ) const PIXEL_SIZE : usize = mem ::size_of ::< Pixel > ( ) ;
#[ derive(Debug) ]
/// An error produced when using [`Icon::from_rgba`] with invalid arguments.
pub enum BadIcon {
/// Produced when the length of the `rgba` argument isn't divisible by 4, thus `rgba` can't be
/// safely interpreted as 32bpp RGBA pixels.
ByteCountNotDivisibleBy4 { 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.
DimensionsVsPixelCount {
width : u32 ,
height : u32 ,
width_x_height : usize ,
pixel_count : usize ,
} ,
/// Produced when underlying OS functionality failed to create the icon
OsError ( io ::Error ) ,
}
impl fmt ::Display for BadIcon {
fn fmt ( & self , f : & mut fmt ::Formatter < '_ > ) -> fmt ::Result {
match self {
BadIcon ::ByteCountNotDivisibleBy4 { byte_count } = > write! ( f ,
" The length of the `rgba` argument ({:?}) isn't divisible by 4, making it impossible to interpret as 32bpp RGBA pixels. " ,
byte_count ,
) ,
BadIcon ::DimensionsVsPixelCount {
width ,
height ,
width_x_height ,
pixel_count ,
} = > write! ( f ,
" The specified dimensions ({:?}x{:?}) don't match the number of pixels supplied by the `rgba` argument ({:?}). For those dimensions, the expected pixel count is {:?}. " ,
width , height , pixel_count , width_x_height ,
) ,
BadIcon ::OsError ( e ) = > write! ( f , " OS error when instantiating the icon: {:?} " , e ) ,
}
}
}
impl Error for BadIcon {
fn source ( & self ) -> Option < & ( dyn Error + 'static ) > {
Some ( self )
}
}
#[ derive(Debug, Clone, PartialEq, Eq) ]
pub ( crate ) struct RgbaIcon {
pub ( crate ) rgba : Vec < u8 > ,
pub ( crate ) width : u32 ,
pub ( crate ) height : u32 ,
}
/// For platforms which don't have window icons (e.g. web)
#[ derive(Debug, Clone, PartialEq, Eq) ]
pub ( crate ) struct NoIcon ;
#[ allow(dead_code) ] // These are not used on every platform
mod constructors {
use super ::* ;
impl RgbaIcon {
pub fn from_rgba ( rgba : Vec < u8 > , width : u32 , height : u32 ) -> Result < Self , BadIcon > {
if rgba . len ( ) % PIXEL_SIZE ! = 0 {
return Err ( BadIcon ::ByteCountNotDivisibleBy4 {
byte_count : rgba . len ( ) ,
} ) ;
}
let pixel_count = rgba . len ( ) / PIXEL_SIZE ;
if pixel_count ! = ( width * height ) as usize {
Err ( BadIcon ::DimensionsVsPixelCount {
width ,
height ,
width_x_height : ( width * height ) as usize ,
pixel_count ,
} )
} else {
Ok ( RgbaIcon {
rgba ,
width ,
height ,
} )
}
}
}
impl NoIcon {
pub fn from_rgba ( rgba : Vec < u8 > , width : u32 , height : u32 ) -> Result < Self , BadIcon > {
// Create the rgba icon anyway to validate the input
let _ = RgbaIcon ::from_rgba ( rgba , width , height ) ? ;
Ok ( NoIcon )
}
}
}
/// An icon used for the window titlebar, taskbar, etc.
#[ derive(Clone) ]
pub struct Icon {
pub ( crate ) inner : PlatformIcon ,
}
impl fmt ::Debug for Icon {
fn fmt ( & self , formatter : & mut fmt ::Formatter < '_ > ) -> Result < ( ) , fmt ::Error > {
fmt ::Debug ::fmt ( & self . inner , formatter )
}
}
impl Icon {
/// Creates an icon from 32bpp RGBA data.
///
/// The length of `rgba` must be divisible by 4, and `width * height` must equal
/// `rgba.len() / 4`. Otherwise, this will return a `BadIcon` error.
pub fn from_rgba ( rgba : Vec < u8 > , width : u32 , height : u32 ) -> Result < Self , BadIcon > {
Ok ( Icon {
inner : PlatformIcon ::from_rgba ( rgba , width , height ) ? ,
} )
}
/// Create an icon from a file path.
///
/// Specify `size` to load a specific icon size from the file, or `None` to load the default
/// icon size from the file.
///
/// In cases where the specified size does not exist in the file, Windows may perform scaling
/// to get an icon of the desired size.
#[ cfg(windows) ]
pub fn from_path < P : AsRef < std ::path ::Path > > (
path : P ,
size : Option < ( u32 , u32 ) > ,
) -> Result < Self , BadIcon > {
let win_icon = PlatformIcon ::from_path ( path , size ) ? ;
Ok ( Icon { inner : win_icon } )
}
/// Create an icon from a resource embedded in this executable or library.
///
/// Specify `size` to load a specific icon size from the file, or `None` to load the default
/// icon size from the file.
///
/// In cases where the specified size does not exist in the file, Windows may perform scaling
/// to get an icon of the desired size.
#[ cfg(windows) ]
pub fn from_resource ( ordinal : u16 , size : Option < ( u32 , u32 ) > ) -> Result < Self , BadIcon > {
let win_icon = PlatformIcon ::from_resource ( ordinal , size ) ? ;
Ok ( Icon { inner : win_icon } )
}
}
2023-07-18 03:44:52 +03:00
/// A native Icon to be used for the menu item
///
/// ## Platform-specific:
///
/// - **Windows / Linux**: Unsupported.
#[ derive(Debug, Clone, Copy, PartialEq, Eq) ]
2023-08-16 19:37:19 +03:00
#[ cfg_attr(feature = " serde " , derive(serde::Serialize, serde::Deserialize)) ]
2023-07-18 03:44:52 +03:00
pub enum NativeIcon {
/// An add item template image.
Add ,
/// Advanced preferences toolbar icon for the preferences window.
Advanced ,
/// A Bluetooth template image.
Bluetooth ,
/// Bookmarks image suitable for a template.
Bookmarks ,
/// A caution image.
Caution ,
/// A color panel toolbar icon.
ColorPanel ,
/// A column view mode template image.
ColumnView ,
/// A computer icon.
Computer ,
/// An enter full-screen mode template image.
EnterFullScreen ,
/// Permissions for all users.
Everyone ,
/// An exit full-screen mode template image.
ExitFullScreen ,
/// A cover flow view mode template image.
FlowView ,
/// A folder image.
Folder ,
/// A burnable folder icon.
FolderBurnable ,
/// A smart folder icon.
FolderSmart ,
/// A link template image.
FollowLinkFreestanding ,
/// A font panel toolbar icon.
FontPanel ,
/// A `go back` template image.
GoLeft ,
/// A `go forward` template image.
GoRight ,
/// Home image suitable for a template.
Home ,
/// An iChat Theater template image.
IChatTheater ,
/// An icon view mode template image.
IconView ,
/// An information toolbar icon.
Info ,
/// A template image used to denote invalid data.
InvalidDataFreestanding ,
/// A generic left-facing triangle template image.
LeftFacingTriangle ,
/// A list view mode template image.
ListView ,
/// A locked padlock template image.
LockLocked ,
/// An unlocked padlock template image.
LockUnlocked ,
/// A horizontal dash, for use in menus.
MenuMixedState ,
/// A check mark template image, for use in menus.
MenuOnState ,
/// A MobileMe icon.
MobileMe ,
/// A drag image for multiple items.
MultipleDocuments ,
/// A network icon.
Network ,
/// A path button template image.
Path ,
/// General preferences toolbar icon for the preferences window.
PreferencesGeneral ,
/// A Quick Look template image.
QuickLook ,
/// A refresh template image.
RefreshFreestanding ,
/// A refresh template image.
Refresh ,
/// A remove item template image.
Remove ,
/// A reveal contents template image.
RevealFreestanding ,
/// A generic right-facing triangle template image.
RightFacingTriangle ,
/// A share view template image.
Share ,
/// A slideshow template image.
Slideshow ,
/// A badge for a `smart` item.
SmartBadge ,
/// Small green indicator, similar to iChat’ s available image.
StatusAvailable ,
/// Small clear indicator.
StatusNone ,
/// Small yellow indicator, similar to iChat’ s idle image.
StatusPartiallyAvailable ,
/// Small red indicator, similar to iChat’ s unavailable image.
StatusUnavailable ,
/// A stop progress template image.
StopProgressFreestanding ,
/// A stop progress button template image.
StopProgress ,
/// An image of the empty trash can.
TrashEmpty ,
/// An image of the full trash can.
TrashFull ,
/// Permissions for a single user.
User ,
/// User account toolbar icon for the preferences window.
UserAccounts ,
/// Permissions for a group of users.
UserGroup ,
/// Permissions for guests.
UserGuest ,
}