mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 07:03:14 -04:00
* rework loading around `Arc<Loaders>` * use `Bytes` instead of splitting api * remove unwraps in `texture_handle` * make `FileLoader` optional under `file` feature * hide http load error stack trace from UI * implement image fit * support more image sources * center spinner if we know size ahead of time * allocate final size for spinner * improve image format guessing * remove `ui.image`, `Image`, add `RawImage` * deprecate `RetainedImage` * `image2` -> `image` * add viewer example * update `examples/image` + remove `svg` and `download_image` exapmles * fix lints and tests * fix doc link * add image controls to `images` example * add more `From` str-like types * add api to forget all images * fix max size * do not scale original size unless necessary * fix doc link * add more docs for `Image` and `RawImage` * make paint_at `pub` * update `ImageButton` to use new `Image` API * fix double rendering * `SizeHint::Original` -> `Scale` + remove `Option` wrapper * Update crates/egui/src/load.rs Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * remove special `None` value for `forget` * Update crates/egui/src/load.rs Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * add more examples to `ui.image` + add `include_image` macro * Update crates/egui/src/ui.rs Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * update `menu_image_button` to use `ImageSource` * `OrderedFloat::get` -> `into_inner` * derive `Eq` on `SizedTexture` * add `id` to loaders + `is_installed` check * move `images` to demo + simplify `images` example * log trace when installing loaders * fix lint * fix doc link * add more documentation * more `egui_extras::loaders` docs * Update examples/images/src/main.rs Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * update `images` example screenshots + readme * remove unused `rfd` from `images` example * Update crates/egui_extras/src/loaders/ehttp_loader.rs Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * add `must_use` on `Image` and `RawImage` * document `loaders::install` multiple call safety * Update crates/egui_extras/Cargo.toml Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * reshuffle `is_loader_installed` * make `include_image` produce `ImageSource` + update docs * update `include_image` docs * remove `None` mentions from loader `forget` * inline `From` texture id + size for `SizedTexture` * add warning about statically known path * change image load error + use in image button * add `.size()` to `Image` * Update crates/egui_demo_app/Cargo.toml Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * add explanations to image viewer ui --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
137 lines
3.3 KiB
Rust
137 lines
3.3 KiB
Rust
use std::sync::Arc;
|
|
|
|
use crate::{
|
|
emath::NumExt, mutex::RwLock, textures::TextureOptions, ImageData, ImageDelta, TextureId,
|
|
TextureManager,
|
|
};
|
|
|
|
/// Used to paint images.
|
|
///
|
|
/// An _image_ is pixels stored in RAM, and represented using [`ImageData`].
|
|
/// Before you can paint it however, you need to convert it to a _texture_.
|
|
///
|
|
/// If you are using egui, use `egui::Context::load_texture`.
|
|
///
|
|
/// The [`TextureHandle`] can be cloned cheaply.
|
|
/// When the last [`TextureHandle`] for specific texture is dropped, the texture is freed.
|
|
///
|
|
/// See also [`TextureManager`].
|
|
#[must_use]
|
|
pub struct TextureHandle {
|
|
tex_mngr: Arc<RwLock<TextureManager>>,
|
|
id: TextureId,
|
|
}
|
|
|
|
impl Drop for TextureHandle {
|
|
fn drop(&mut self) {
|
|
self.tex_mngr.write().free(self.id);
|
|
}
|
|
}
|
|
|
|
impl Clone for TextureHandle {
|
|
fn clone(&self) -> Self {
|
|
self.tex_mngr.write().retain(self.id);
|
|
Self {
|
|
tex_mngr: self.tex_mngr.clone(),
|
|
id: self.id,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl PartialEq for TextureHandle {
|
|
#[inline]
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.id == other.id
|
|
}
|
|
}
|
|
|
|
impl Eq for TextureHandle {}
|
|
|
|
impl std::hash::Hash for TextureHandle {
|
|
#[inline]
|
|
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
|
self.id.hash(state);
|
|
}
|
|
}
|
|
|
|
impl TextureHandle {
|
|
/// If you are using egui, use `egui::Context::load_texture` instead.
|
|
pub fn new(tex_mngr: Arc<RwLock<TextureManager>>, id: TextureId) -> Self {
|
|
Self { tex_mngr, id }
|
|
}
|
|
|
|
#[inline]
|
|
pub fn id(&self) -> TextureId {
|
|
self.id
|
|
}
|
|
|
|
/// Assign a new image to an existing texture.
|
|
pub fn set(&mut self, image: impl Into<ImageData>, options: TextureOptions) {
|
|
self.tex_mngr
|
|
.write()
|
|
.set(self.id, ImageDelta::full(image.into(), options));
|
|
}
|
|
|
|
/// Assign a new image to a subregion of the whole texture.
|
|
pub fn set_partial(
|
|
&mut self,
|
|
pos: [usize; 2],
|
|
image: impl Into<ImageData>,
|
|
options: TextureOptions,
|
|
) {
|
|
self.tex_mngr
|
|
.write()
|
|
.set(self.id, ImageDelta::partial(pos, image.into(), options));
|
|
}
|
|
|
|
/// width x height
|
|
pub fn size(&self) -> [usize; 2] {
|
|
self.tex_mngr
|
|
.read()
|
|
.meta(self.id)
|
|
.map_or([0, 0], |tex| tex.size)
|
|
}
|
|
|
|
/// width x height
|
|
pub fn size_vec2(&self) -> crate::Vec2 {
|
|
let [w, h] = self.size();
|
|
crate::Vec2::new(w as f32, h as f32)
|
|
}
|
|
|
|
/// `width x height x bytes_per_pixel`
|
|
pub fn byte_size(&self) -> usize {
|
|
self.tex_mngr
|
|
.read()
|
|
.meta(self.id)
|
|
.map_or(0, |tex| tex.bytes_used())
|
|
}
|
|
|
|
/// width / height
|
|
pub fn aspect_ratio(&self) -> f32 {
|
|
let [w, h] = self.size();
|
|
w as f32 / h.at_least(1) as f32
|
|
}
|
|
|
|
/// Debug-name.
|
|
pub fn name(&self) -> String {
|
|
self.tex_mngr
|
|
.read()
|
|
.meta(self.id)
|
|
.map_or_else(|| "<none>".to_owned(), |tex| tex.name.clone())
|
|
}
|
|
}
|
|
|
|
impl From<&TextureHandle> for TextureId {
|
|
#[inline(always)]
|
|
fn from(handle: &TextureHandle) -> Self {
|
|
handle.id()
|
|
}
|
|
}
|
|
|
|
impl From<&mut TextureHandle> for TextureId {
|
|
#[inline(always)]
|
|
fn from(handle: &mut TextureHandle) -> Self {
|
|
handle.id()
|
|
}
|
|
}
|