Files
jello/ui-iced/src/blur_hash.rs
uttarayan21 b1cfc19b96
Some checks failed
build / checks-matrix (push) Has been cancelled
build / codecov (push) Has been cancelled
docs / docs (push) Has been cancelled
build / checks-build (push) Has been cancelled
feat: Added iced_video_player
2025-11-20 21:59:47 +05:30

131 lines
3.7 KiB
Rust

use iced::{Element, Length, advanced::Widget};
use std::sync::Arc;
use crate::shared_string::SharedString;
#[derive(Clone)]
pub struct BlurHash {
hash: SharedString,
handle: Arc<iced::advanced::image::Handle>,
width: iced::Length,
height: iced::Length,
punch: f32,
}
impl core::fmt::Debug for BlurHash {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("BlurHash")
.field("hash", &self.hash)
.field("width", &self.width)
.field("height", &self.height)
.field("punch", &self.punch)
.finish()
}
}
impl BlurHash {
pub fn recompute(&mut self, width: u32, height: u32, punch: f32) {
let pixels = blurhash::decode(&self.hash, width, height, punch)
.unwrap_or_else(|_| vec![0; (width * height * 4) as usize]);
let handle = iced::advanced::image::Handle::from_rgba(width, height, pixels);
self.handle = Arc::new(handle);
}
pub fn new(hash: impl AsRef<str>) -> Self {
let hash = SharedString::from(hash.as_ref().to_string());
let pixels = blurhash::decode(&hash, 32, 32, 1.0).unwrap_or_else(|_| vec![0; 32 * 32 * 4]);
let handle = iced::advanced::image::Handle::from_rgba(32, 32, pixels);
let handle = Arc::new(handle);
BlurHash {
hash,
handle,
width: 32.into(),
height: 32.into(),
punch: 1.0,
}
}
pub fn width(mut self, width: impl Into<Length>) -> Self {
self.width = width.into();
self
}
pub fn height(mut self, height: impl Into<Length>) -> Self {
self.height = height.into();
self
}
pub fn punch(mut self, punch: f32) -> Self {
self.punch = punch;
self
}
}
impl<Message, Theme, Renderer> Widget<Message, Theme, Renderer> for BlurHash
where
Renderer: iced::advanced::image::Renderer<Handle = iced::advanced::image::Handle>,
{
fn size(&self) -> iced::Size<iced::Length> {
iced::Size {
width: self.width,
height: self.height,
}
}
fn layout(
&mut self,
_tree: &mut iced::advanced::widget::Tree,
renderer: &Renderer,
limits: &iced::advanced::layout::Limits,
) -> iced::advanced::layout::Node {
let layout = iced::widget::image::layout(
renderer,
limits,
&self.handle,
self.width,
self.height,
None,
iced::ContentFit::default(),
iced::Rotation::default(),
false,
);
let height = layout.bounds().height;
let width = layout.bounds().width;
self.recompute(width as u32, height as u32, self.punch);
layout
}
fn draw(
&self,
_state: &iced::advanced::widget::Tree,
renderer: &mut Renderer,
_theme: &Theme,
_style: &iced::advanced::renderer::Style,
layout: iced::advanced::Layout<'_>,
_cursor: iced::advanced::mouse::Cursor,
_viewport: &iced::Rectangle,
) {
iced::widget::image::draw(
renderer,
layout,
&self.handle,
None,
iced::border::Radius::default(),
iced::ContentFit::default(),
iced::widget::image::FilterMethod::default(),
iced::Rotation::default(),
1.0,
1.0,
);
}
}
impl<'a, Message, Theme, Renderer> From<BlurHash> for iced::Element<'a, Message, Theme, Renderer>
where
Renderer: iced::advanced::image::Renderer<Handle = iced::advanced::image::Handle>,
{
fn from(blur_hash: BlurHash) -> Element<'a, Message, Theme, Renderer> {
iced::Element::new(blur_hash)
}
}