Skip to content

Commit

Permalink
Use bytes:// schema for included bytes loader
Browse files Browse the repository at this point in the history
  • Loading branch information
emilk committed Sep 14, 2023
1 parent 4e2a0b8 commit b345745
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 8 deletions.
3 changes: 3 additions & 0 deletions crates/egui/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1912,6 +1912,9 @@ impl Context {
/// Associate some static bytes with a `uri`.
///
/// The same `uri` may be passed to [`Ui::image`] later to load the bytes as an image.
///
/// By convention, the `uri` should start wtih `bytes://`.
/// Following that convention will lead to better error messages.
pub fn include_bytes(&self, uri: impl Into<Cow<'static, str>>, bytes: impl Into<Bytes>) {
self.loaders().include.insert(uri, bytes);
}
Expand Down
5 changes: 4 additions & 1 deletion crates/egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,16 @@ pub fn warn_if_debug_build(ui: &mut crate::Ui) {
/// egui::Image::new(egui::include_image!("../assets/ferris.png"))
/// .rounding(egui::Rounding::same(6.0))
/// );
///
/// let image_source: egui::ImageSource = egui::include_image!("../assets/ferris.png");
/// assert_eq!(image_source.uri(), Some("bytes://../assets/ferris.png"));
/// # });
/// ```
#[macro_export]
macro_rules! include_image {
($path: literal) => {
$crate::ImageSource::Bytes(
::std::borrow::Cow::Borrowed($path),
::std::borrow::Cow::Borrowed(concat!("bytes://", $path)), // uri
$crate::load::Bytes::Static(include_bytes!($path)),
)
};
Expand Down
14 changes: 13 additions & 1 deletion crates/egui/src/load/bytes_loader.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use super::*;

/// Maps URI:s to [`Bytes`], e.g. found with `include_bytes!`.
///
/// By convention, the URI:s should be prefixed with `bytes://`.
#[derive(Default)]
pub struct DefaultBytesLoader {
cache: Mutex<HashMap<Cow<'static, str>, Bytes>>,
Expand Down Expand Up @@ -27,13 +30,22 @@ impl BytesLoader for DefaultBytesLoader {
}

fn load(&self, _: &Context, uri: &str) -> BytesLoadResult {
// We accept uri:s that don't start with `bytes://` too… for now.
match self.cache.lock().get(uri).cloned() {
Some(bytes) => Ok(BytesPoll::Ready {
size: None,
bytes,
mime: None,
}),
None => Err(LoadError::NotSupported),
None => {
if uri.starts_with("bytes://") {
Err(LoadError::Loading(
"Bytes not found. Did you forget to call Context::include_bytes?".into(),
))
} else {
Err(LoadError::NotSupported)
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions crates/egui/src/widgets/image.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ impl<'a> Image<'a> {

/// Load the image from some raw bytes.
///
/// For better error messages, use the `bytes://` prefix for the URI.
///
/// See [`ImageSource::Bytes`].
pub fn from_bytes(uri: impl Into<Cow<'static, str>>, bytes: impl Into<Bytes>) -> Self {
Self::new(ImageSource::Bytes(uri.into(), bytes.into()))
Expand Down Expand Up @@ -472,6 +474,8 @@ 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]>`
Expand Down
8 changes: 2 additions & 6 deletions examples/images/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // hide console window on Windows in release

use eframe::egui;
use eframe::epaint::vec2;

fn main() -> Result<(), eframe::Error> {
env_logger::init(); // Log to stderr (if you run with `RUST_LOG=debug`).
let options = eframe::NativeOptions {
drag_and_drop_support: true,
initial_window_size: Some(egui::vec2(600.0, 800.0)),
..Default::default()
};
eframe::run_native(
Expand All @@ -27,10 +26,7 @@ impl eframe::App for MyApp {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
egui::CentralPanel::default().show(ctx, |ui| {
egui::ScrollArea::new([true, true]).show(ui, |ui| {
ui.add(
egui::Image::new(egui::include_image!("ferris.svg"))
.fit_to_fraction(vec2(1.0, 0.5)),
);
ui.image(egui::include_image!("ferris.svg"));
ui.add(
egui::Image::new("https://picsum.photos/seed/1.759706314/1024")
.rounding(egui::Rounding::same(10.0)),
Expand Down

0 comments on commit b345745

Please sign in to comment.