mirror of
https://github.com/emilk/egui.git
synced 2026-06-27 07:03:14 -04:00
* add types from proposal * add load methods on `egui::Context` * implement loaders from proposal in `egui_extras` * impl `From<Vec2>` for `SizeHint` * re-export `SizeHint` from `egui` root * rework `svg` example to use new managed `Image` * split loaders into separate files + add logging * add `log_trace` * clean up `RetainedImage` from `svg` example * refactor ehttp loader response to bytes mapping * remove spammy trace * load images even without extension * fix lints * remove unused imports * use `Image2` in `download_image` * use `visuals.error_fg_color` in `Image2` error state * update lockfile * use `Arc<ColorImage>` in `ImageData` + add `forget` API * add `ui.image2` * add byte size query api * use iterators to sum loader byte sizes * add static image loading * use static image in `svg` example * small refactor of `Image2::ui` texture loading code * add `ImageFit` to size images properly * remove println calls * add bad image load to `download_image` example * add loader file extension support tests * fix lint errors in `loaders` * remove unused `poll-promise` dependency * add some docs to `Image2` * add some docs to `egui_extras::loaders::install` * explain `loaders::install` in examples * fix lint * upgrade `ehttp` to `0.3` for some crates * Remove some unused dependencies * Remove unnecessary context clone * Turn on the `log` create feature of egui_extras in all examples * rename `forget` and document it * derive `Debug` on `SizeHint` Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * round when converting SizeHint from vec2 Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com> * add `load` module docs * docstring `add_loader` methods * expose + document `load_include_bytes` * cache texture handles in `DefaultTextureLoader` * add `image2` doctest + further document `Image2` * use `Default` for default `Image2` options * update `image2` doc comment * mention immediate-mode safety * more fit calculation into inherent impl * add hover text on spinner * add `all-loaders` feature * clarify `egui_extras::loaders::install` behavior * explain how to enable image formats * properly format `uri` * use `thread::Builder` instead of `spawn` * use eq op instead of `matches` * inline `From<Arc<ColorImage>>` for `ImageData` * allow non-`'static` bytes + `forget` in `DefaultTextureLoader` * sort features * change `ehttp` feature to `http` * update `Image2` docs * refactor loader cache type --------- Co-authored-by: Emil Ernerfeldt <emil.ernerfeldt@gmail.com>
128 lines
3.1 KiB
Rust
128 lines
3.1 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).unwrap().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).unwrap().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).unwrap().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()
|
|
}
|
|
}
|