feat: Initial working prototype
Some checks failed
build / checks-matrix (push) Has been cancelled
build / checks-build (push) Has been cancelled
build / codecov (push) Has been cancelled
docs / docs (push) Has been cancelled

This commit is contained in:
uttarayan21
2025-11-19 01:39:20 +05:30
parent 3222c26bb6
commit a1c36e4fb2
10 changed files with 269 additions and 76 deletions

119
ui-iced/src/blur_hash.rs Normal file
View File

@@ -0,0 +1,119 @@
use std::sync::{Arc, LazyLock, atomic::AtomicBool};
use iced::{Element, advanced::Widget, widget::Image};
use crate::shared_string::SharedString;
#[derive(Clone)]
pub struct BlurHash {
hash: SharedString,
handle: Arc<iced::advanced::image::Handle>,
width: u32,
height: u32,
punch: f32,
}
impl BlurHash {
pub fn recompute(&mut self) {
let pixels = blurhash::decode(&self.hash, self.width, self.height, self.punch)
.unwrap_or_else(|_| vec![0; (self.width * self.height * 4) as usize]);
let handle = iced::advanced::image::Handle::from_rgba(self.width, self.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,
height: 32,
punch: 1.0,
}
}
pub fn width(mut self, height: u32) -> Self {
self.width = height;
self.recompute();
self
}
pub fn height(mut self, height: u32) -> Self {
self.height = height;
self.recompute();
self
}
pub fn punch(mut self, punch: f32) -> Self {
self.punch = punch;
self.recompute();
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: iced::Length::Fixed(self.width as f32),
height: iced::Length::Fixed(self.height as f32),
}
}
fn layout(
&mut self,
_tree: &mut iced::advanced::widget::Tree,
renderer: &Renderer,
limits: &iced::advanced::layout::Limits,
) -> iced::advanced::layout::Node {
iced::widget::image::layout(
renderer,
limits,
&self.handle,
self.width.into(),
self.height.into(),
None,
iced::ContentFit::default(),
iced::Rotation::default(),
false,
)
}
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)
}
}