1
0
mirror of https://github.com/emilk/egui.git synced 2026-08-31 22:00:03 -04:00

Polish image API (#3338)

* Imoprove docs for callback shapes

* Improve docs for loader traits

* Use snake_case for feature `all_loaders`

* Make loaders publix

* Slightly better error message on image load failure

* Improve image loading error messages

* Use `bytes://` schema for included bytes loader

* Try user loaders first

* Move `image_loading_spinners` to `Visuals`

* Unify and simplify code

* Make the main text of `Button` optional

This largely makes ImageButton obsolete

* Fix docstrings

* Better docs

* typos

* Use the more explicit `egui_extras::install_image_loaders`

* Simplify `Image::paint_at` function
This commit is contained in:
Emil Ernerfeldt
2023-09-14 16:33:10 +02:00
committed by GitHub
parent e367c20779
commit d7d222d3f6
25 changed files with 406 additions and 279 deletions

View File

@@ -34,6 +34,8 @@ pub use crate::sizing::Size;
pub use crate::strip::*;
pub use crate::table::*;
pub use loaders::install_image_loaders;
// ---------------------------------------------------------------------------
mod profiling_scopes {

View File

@@ -1,22 +1,25 @@
// TODO: automatic cache eviction
/// Installs the default set of loaders.
/// Installs a set of image loaders.
///
/// - `file` loader on non-Wasm targets
/// - `http` loader (with the `http` feature)
/// - `image` loader (with the `image` feature)
/// - `svg` loader with the `svg` feature
/// Calling this enables the use of [`egui::Image`] and [`egui::Ui::image`].
///
/// ⚠ This will do nothing and you won't see any images unless you also enable some feature flags on `egui_extras`:
///
/// - `file` feature: `file://` loader on non-Wasm targets
/// - `http` feature: `http(s)://` loader
/// - `image` feature: Loader of png, jpeg etc using the [`image`] crate
/// - `svg` feature: `.svg` loader
///
/// Calling this multiple times on the same [`egui::Context`] is safe.
/// It will never install duplicate loaders.
///
/// ⚠ This will do nothing and you won't see any images unless you enable some features:
///
/// - If you just want to be able to load `file://` and `http://` URIs, enable the `all-loaders` feature.
/// - If you just want to be able to load `file://` and `http://` URIs, enable the `all_loaders` feature.
/// - The supported set of image formats is configured by adding the [`image`](https://crates.io/crates/image)
/// crate as your direct dependency, and enabling features on it:
///
/// ```toml,ignore
/// egui_extras = { version = "*", features = ["all_loaders"] }
/// image = { version = "0.24", features = ["jpeg", "png"] }
/// ```
///
@@ -39,7 +42,8 @@
/// It will attempt to load `http://` and `https://` URIs, and infer the content type from the `Content-Type` header.
///
/// The `image` loader is an [`ImageLoader`][`egui::load::ImageLoader`].
/// It will attempt to load any URI with any extension other than `svg`. It will also load any URI without an extension.
/// It will attempt to load any URI with any extension other than `svg`.
/// It will also try to load any URI without an extension.
/// The content type specified by [`BytesPoll::Ready::mime`][`egui::load::BytesPoll::Ready::mime`] always takes precedence.
/// This means that even if the URI has a `png` extension, and the `png` image format is enabled, if the content type is
/// not one of the supported and enabled image formats, the loader will return [`LoadError::NotSupported`][`egui::load::LoadError::NotSupported`],
@@ -51,7 +55,7 @@
/// and must include `svg` for it to be considered supported. For example, `image/svg+xml` would be loaded by the `svg` loader.
///
/// See [`egui::load`] for more information about how loaders work.
pub fn install(ctx: &egui::Context) {
pub fn install_image_loaders(ctx: &egui::Context) {
#[cfg(all(not(target_arch = "wasm32"), feature = "file"))]
if !ctx.is_loader_installed(self::file_loader::FileLoader::ID) {
ctx.add_bytes_loader(std::sync::Arc::new(self::file_loader::FileLoader::default()));
@@ -86,7 +90,7 @@ pub fn install(ctx: &egui::Context) {
not(feature = "image"),
not(feature = "svg")
))]
log::warn!("`loaders::install` was called, but no loaders are enabled");
log::warn!("`install_image_loaders` was called, but no loaders are enabled");
let _ = ctx;
}

View File

@@ -72,7 +72,7 @@ impl BytesLoader for EhttpLoader {
bytes: Bytes::Shared(file.bytes),
mime: file.mime,
}),
Poll::Ready(Err(err)) => Err(LoadError::Custom(err)),
Poll::Ready(Err(err)) => Err(LoadError::Loading(err)),
Poll::Pending => Ok(BytesPoll::Pending { size: None }),
}
} else {

View File

@@ -45,7 +45,7 @@ impl BytesLoader for FileLoader {
bytes: Bytes::Shared(file.bytes),
mime: file.mime,
}),
Poll::Ready(Err(err)) => Err(LoadError::Custom(err)),
Poll::Ready(Err(err)) => Err(LoadError::Loading(err)),
Poll::Pending => Ok(BytesPoll::Pending { size: None }),
}
} else {

View File

@@ -50,7 +50,7 @@ impl ImageLoader for ImageCrateLoader {
if let Some(entry) = cache.get(uri).cloned() {
match entry {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Custom(err)),
Err(err) => Err(LoadError::Loading(err)),
}
} else {
match ctx.try_load_bytes(uri) {
@@ -68,7 +68,7 @@ impl ImageLoader for ImageCrateLoader {
cache.insert(uri.into(), result.clone());
match result {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Custom(err)),
Err(err) => Err(LoadError::Loading(err)),
}
}
Ok(BytesPoll::Pending { size }) => Ok(ImagePoll::Pending { size }),

View File

@@ -42,7 +42,7 @@ impl ImageLoader for SvgLoader {
if let Some(entry) = cache.get(&(uri.clone(), size_hint)).cloned() {
match entry {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Custom(err)),
Err(err) => Err(LoadError::Loading(err)),
}
} else {
match ctx.try_load_bytes(&uri) {
@@ -60,7 +60,7 @@ impl ImageLoader for SvgLoader {
cache.insert((uri, size_hint), result.clone());
match result {
Ok(image) => Ok(ImagePoll::Ready { image }),
Err(err) => Err(LoadError::Custom(err)),
Err(err) => Err(LoadError::Loading(err)),
}
}
Ok(BytesPoll::Pending { size }) => Ok(ImagePoll::Pending { size }),