Merge branch 'master' into beacon

This commit is contained in:
Héctor Ramón Jiménez 2025-04-05 18:20:31 +02:00
commit 3f67044977
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
62 changed files with 713 additions and 780 deletions

View file

@ -9,4 +9,4 @@ publish = false
iced.workspace = true
iced.features = ["canvas"]
palette.workspace = true
palette = "0.7"

View file

@ -45,7 +45,7 @@ pub enum Message {
impl ColorPalette {
fn update(&mut self, message: Message) {
let srgb = match message {
Message::RgbColorChanged(rgb) => Rgb::from(rgb),
Message::RgbColorChanged(rgb) => to_rgb(rgb),
Message::HslColorChanged(hsl) => Rgb::from_color(hsl),
Message::HsvColorChanged(hsv) => Rgb::from_color(hsv),
Message::HwbColorChanged(hwb) => Rgb::from_color(hwb),
@ -53,13 +53,13 @@ impl ColorPalette {
Message::LchColorChanged(lch) => Rgb::from_color(lch),
};
self.theme = Theme::new(srgb);
self.theme = Theme::new(to_color(srgb));
}
fn view(&self) -> Element<Message> {
let base = self.theme.base;
let srgb = Rgb::from(base);
let srgb = to_rgb(base);
let hsl = palette::Hsl::from_color(srgb);
let hsv = palette::Hsv::from_color(srgb);
let hwb = palette::Hwb::from_color(srgb);
@ -108,7 +108,7 @@ impl Theme {
let base = base.into();
// Convert to HSL color for manipulation
let hsl = Hsl::from_color(Rgb::from(base));
let hsl = Hsl::from_color(to_rgb(base));
let lower = [
hsl.shift_hue(-135.0).lighten(0.075),
@ -127,12 +127,12 @@ impl Theme {
Theme {
lower: lower
.iter()
.map(|&color| Rgb::from_color(color).into())
.map(|&color| to_color(Rgb::from_color(color)))
.collect(),
base,
higher: higher
.iter()
.map(|&color| Rgb::from_color(color).into())
.map(|&color| to_color(Rgb::from_color(color)))
.collect(),
canvas_cache: canvas::Cache::default(),
}
@ -215,14 +215,14 @@ impl Theme {
text.align_y = alignment::Vertical::Bottom;
let hsl = Hsl::from_color(Rgb::from(self.base));
let hsl = Hsl::from_color(to_rgb(self.base));
for i in 0..self.len() {
let pct = (i as f32 + 1.0) / (self.len() as f32 + 1.0);
let graded = Hsl {
lightness: 1.0 - pct,
..hsl
};
let color: Color = Rgb::from_color(graded).into();
let color: Color = to_color(Rgb::from_color(graded));
let anchor = Point {
x: (i as f32) * box_size.width,
@ -474,3 +474,21 @@ impl ColorSpace for palette::Lch {
)
}
}
fn to_rgb(color: Color) -> Rgb {
Rgb {
red: color.r,
green: color.g,
blue: color.b,
..Rgb::default()
}
}
fn to_color(rgb: Rgb) -> Color {
Color {
r: rgb.red,
g: rgb.green,
b: rgb.blue,
a: 1.0,
}
}

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["tokio"]
iced.features = ["tokio", "sipper"]
[dependencies.reqwest]
version = "0.12"

View file

@ -112,9 +112,7 @@ impl Download {
pub fn start(&mut self) -> Task<Update> {
match self.state {
State::Idle { .. }
| State::Finished { .. }
| State::Errored { .. } => {
State::Idle | State::Finished | State::Errored => {
let (task, handle) = Task::sip(
download(
"https://huggingface.co/\
@ -156,10 +154,10 @@ impl Download {
pub fn view(&self) -> Element<Message> {
let current_progress = match &self.state {
State::Idle { .. } => 0.0,
State::Idle => 0.0,
State::Downloading { progress, .. } => *progress,
State::Finished { .. } => 100.0,
State::Errored { .. } => 0.0,
State::Finished => 100.0,
State::Errored => 0.0,
};
let progress_bar = progress_bar(0.0..=100.0, current_progress);

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["tokio", "image", "web-colors", "debug"]
iced.features = ["tokio", "sipper", "image", "web-colors", "debug"]
reqwest.version = "0.12"
reqwest.features = ["json"]

View file

@ -12,6 +12,9 @@ iced_wgpu.workspace = true
iced_widget.workspace = true
iced_widget.features = ["wgpu"]
futures.workspace = true
futures.features = ["thread-pool"]
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tracing-subscriber = "0.3"

View file

@ -36,9 +36,10 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
Loading,
Ready {
window: Arc<winit::window::Window>,
queue: wgpu::Queue,
device: wgpu::Device,
surface: wgpu::Surface<'static>,
format: wgpu::TextureFormat,
device: wgpu::Device,
renderer: Renderer,
scene: Scene,
controls: Controls,
@ -144,11 +145,12 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
let controls = Controls::new();
// Initialize iced
let renderer = {
let engine = Engine::new(
&adapter,
device.clone(),
queue,
queue.clone(),
format,
None,
);
@ -161,10 +163,11 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
*self = Self::Ready {
window,
device,
queue,
renderer,
surface,
format,
device,
renderer,
scene,
controls,
events: Vec::new(),
@ -187,6 +190,7 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
let Self::Ready {
window,
device,
queue,
surface,
format,
renderer,
@ -233,16 +237,16 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
match surface.get_current_texture() {
Ok(frame) => {
let mut encoder = device.create_command_encoder(
&wgpu::CommandEncoderDescriptor { label: None },
);
let view = frame.texture.create_view(
&wgpu::TextureViewDescriptor::default(),
);
let mut encoder = device.create_command_encoder(
&wgpu::CommandEncoderDescriptor { label: None },
);
{
// We clear the frame
// Clear the frame
let mut render_pass = Scene::clear(
&view,
&mut encoder,
@ -253,7 +257,10 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
scene.draw(&mut render_pass);
}
// And then iced on top
// Submit the scene
queue.submit([encoder.finish()]);
// Draw iced on top
let mut interface = UserInterface::build(
controls.view(),
viewport.logical_size(),
@ -288,7 +295,7 @@ pub fn main() -> Result<(), winit::error::EventLoopError> {
viewport,
);
// Then we submit the work
// Present the frame
frame.present();
// Update the mouse cursor

View file

@ -34,7 +34,7 @@ impl Pokedex {
let subtitle = match self {
Pokedex::Loading => "Loading",
Pokedex::Loaded { pokemon, .. } => &pokemon.name,
Pokedex::Errored { .. } => "Whoops!",
Pokedex::Errored => "Whoops!",
};
format!("{subtitle} - Pokédex")

View file

@ -7,3 +7,7 @@ publish = false
[dependencies]
iced.workspace = true
[dev-dependencies]
iced_test.workspace = true
rayon = "1"

View file

@ -0,0 +1 @@
9e67e429f88fd5a64744d9cd4d42e123950bea4a45fea78581bc3d64b12e11f0

View file

@ -0,0 +1 @@
811a22238f3a40e3e3998f514c0a95f24f2b45449250682d86c8ec392fec5e28

View file

@ -0,0 +1 @@
6bf957efe807f87f38cfc672f9a05325aadee6256aacca87bbc3281b98160c8a

View file

@ -0,0 +1 @@
d3f4110fae78a3be3b7a4813e9a432b48b81fff1e982c0244e4ea394074bef55

View file

@ -0,0 +1 @@
578e7420de69d82906d284c59d81fcea0edf81098481fc4dd7b4c1fb577b7f1c

View file

@ -0,0 +1 @@
422e841113efaa86e9e37593d0d14f8dd36ad483a81c30a08588f48805e4f9f3

View file

@ -0,0 +1 @@
3d616a31842a29b4a3d31fbeef25f95c7b50f33360f1c05e069e0b29b3f7553e

View file

@ -0,0 +1 @@
9a21865bfc075669d368ccac69b975c3e1f6c22ba297dddfa003d4ee1a06641c

View file

@ -0,0 +1 @@
d5164fb10a92177afd0aab353557d1e3fdaa743962c6a901f05cbfcd0d91e9fb

View file

@ -0,0 +1 @@
3d5ba3b50f192f8700edbfbf54007e92dfd66997bce7342671afc2b60d556aca

View file

@ -0,0 +1 @@
90cb13c900d58a56ce170afeefbceb77410d024e7eae6030e181df1c929c3944

View file

@ -0,0 +1 @@
71b625bc39aaead7a1298e4b2dad51b266526c53deab139858774986395878db

View file

@ -0,0 +1 @@
f08f80a79959ef1c2fd8f8696a26555f2b2eab6618dd3653a042acab563bcced

View file

@ -0,0 +1 @@
3302b7934051ff8aa01d70c45e28c444bdc93e8a4da219931aa22465b51c6748

View file

@ -0,0 +1 @@
661ec43b66213f369ce5a3680e9e8ead56c98d94718da25b12fbb313386944e0

View file

@ -0,0 +1 @@
b5dd22b064220d5f2f90c6f0f381eff41d25f534587d1649ed59e25f878eda97

View file

@ -0,0 +1 @@
dd6e7e7ba125a2549143501c3de44427633f0bfa6c0d8b6f66aa95d503874065

View file

@ -0,0 +1 @@
44b5afe743b753a54f3e68da2fd2701837e7e8cff276ff1e8c349030c83ac72e

View file

@ -0,0 +1 @@
1b46820f12611b2759eb843688cd13b6024f2096b7986f205398bb029e0c60bd

View file

@ -0,0 +1 @@
27a9a8bb08cea7b0a9b9763e332a6833d4fead1a885cdd59a1f5161e3726d6b1

View file

@ -0,0 +1 @@
ab0dee2cc24f30eb51b376a0385302b45bfeddb373348525dab7f551c27ffec2

View file

@ -0,0 +1 @@
aef404c7e38aec5387c39cf3a2911688324c1b9b520e5f541b9fd3fd6eefd3a8

View file

@ -167,3 +167,42 @@ impl Styling {
self.theme.clone()
}
}
#[cfg(test)]
mod tests {
use super::*;
use rayon::prelude::*;
use iced_test::{Error, simulator};
#[test]
#[ignore]
fn it_showcases_every_theme() -> Result<(), Error> {
Theme::ALL
.par_iter()
.cloned()
.map(|theme| {
let mut styling = Styling::default();
styling.update(Message::ThemeChanged(theme));
let theme = styling.theme();
let mut ui = simulator(styling.view());
let snapshot = ui.snapshot(&theme)?;
assert!(
snapshot.matches_hash(format!(
"snapshots/{theme}",
theme = theme
.to_string()
.to_ascii_lowercase()
.replace(" ", "_")
))?,
"snapshots for {theme} should match!"
);
Ok(())
})
.collect()
}
}

View file

@ -327,9 +327,10 @@ mod toast {
instants.truncate(new);
}
(old, new) if old < new => {
instants.extend(
std::iter::repeat(Some(Instant::now())).take(new - old),
);
instants.extend(std::iter::repeat_n(
Some(Instant::now()),
new - old,
));
}
_ => {}
}

View file

@ -7,14 +7,15 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["async-std", "debug"]
iced.features = ["tokio", "debug"]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
async-std.workspace = true
tokio.workspace = true
tokio.features = ["fs", "time"]
directories = "6.0"
tracing-subscriber = "0.3"

View file

@ -483,7 +483,6 @@ enum LoadError {
#[derive(Debug, Clone)]
enum SaveError {
File,
Write,
Format,
}
@ -505,15 +504,7 @@ impl SavedState {
}
async fn load() -> Result<SavedState, LoadError> {
use async_std::prelude::*;
let mut contents = String::new();
let mut file = async_std::fs::File::open(Self::path())
.await
.map_err(|_| LoadError::File)?;
file.read_to_string(&mut contents)
let contents = tokio::fs::read_to_string(Self::path())
.await
.map_err(|_| LoadError::File)?;
@ -521,31 +512,25 @@ impl SavedState {
}
async fn save(self) -> Result<(), SaveError> {
use async_std::prelude::*;
let json = serde_json::to_string_pretty(&self)
.map_err(|_| SaveError::Format)?;
let path = Self::path();
if let Some(dir) = path.parent() {
async_std::fs::create_dir_all(dir)
tokio::fs::create_dir_all(dir)
.await
.map_err(|_| SaveError::File)?;
.map_err(|_| SaveError::Write)?;
}
{
let mut file = async_std::fs::File::create(path)
.await
.map_err(|_| SaveError::File)?;
file.write_all(json.as_bytes())
tokio::fs::write(path, json.as_bytes())
.await
.map_err(|_| SaveError::Write)?;
}
// This is a simple way to save at most once every couple seconds
async_std::task::sleep(std::time::Duration::from_secs(2)).await;
tokio::time::sleep(std::time::Duration::from_secs(2)).await;
Ok(())
}
@ -571,7 +556,7 @@ impl SavedState {
}
async fn save(self) -> Result<(), SaveError> {
let storage = Self::storage().ok_or(SaveError::File)?;
let storage = Self::storage().ok_or(SaveError::Write)?;
let json = serde_json::to_string_pretty(&self)
.map_err(|_| SaveError::Format)?;

View file

@ -7,7 +7,7 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["debug", "tokio"]
iced.features = ["debug", "tokio", "sipper"]
warp = "0.3"