diff --git a/crates/egui/src/lib.rs b/crates/egui/src/lib.rs index 2647f72f0e2..ea9e7fdcb24 100644 --- a/crates/egui/src/lib.rs +++ b/crates/egui/src/lib.rs @@ -458,10 +458,10 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) { #[macro_export] macro_rules! include_image { ($path: literal) => { - $crate::ImageSource::Bytes( - ::std::borrow::Cow::Borrowed(concat!("bytes://", $path)), // uri - $crate::load::Bytes::Static(include_bytes!($path)), - ) + $crate::ImageSource::Bytes { + uri: ::std::borrow::Cow::Borrowed(concat!("bytes://", $path)), + bytes: $crate::load::Bytes::Static(include_bytes!($path)), + } }; } diff --git a/crates/egui/src/load.rs b/crates/egui/src/load.rs index a70986d4c81..9f0f1c3381c 100644 --- a/crates/egui/src/load.rs +++ b/crates/egui/src/load.rs @@ -79,15 +79,15 @@ pub enum LoadError { /// Programmer error: There are no image loaders installed. NoImageLoaders, - /// A specific loader does not support this schema, protocol or image format. + /// A specific loader does not support this scheme, protocol or image format. NotSupported, /// Programmer error: Failed to find the bytes for this image because - /// there was no [`BytesLoader`] supporting the schema. + /// there was no [`BytesLoader`] supporting the scheme. NoMatchingBytesLoader, /// Programmer error: Failed to parse the bytes as an image because - /// there was no [`ImageLoader`] supporting the schema. + /// there was no [`ImageLoader`] supporting the scheme. NoMatchingImageLoader, /// Programmer error: no matching [`TextureLoader`]. @@ -111,7 +111,7 @@ impl Display for LoadError { Self::NoMatchingTextureLoader => f.write_str("No matching TextureLoader. Did you remove the default one?"), - Self::NotSupported => f.write_str("Iagge schema or URI not supported by this loader"), + Self::NotSupported => f.write_str("Image scheme or URI not supported by this loader"), Self::Loading(message) => f.write_str(message), } diff --git a/crates/egui/src/widgets/image.rs b/crates/egui/src/widgets/image.rs index fde5c3304fb..c1838b46424 100644 --- a/crates/egui/src/widgets/image.rs +++ b/crates/egui/src/widgets/image.rs @@ -100,7 +100,10 @@ impl<'a> Image<'a> { /// /// See [`ImageSource::Bytes`]. pub fn from_bytes(uri: impl Into>, bytes: impl Into) -> Self { - Self::new(ImageSource::Bytes(uri.into(), bytes.into())) + Self::new(ImageSource::Bytes { + uri: uri.into(), + bytes: bytes.into(), + }) } /// Texture options used when creating the texture. @@ -275,7 +278,7 @@ impl<'a> Image<'a> { pub fn size(&self) -> Option { match &self.source { ImageSource::Texture(texture) => Some(texture.size), - ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None, + ImageSource::Uri(_) | ImageSource::Bytes { .. } => None, } } @@ -478,9 +481,10 @@ impl Default for ImageSize { /// This is used by [`Image::new`] and [`Ui::image`]. #[derive(Clone)] pub enum ImageSource<'a> { - /// Load the image from a URI. + /// Load the image from a URI, e.g. `https://example.com/image.png`. + /// + /// This could be a `file://` path, `https://` url, `bytes://` identifier, or some other scheme. /// - /// This could be a `file://` url, `http(s)?://` url, or a `bare` identifier. /// How the URI will be turned into a texture for rendering purposes is /// up to the registered loaders to handle. /// @@ -495,8 +499,6 @@ pub enum ImageSource<'a> { /// Load the image from some raw bytes. /// - /// For better error messages, use the `bytes://` prefix for the URI. - /// /// The [`Bytes`] may be: /// - `'static`, obtained from `include_bytes!` or similar /// - Anything that can be converted to `Arc<[u8]>` @@ -506,13 +508,22 @@ pub enum ImageSource<'a> { /// See also [`include_image`] for an easy way to load and display static images. /// /// See [`crate::load`] for more information. - Bytes(Cow<'static, str>, Bytes), + Bytes { + /// The unique identifier for this image, e.g. `bytes://my_logo.png`. + /// + /// You should use a proper extension (`.jpg`, `.png`, `.svg`, etc) for the image to load properly. + /// + /// Use the `bytes://` scheme for the URI for better error messages. + uri: Cow<'static, str>, + + bytes: Bytes, + }, } impl<'a> std::fmt::Debug for ImageSource<'a> { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => uri.as_ref().fmt(f), + ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => uri.as_ref().fmt(f), ImageSource::Texture(st) => st.id.fmt(f), } } @@ -524,7 +535,7 @@ impl<'a> ImageSource<'a> { pub fn texture_size(&self) -> Option { match self { ImageSource::Texture(texture) => Some(texture.size), - ImageSource::Uri(_) | ImageSource::Bytes(_, _) => None, + ImageSource::Uri(_) | ImageSource::Bytes { .. } => None, } } @@ -539,7 +550,7 @@ impl<'a> ImageSource<'a> { match self { Self::Texture(texture) => Ok(TexturePoll::Ready { texture }), Self::Uri(uri) => ctx.try_load_texture(uri.as_ref(), texture_options, size_hint), - Self::Bytes(uri, bytes) => { + Self::Bytes { uri, bytes } => { ctx.include_bytes(uri.clone(), bytes); ctx.try_load_texture(uri.as_ref(), texture_options, size_hint) } @@ -551,7 +562,7 @@ impl<'a> ImageSource<'a> { /// This will return `None` for [`Self::Texture`]. pub fn uri(&self) -> Option<&str> { match self { - ImageSource::Bytes(uri, _) | ImageSource::Uri(uri) => Some(uri), + ImageSource::Bytes { uri, .. } | ImageSource::Uri(uri) => Some(uri), ImageSource::Texture(_) => None, } } @@ -644,21 +655,30 @@ impl<'a> From> for ImageSource<'a> { impl> From<(&'static str, T)> for ImageSource<'static> { #[inline] fn from((uri, bytes): (&'static str, T)) -> Self { - Self::Bytes(uri.into(), bytes.into()) + Self::Bytes { + uri: uri.into(), + bytes: bytes.into(), + } } } impl> From<(Cow<'static, str>, T)> for ImageSource<'static> { #[inline] fn from((uri, bytes): (Cow<'static, str>, T)) -> Self { - Self::Bytes(uri, bytes.into()) + Self::Bytes { + uri, + bytes: bytes.into(), + } } } impl> From<(String, T)> for ImageSource<'static> { #[inline] fn from((uri, bytes): (String, T)) -> Self { - Self::Bytes(uri.into(), bytes.into()) + Self::Bytes { + uri: uri.into(), + bytes: bytes.into(), + } } }