summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/arc/src/main.rs4
-rw-r--r--examples/bezier_tool/src/main.rs7
-rw-r--r--examples/clock/src/main.rs53
-rw-r--r--examples/color_palette/src/main.rs1
-rw-r--r--examples/counter/Cargo.toml5
-rw-r--r--examples/counter/src/main.rs28
-rw-r--r--examples/editor/src/main.rs6
-rw-r--r--examples/game_of_life/src/main.rs7
-rw-r--r--examples/geometry/src/main.rs8
-rw-r--r--examples/gradient/src/main.rs10
-rw-r--r--examples/integration/src/controls.rs11
-rw-r--r--examples/layout/src/main.rs11
-rw-r--r--examples/loading_spinners/Cargo.toml1
-rw-r--r--examples/loading_spinners/src/easing.rs15
-rw-r--r--examples/multi_window/src/main.rs4
-rw-r--r--examples/pane_grid/src/main.rs13
-rw-r--r--examples/progress_bar/src/main.rs42
-rw-r--r--examples/screenshot/src/main.rs10
-rw-r--r--examples/scrollable/Cargo.toml2
-rw-r--r--examples/scrollable/src/main.rs5
-rw-r--r--examples/stopwatch/src/main.rs6
-rw-r--r--examples/styling/src/main.rs54
-rw-r--r--examples/svg/src/main.rs12
-rw-r--r--examples/the_matrix/src/main.rs6
-rw-r--r--examples/toast/src/main.rs7
-rw-r--r--examples/todos/Cargo.toml5
-rw-r--r--examples/todos/snapshots/creates_a_new_task.sha2561
-rw-r--r--examples/todos/src/main.rs61
-rw-r--r--examples/tour/Cargo.toml2
-rw-r--r--examples/tour/src/main.rs22
-rw-r--r--examples/visible_bounds/Cargo.toml2
-rw-r--r--examples/visible_bounds/src/main.rs10
-rw-r--r--examples/websocket/Cargo.toml1
-rw-r--r--examples/websocket/src/main.rs5
34 files changed, 307 insertions, 130 deletions
diff --git a/examples/arc/src/main.rs b/examples/arc/src/main.rs
index 18873259..88544caa 100644
--- a/examples/arc/src/main.rs
+++ b/examples/arc/src/main.rs
@@ -4,6 +4,7 @@ use iced::mouse;
use iced::widget::canvas::{
self, stroke, Cache, Canvas, Geometry, Path, Stroke,
};
+use iced::window;
use iced::{Element, Fill, Point, Rectangle, Renderer, Subscription, Theme};
pub fn main() -> iced::Result {
@@ -34,8 +35,7 @@ impl Arc {
}
fn subscription(&self) -> Subscription<Message> {
- iced::time::every(std::time::Duration::from_millis(10))
- .map(|_| Message::Tick)
+ window::frames().map(|_| Message::Tick)
}
}
diff --git a/examples/bezier_tool/src/main.rs b/examples/bezier_tool/src/main.rs
index e8f0efc9..4d438bd9 100644
--- a/examples/bezier_tool/src/main.rs
+++ b/examples/bezier_tool/src/main.rs
@@ -1,6 +1,6 @@
//! This example showcases an interactive `Canvas` for drawing Bézier curves.
-use iced::widget::{button, container, horizontal_space, hover};
-use iced::{Element, Fill, Theme};
+use iced::widget::{button, container, horizontal_space, hover, right};
+use iced::{Element, Theme};
pub fn main() -> iced::Result {
iced::application("Bezier Tool - Iced", Example::update, Example::view)
@@ -41,13 +41,12 @@ impl Example {
if self.curves.is_empty() {
container(horizontal_space())
} else {
- container(
+ right(
button("Clear")
.style(button::danger)
.on_press(Message::Clear),
)
.padding(10)
- .align_right(Fill)
},
))
.padding(20)
diff --git a/examples/clock/src/main.rs b/examples/clock/src/main.rs
index ef3064c7..0810594f 100644
--- a/examples/clock/src/main.rs
+++ b/examples/clock/src/main.rs
@@ -1,11 +1,11 @@
-use iced::alignment;
use iced::mouse;
-use iced::time;
+use iced::time::{self, milliseconds};
use iced::widget::canvas::{stroke, Cache, Geometry, LineCap, Path, Stroke};
use iced::widget::{canvas, container};
+use iced::{alignment, Radians};
use iced::{
- Degrees, Element, Fill, Font, Point, Rectangle, Renderer, Subscription,
- Theme, Vector,
+ Degrees, Element, Fill, Font, Point, Rectangle, Renderer, Size,
+ Subscription, Theme, Vector,
};
pub fn main() -> iced::Result {
@@ -49,7 +49,7 @@ impl Clock {
}
fn subscription(&self) -> Subscription<Message> {
- time::every(time::Duration::from_millis(500))
+ time::every(milliseconds(500))
.map(|_| Message::Tick(chrono::offset::Local::now()))
}
@@ -117,9 +117,14 @@ impl<Message> canvas::Program<Message> for Clock {
};
frame.translate(Vector::new(center.x, center.y));
+ let minutes_portion =
+ Radians::from(hand_rotation(self.now.minute(), 60)) / 12.0;
+ let hour_hand_angle =
+ Radians::from(hand_rotation(self.now.hour(), 12))
+ + minutes_portion;
frame.with_save(|frame| {
- frame.rotate(hand_rotation(self.now.hour(), 12));
+ frame.rotate(hour_hand_angle);
frame.stroke(&short_hand, wide_stroke());
});
@@ -155,6 +160,42 @@ impl<Message> canvas::Program<Message> for Clock {
..canvas::Text::default()
});
});
+
+ // Draw clock numbers
+ for hour in 1..=12 {
+ let angle = Radians::from(hand_rotation(hour, 12))
+ - Radians::from(Degrees(90.0));
+ let x = radius * angle.0.cos();
+ let y = radius * angle.0.sin();
+
+ frame.fill_text(canvas::Text {
+ content: format!("{}", hour),
+ size: (radius / 5.0).into(),
+ position: Point::new(x * 0.82, y * 0.82),
+ color: palette.secondary.strong.text,
+ horizontal_alignment: alignment::Horizontal::Center,
+ vertical_alignment: alignment::Vertical::Center,
+ font: Font::MONOSPACE,
+ ..canvas::Text::default()
+ });
+ }
+
+ // Draw ticks
+ for tick in 0..60 {
+ let angle = hand_rotation(tick, 60);
+ let width = if tick % 5 == 0 { 3.0 } else { 1.0 };
+
+ frame.with_save(|frame| {
+ frame.rotate(angle);
+ frame.fill(
+ &Path::rectangle(
+ Point::new(0.0, radius - 15.0),
+ Size::new(width, 7.0),
+ ),
+ palette.secondary.strong.text,
+ );
+ });
+ }
});
vec![clock]
diff --git a/examples/color_palette/src/main.rs b/examples/color_palette/src/main.rs
index 7f21003b..1a86b168 100644
--- a/examples/color_palette/src/main.rs
+++ b/examples/color_palette/src/main.rs
@@ -89,6 +89,7 @@ impl ColorPalette {
primary: *self.theme.lower.first().unwrap(),
text: *self.theme.higher.last().unwrap(),
success: *self.theme.lower.last().unwrap(),
+ warning: *self.theme.higher.last().unwrap(),
danger: *self.theme.higher.last().unwrap(),
},
)
diff --git a/examples/counter/Cargo.toml b/examples/counter/Cargo.toml
index 22f86064..02eac329 100644
--- a/examples/counter/Cargo.toml
+++ b/examples/counter/Cargo.toml
@@ -10,4 +10,7 @@ iced.workspace = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
-iced.features = ["webgl"]
+iced.features = ["webgl", "fira-sans"]
+
+[dev-dependencies]
+iced_test.workspace = true
diff --git a/examples/counter/src/main.rs b/examples/counter/src/main.rs
index 81684c1c..18bb8cfe 100644
--- a/examples/counter/src/main.rs
+++ b/examples/counter/src/main.rs
@@ -38,3 +38,31 @@ impl Counter {
.align_x(Center)
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use iced_test::selector::text;
+ use iced_test::{simulator, Error};
+
+ #[test]
+ fn it_counts() -> Result<(), Error> {
+ let mut counter = Counter { value: 0 };
+ let mut ui = simulator(counter.view());
+
+ let _ = ui.click(text("Increment"))?;
+ let _ = ui.click(text("Increment"))?;
+ let _ = ui.click(text("Decrement"))?;
+
+ for message in ui.into_messages() {
+ counter.update(message);
+ }
+
+ assert_eq!(counter.value, 1);
+
+ let mut ui = simulator(counter.view());
+ assert!(ui.find(text("1")).is_ok(), "Counter should display 1!");
+
+ Ok(())
+ }
+}
diff --git a/examples/editor/src/main.rs b/examples/editor/src/main.rs
index d55f9bdf..7032324a 100644
--- a/examples/editor/src/main.rs
+++ b/examples/editor/src/main.rs
@@ -1,8 +1,8 @@
use iced::highlighter;
use iced::keyboard;
use iced::widget::{
- self, button, column, container, horizontal_space, pick_list, row, text,
- text_editor, toggler, tooltip,
+ self, button, center_x, column, container, horizontal_space, pick_list,
+ row, text, text_editor, toggler, tooltip,
};
use iced::{Center, Element, Fill, Font, Task, Theme};
@@ -288,7 +288,7 @@ fn action<'a, Message: Clone + 'a>(
label: &'a str,
on_press: Option<Message>,
) -> Element<'a, Message> {
- let action = button(container(content).center_x(30));
+ let action = button(center_x(content).width(30));
if let Some(on_press) = on_press {
tooltip(
diff --git a/examples/game_of_life/src/main.rs b/examples/game_of_life/src/main.rs
index 7a7224d5..1008e477 100644
--- a/examples/game_of_life/src/main.rs
+++ b/examples/game_of_life/src/main.rs
@@ -5,12 +5,11 @@ mod preset;
use grid::Grid;
use preset::Preset;
-use iced::time;
+use iced::time::{self, milliseconds};
use iced::widget::{
button, checkbox, column, container, pick_list, row, slider, text,
};
use iced::{Center, Element, Fill, Subscription, Task, Theme};
-use std::time::Duration;
pub fn main() -> iced::Result {
tracing_subscriber::fmt::init();
@@ -112,7 +111,7 @@ impl GameOfLife {
fn subscription(&self) -> Subscription<Message> {
if self.is_playing {
- time::every(Duration::from_millis(1000 / self.speed as u64))
+ time::every(milliseconds(1000 / self.speed as u64))
.map(|_| Message::Tick)
} else {
Subscription::none()
@@ -191,6 +190,7 @@ mod grid {
use crate::Preset;
use iced::alignment;
use iced::mouse;
+ use iced::time::{Duration, Instant};
use iced::touch;
use iced::widget::canvas;
use iced::widget::canvas::{
@@ -202,7 +202,6 @@ mod grid {
use rustc_hash::{FxHashMap, FxHashSet};
use std::future::Future;
use std::ops::RangeInclusive;
- use std::time::{Duration, Instant};
pub struct Grid {
state: State,
diff --git a/examples/geometry/src/main.rs b/examples/geometry/src/main.rs
index d53ae6a5..44214c63 100644
--- a/examples/geometry/src/main.rs
+++ b/examples/geometry/src/main.rs
@@ -152,8 +152,8 @@ mod rainbow {
}
}
-use iced::widget::{column, container, scrollable};
-use iced::{Element, Length};
+use iced::widget::{center_x, center_y, column, scrollable};
+use iced::Element;
use rainbow::rainbow;
pub fn main() -> iced::Result {
@@ -176,7 +176,7 @@ fn view(_state: &()) -> Element<'_, ()> {
.spacing(20)
.max_width(500);
- let scrollable = scrollable(container(content).center_x(Length::Fill));
+ let scrollable = scrollable(center_x(content));
- container(scrollable).center_y(Length::Fill).into()
+ center_y(scrollable).into()
}
diff --git a/examples/gradient/src/main.rs b/examples/gradient/src/main.rs
index b2de069f..910ea9fc 100644
--- a/examples/gradient/src/main.rs
+++ b/examples/gradient/src/main.rs
@@ -1,5 +1,5 @@
-use iced::application;
use iced::gradient;
+use iced::theme;
use iced::widget::{
checkbox, column, container, horizontal_space, row, slider, text,
};
@@ -95,16 +95,14 @@ impl Gradient {
.into()
}
- fn style(&self, theme: &Theme) -> application::Appearance {
- use application::DefaultStyle;
-
+ fn style(&self, theme: &Theme) -> theme::Style {
if self.transparent {
- application::Appearance {
+ theme::Style {
background_color: Color::TRANSPARENT,
text_color: theme.palette().text,
}
} else {
- Theme::default_style(theme)
+ theme::default(theme)
}
}
}
diff --git a/examples/integration/src/controls.rs b/examples/integration/src/controls.rs
index 0b11a323..b92e4987 100644
--- a/examples/integration/src/controls.rs
+++ b/examples/integration/src/controls.rs
@@ -1,6 +1,6 @@
use iced_wgpu::Renderer;
-use iced_widget::{column, container, row, slider, text, text_input};
-use iced_winit::core::{Color, Element, Length::*, Theme};
+use iced_widget::{bottom, column, row, slider, text, text_input};
+use iced_winit::core::{Color, Element, Theme};
use iced_winit::runtime::{Program, Task};
pub struct Controls {
@@ -74,18 +74,17 @@ impl Program for Controls {
.width(500)
.spacing(20);
- container(
+ bottom(
column![
text("Background color").color(Color::WHITE),
text!("{background_color:?}").size(14).color(Color::WHITE),
- text_input("Placeholder", &self.input)
- .on_input(Message::InputChanged),
sliders,
+ text_input("Type something...", &self.input)
+ .on_input(Message::InputChanged),
]
.spacing(10),
)
.padding(10)
- .align_bottom(Fill)
.into()
}
}
diff --git a/examples/layout/src/main.rs b/examples/layout/src/main.rs
index e83a1f7d..b298dce4 100644
--- a/examples/layout/src/main.rs
+++ b/examples/layout/src/main.rs
@@ -2,9 +2,9 @@ use iced::border;
use iced::keyboard;
use iced::mouse;
use iced::widget::{
- button, canvas, center, checkbox, column, container, horizontal_rule,
- horizontal_space, pick_list, pin, row, scrollable, stack, text,
- vertical_rule,
+ button, canvas, center, center_y, checkbox, column, container,
+ horizontal_rule, horizontal_space, pick_list, pin, row, scrollable, stack,
+ text, vertical_rule,
};
use iced::{
color, Center, Element, Fill, Font, Length, Point, Rectangle, Renderer,
@@ -253,15 +253,14 @@ fn application<'a>() -> Element<'a, Message> {
.border(border::color(palette.background.strong.color).width(1))
});
- let sidebar = container(
+ let sidebar = center_y(
column!["Sidebar!", square(50), square(50)]
.spacing(40)
.padding(10)
.width(200)
.align_x(Center),
)
- .style(container::rounded_box)
- .center_y(Fill);
+ .style(container::rounded_box);
let content = container(
scrollable(
diff --git a/examples/loading_spinners/Cargo.toml b/examples/loading_spinners/Cargo.toml
index a32da386..abd28aec 100644
--- a/examples/loading_spinners/Cargo.toml
+++ b/examples/loading_spinners/Cargo.toml
@@ -10,4 +10,3 @@ iced.workspace = true
iced.features = ["advanced", "canvas"]
lyon_algorithms = "1.0"
-once_cell.workspace = true \ No newline at end of file
diff --git a/examples/loading_spinners/src/easing.rs b/examples/loading_spinners/src/easing.rs
index 45089ef6..8caf282d 100644
--- a/examples/loading_spinners/src/easing.rs
+++ b/examples/loading_spinners/src/easing.rs
@@ -2,40 +2,41 @@ use iced::Point;
use lyon_algorithms::measure::PathMeasurements;
use lyon_algorithms::path::{builder::NoAttributes, path::BuilderImpl, Path};
-use once_cell::sync::Lazy;
-pub static EMPHASIZED: Lazy<Easing> = Lazy::new(|| {
+use std::sync::LazyLock;
+
+pub static EMPHASIZED: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.05, 0.0], [0.133333, 0.06], [0.166666, 0.4])
.cubic_bezier_to([0.208333, 0.82], [0.25, 1.0], [1.0, 1.0])
.build()
});
-pub static EMPHASIZED_DECELERATE: Lazy<Easing> = Lazy::new(|| {
+pub static EMPHASIZED_DECELERATE: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.05, 0.7], [0.1, 1.0], [1.0, 1.0])
.build()
});
-pub static EMPHASIZED_ACCELERATE: Lazy<Easing> = Lazy::new(|| {
+pub static EMPHASIZED_ACCELERATE: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.3, 0.0], [0.8, 0.15], [1.0, 1.0])
.build()
});
-pub static STANDARD: Lazy<Easing> = Lazy::new(|| {
+pub static STANDARD: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.2, 0.0], [0.0, 1.0], [1.0, 1.0])
.build()
});
-pub static STANDARD_DECELERATE: Lazy<Easing> = Lazy::new(|| {
+pub static STANDARD_DECELERATE: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.0, 0.0], [0.0, 1.0], [1.0, 1.0])
.build()
});
-pub static STANDARD_ACCELERATE: Lazy<Easing> = Lazy::new(|| {
+pub static STANDARD_ACCELERATE: LazyLock<Easing> = LazyLock::new(|| {
Easing::builder()
.cubic_bezier_to([0.3, 0.0], [1.0, 1.0], [1.0, 1.0])
.build()
diff --git a/examples/multi_window/src/main.rs b/examples/multi_window/src/main.rs
index b43a627a..f9021c8d 100644
--- a/examples/multi_window/src/main.rs
+++ b/examples/multi_window/src/main.rs
@@ -1,5 +1,5 @@
use iced::widget::{
- button, center, column, container, horizontal_space, scrollable, text,
+ button, center, center_x, column, horizontal_space, scrollable, text,
text_input,
};
use iced::window;
@@ -193,6 +193,6 @@ impl Window {
.align_x(Center),
);
- container(content).center_x(200).into()
+ center_x(content).width(200).into()
}
}
diff --git a/examples/pane_grid/src/main.rs b/examples/pane_grid/src/main.rs
index 67f4d27f..17ba5804 100644
--- a/examples/pane_grid/src/main.rs
+++ b/examples/pane_grid/src/main.rs
@@ -1,7 +1,7 @@
use iced::keyboard;
use iced::widget::pane_grid::{self, PaneGrid};
use iced::widget::{
- button, column, container, responsive, row, scrollable, text,
+ button, center_y, column, container, responsive, row, scrollable, text,
};
use iced::{Center, Color, Element, Fill, Size, Subscription};
@@ -196,11 +196,7 @@ impl Example {
.on_drag(Message::Dragged)
.on_resize(10, Message::Resized);
- container(pane_grid)
- .width(Fill)
- .height(Fill)
- .padding(10)
- .into()
+ container(pane_grid).padding(10).into()
}
}
@@ -295,10 +291,7 @@ fn view_content<'a>(
.spacing(10)
.align_x(Center);
- container(scrollable(content))
- .center_y(Fill)
- .padding(5)
- .into()
+ center_y(scrollable(content)).padding(5).into()
}
fn view_controls<'a>(
diff --git a/examples/progress_bar/src/main.rs b/examples/progress_bar/src/main.rs
index 67da62f2..e431a404 100644
--- a/examples/progress_bar/src/main.rs
+++ b/examples/progress_bar/src/main.rs
@@ -1,4 +1,7 @@
-use iced::widget::{column, progress_bar, slider};
+use iced::widget::{
+ center, center_x, checkbox, column, progress_bar, row, slider,
+ vertical_slider,
+};
use iced::Element;
pub fn main() -> iced::Result {
@@ -8,25 +11,58 @@ pub fn main() -> iced::Result {
#[derive(Default)]
struct Progress {
value: f32,
+ is_vertical: bool,
}
#[derive(Debug, Clone, Copy)]
enum Message {
SliderChanged(f32),
+ ToggleVertical(bool),
}
impl Progress {
fn update(&mut self, message: Message) {
match message {
Message::SliderChanged(x) => self.value = x,
+ Message::ToggleVertical(is_vertical) => {
+ self.is_vertical = is_vertical
+ }
}
}
fn view(&self) -> Element<Message> {
+ let bar = progress_bar(0.0..=100.0, self.value);
+
column![
- progress_bar(0.0..=100.0, self.value),
- slider(0.0..=100.0, self.value, Message::SliderChanged).step(0.01)
+ if self.is_vertical {
+ center(
+ row![
+ bar.vertical(),
+ vertical_slider(
+ 0.0..=100.0,
+ self.value,
+ Message::SliderChanged
+ )
+ .step(0.01)
+ ]
+ .spacing(20),
+ )
+ } else {
+ center(
+ column![
+ bar,
+ slider(0.0..=100.0, self.value, Message::SliderChanged)
+ .step(0.01)
+ ]
+ .spacing(20),
+ )
+ },
+ center_x(
+ checkbox("Vertical", self.is_vertical)
+ .on_toggle(Message::ToggleVertical)
+ ),
]
+ .spacing(20)
.padding(20)
.into()
}
diff --git a/examples/screenshot/src/main.rs b/examples/screenshot/src/main.rs
index 5c105f6c..7766542d 100644
--- a/examples/screenshot/src/main.rs
+++ b/examples/screenshot/src/main.rs
@@ -1,5 +1,7 @@
use iced::keyboard;
-use iced::widget::{button, column, container, image, row, text, text_input};
+use iced::widget::{
+ button, center_y, column, container, image, row, text, text_input,
+};
use iced::window;
use iced::window::screenshot::{self, Screenshot};
use iced::{
@@ -131,8 +133,8 @@ impl Example {
text("Press the button to take a screenshot!").into()
};
- let image = container(image)
- .center_y(FillPortion(2))
+ let image = center_y(image)
+ .height(FillPortion(2))
.padding(10)
.style(container::rounded_box);
@@ -211,7 +213,7 @@ impl Example {
.spacing(40)
};
- let side_content = container(controls).center_y(Fill);
+ let side_content = center_y(controls);
let content = row![side_content, image]
.spacing(10)
diff --git a/examples/scrollable/Cargo.toml b/examples/scrollable/Cargo.toml
index f8c735c0..ba291520 100644
--- a/examples/scrollable/Cargo.toml
+++ b/examples/scrollable/Cargo.toml
@@ -8,5 +8,3 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["debug"]
-
-once_cell.workspace = true
diff --git a/examples/scrollable/src/main.rs b/examples/scrollable/src/main.rs
index de4f2f9a..6359fb5a 100644
--- a/examples/scrollable/src/main.rs
+++ b/examples/scrollable/src/main.rs
@@ -4,9 +4,10 @@ use iced::widget::{
};
use iced::{Border, Center, Color, Element, Fill, Task, Theme};
-use once_cell::sync::Lazy;
+use std::sync::LazyLock;
-static SCROLLABLE_ID: Lazy<scrollable::Id> = Lazy::new(scrollable::Id::unique);
+static SCROLLABLE_ID: LazyLock<scrollable::Id> =
+ LazyLock::new(scrollable::Id::unique);
pub fn main() -> iced::Result {
iced::application(
diff --git a/examples/stopwatch/src/main.rs b/examples/stopwatch/src/main.rs
index 0d824d36..a814da55 100644
--- a/examples/stopwatch/src/main.rs
+++ b/examples/stopwatch/src/main.rs
@@ -1,10 +1,8 @@
use iced::keyboard;
-use iced::time;
+use iced::time::{self, milliseconds, Duration, Instant};
use iced::widget::{button, center, column, row, text};
use iced::{Center, Element, Subscription, Theme};
-use std::time::{Duration, Instant};
-
pub fn main() -> iced::Result {
iced::application("Stopwatch - Iced", Stopwatch::update, Stopwatch::view)
.subscription(Stopwatch::subscription)
@@ -63,7 +61,7 @@ impl Stopwatch {
let tick = match self.state {
State::Idle => Subscription::none(),
State::Ticking { .. } => {
- time::every(Duration::from_millis(10)).map(Message::Tick)
+ time::every(milliseconds(10)).map(Message::Tick)
}
};
diff --git a/examples/styling/src/main.rs b/examples/styling/src/main.rs
index 534f5e32..594be4a7 100644
--- a/examples/styling/src/main.rs
+++ b/examples/styling/src/main.rs
@@ -1,12 +1,14 @@
+use iced::keyboard;
use iced::widget::{
button, center, checkbox, column, horizontal_rule, pick_list, progress_bar,
row, scrollable, slider, text, text_input, toggler, vertical_rule,
vertical_space,
};
-use iced::{Center, Element, Fill, Theme};
+use iced::{Center, Element, Fill, Subscription, Theme};
pub fn main() -> iced::Result {
iced::application("Styling - Iced", Styling::update, Styling::view)
+ .subscription(Styling::subscription)
.theme(Styling::theme)
.run()
}
@@ -28,6 +30,8 @@ enum Message {
SliderChanged(f32),
CheckboxToggled(bool),
TogglerToggled(bool),
+ PreviousTheme,
+ NextTheme,
}
impl Styling {
@@ -41,6 +45,23 @@ impl Styling {
Message::SliderChanged(value) => self.slider_value = value,
Message::CheckboxToggled(value) => self.checkbox_value = value,
Message::TogglerToggled(value) => self.toggler_value = value,
+ Message::PreviousTheme | Message::NextTheme => {
+ if let Some(current) = Theme::ALL
+ .iter()
+ .position(|candidate| &self.theme == candidate)
+ {
+ self.theme = if matches!(message, Message::NextTheme) {
+ Theme::ALL[(current + 1) % Theme::ALL.len()].clone()
+ } else if current == 0 {
+ Theme::ALL
+ .last()
+ .expect("Theme::ALL must not be empty")
+ .clone()
+ } else {
+ Theme::ALL[current - 1].clone()
+ };
+ }
+ }
}
}
@@ -57,9 +78,16 @@ impl Styling {
.padding(10)
.size(20);
- let button = button("Submit")
- .padding(10)
- .on_press(Message::ButtonPressed);
+ let styled_button = |label| {
+ button(text(label).width(Fill).center())
+ .padding(10)
+ .on_press(Message::ButtonPressed)
+ };
+
+ let primary = styled_button("Primary");
+ let success = styled_button("Success").style(button::success);
+ let warning = styled_button("Warning").style(button::warning);
+ let danger = styled_button("Danger").style(button::danger);
let slider =
slider(0.0..=100.0, self.slider_value, Message::SliderChanged);
@@ -85,7 +113,10 @@ impl Styling {
let content = column![
choose_theme,
horizontal_rule(38),
- row![text_input, button].spacing(10).align_y(Center),
+ text_input,
+ row![primary, success, warning, danger]
+ .spacing(10)
+ .align_y(Center),
slider,
progress_bar,
row![
@@ -104,6 +135,19 @@ impl Styling {
center(content).into()
}
+ fn subscription(&self) -> Subscription<Message> {
+ keyboard::on_key_press(|key, _modifiers| match key {
+ keyboard::Key::Named(
+ keyboard::key::Named::ArrowUp | keyboard::key::Named::ArrowLeft,
+ ) => Some(Message::PreviousTheme),
+ keyboard::Key::Named(
+ keyboard::key::Named::ArrowDown
+ | keyboard::key::Named::ArrowRight,
+ ) => Some(Message::NextTheme),
+ _ => None,
+ })
+ }
+
fn theme(&self) -> Theme {
self.theme.clone()
}
diff --git a/examples/svg/src/main.rs b/examples/svg/src/main.rs
index 02cb85cc..c4be8fb8 100644
--- a/examples/svg/src/main.rs
+++ b/examples/svg/src/main.rs
@@ -1,4 +1,4 @@
-use iced::widget::{center, checkbox, column, container, svg};
+use iced::widget::{center, center_x, checkbox, column, svg};
use iced::{color, Element, Fill};
pub fn main() -> iced::Result {
@@ -46,12 +46,8 @@ impl Tiger {
checkbox("Apply a color filter", self.apply_color_filter)
.on_toggle(Message::ToggleColorFilter);
- center(
- column![svg, container(apply_color_filter).center_x(Fill)]
- .spacing(20)
- .height(Fill),
- )
- .padding(20)
- .into()
+ center(column![svg, center_x(apply_color_filter)].spacing(20))
+ .padding(20)
+ .into()
}
}
diff --git a/examples/the_matrix/src/main.rs b/examples/the_matrix/src/main.rs
index 0ed52dda..315e9ee5 100644
--- a/examples/the_matrix/src/main.rs
+++ b/examples/the_matrix/src/main.rs
@@ -1,5 +1,5 @@
use iced::mouse;
-use iced::time::{self, Instant};
+use iced::time::{self, milliseconds, Instant};
use iced::widget::canvas;
use iced::{
Color, Element, Fill, Font, Point, Rectangle, Renderer, Subscription, Theme,
@@ -36,11 +36,11 @@ impl TheMatrix {
}
fn view(&self) -> Element<Message> {
- canvas(self as &Self).width(Fill).height(Fill).into()
+ canvas(self).width(Fill).height(Fill).into()
}
fn subscription(&self) -> Subscription<Message> {
- time::every(std::time::Duration::from_millis(50)).map(Message::Tick)
+ time::every(milliseconds(50)).map(Message::Tick)
}
}
diff --git a/examples/toast/src/main.rs b/examples/toast/src/main.rs
index a1b5886f..2ae9bfe2 100644
--- a/examples/toast/src/main.rs
+++ b/examples/toast/src/main.rs
@@ -162,7 +162,6 @@ impl Default for App {
mod toast {
use std::fmt;
- use std::time::{Duration, Instant};
use iced::advanced::layout::{self, Layout};
use iced::advanced::overlay;
@@ -171,6 +170,7 @@ mod toast {
use iced::advanced::{Clipboard, Shell, Widget};
use iced::mouse;
use iced::theme;
+ use iced::time::{self, Duration, Instant};
use iced::widget::{
button, column, container, horizontal_rule, horizontal_space, row, text,
};
@@ -502,9 +502,8 @@ mod toast {
self.instants.iter_mut().enumerate().for_each(
|(index, maybe_instant)| {
if let Some(instant) = maybe_instant.as_mut() {
- let remaining =
- Duration::from_secs(self.timeout_secs)
- .saturating_sub(instant.elapsed());
+ let remaining = time::seconds(self.timeout_secs)
+ .saturating_sub(instant.elapsed());
if remaining == Duration::ZERO {
maybe_instant.take();
diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml
index 0d72be86..16f4fdd2 100644
--- a/examples/todos/Cargo.toml
+++ b/examples/todos/Cargo.toml
@@ -20,12 +20,15 @@ tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
-iced.features = ["debug", "webgl"]
+iced.features = ["debug", "webgl", "fira-sans"]
uuid = { version = "1.0", features = ["js"] }
web-sys = { workspace = true, features = ["Window", "Storage"] }
wasm-timer.workspace = true
+[dev-dependencies]
+iced_test.workspace = true
+
[package.metadata.deb]
assets = [
["target/release-opt/todos", "usr/bin/iced-todos", "755"],
diff --git a/examples/todos/snapshots/creates_a_new_task.sha256 b/examples/todos/snapshots/creates_a_new_task.sha256
new file mode 100644
index 00000000..193132c5
--- /dev/null
+++ b/examples/todos/snapshots/creates_a_new_task.sha256
@@ -0,0 +1 @@
+3160686067cb7c738802009cdf2f3c5f5a5bd8c89ada70517388b7adbe64c313 \ No newline at end of file
diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs
index 25e3ead2..7759552c 100644
--- a/examples/todos/src/main.rs
+++ b/examples/todos/src/main.rs
@@ -1,6 +1,6 @@
use iced::keyboard;
use iced::widget::{
- self, button, center, checkbox, column, container, keyed_column, row,
+ self, button, center, center_x, checkbox, column, keyed_column, row,
scrollable, text, text_input, Text,
};
use iced::window;
@@ -15,7 +15,7 @@ pub fn main() -> iced::Result {
iced::application(Todos::title, Todos::update, Todos::view)
.subscription(Todos::subscription)
- .font(include_bytes!("../fonts/icons.ttf").as_slice())
+ .font(Todos::ICON_FONT)
.window_size((500.0, 800.0))
.run_with(Todos::new)
}
@@ -48,6 +48,8 @@ enum Message {
}
impl Todos {
+ const ICON_FONT: &'static [u8] = include_bytes!("../fonts/icons.ttf");
+
fn new() -> (Self, Command<Message>) {
(
Self::Loading,
@@ -147,9 +149,7 @@ impl Todos {
}
}
Message::ToggleFullscreen(mode) => window::get_latest()
- .and_then(move |window| {
- window::change_mode(window, mode)
- }),
+ .and_then(move |window| window::set_mode(window, mode)),
Message::Loaded(_) => Command::none(),
};
@@ -237,7 +237,7 @@ impl Todos {
.spacing(20)
.max_width(800);
- scrollable(container(content).center_x(Fill).padding(40)).into()
+ scrollable(center_x(content).padding(40)).into()
}
}
}
@@ -449,11 +449,10 @@ fn empty_message(message: &str) -> Element<'_, Message> {
}
// Fonts
-const ICONS: Font = Font::with_name("Iced-Todos-Icons");
fn icon(unicode: char) -> Text<'static> {
text(unicode.to_string())
- .font(ICONS)
+ .font(Font::with_name("Iced-Todos-Icons"))
.width(20)
.align_x(Center)
}
@@ -584,3 +583,49 @@ impl SavedState {
Ok(())
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ use iced::{Settings, Theme};
+ use iced_test::selector::text;
+ use iced_test::{Error, Simulator};
+
+ fn simulator(todos: &Todos) -> Simulator<Message> {
+ Simulator::with_settings(
+ Settings {
+ fonts: vec![Todos::ICON_FONT.into()],
+ ..Settings::default()
+ },
+ todos.view(),
+ )
+ }
+
+ #[test]
+ fn it_creates_a_new_task() -> Result<(), Error> {
+ let (mut todos, _command) = Todos::new();
+ let _command = todos.update(Message::Loaded(Err(LoadError::File)));
+
+ let mut ui = simulator(&todos);
+ let _input = ui.click("new-task")?;
+
+ let _ = ui.typewrite("Create the universe");
+ let _ = ui.tap_key(keyboard::key::Named::Enter);
+
+ for message in ui.into_messages() {
+ let _command = todos.update(message);
+ }
+
+ let mut ui = simulator(&todos);
+ let _ = ui.find(text("Create the universe"))?;
+
+ let snapshot = ui.snapshot(&Theme::Dark)?;
+ assert!(
+ snapshot.matches_hash("snapshots/creates_a_new_task")?,
+ "snapshots should match!"
+ );
+
+ Ok(())
+ }
+}
diff --git a/examples/tour/Cargo.toml b/examples/tour/Cargo.toml
index 9e984ad1..719d355f 100644
--- a/examples/tour/Cargo.toml
+++ b/examples/tour/Cargo.toml
@@ -14,7 +14,7 @@ tracing-subscriber = "0.3"
[target.'cfg(target_arch = "wasm32")'.dependencies]
iced.workspace = true
-iced.features = ["image", "debug", "webgl"]
+iced.features = ["image", "debug", "webgl", "fira-sans"]
console_error_panic_hook = "0.1"
console_log = "1.0"
diff --git a/examples/tour/src/main.rs b/examples/tour/src/main.rs
index d8c0b29a..32720c47 100644
--- a/examples/tour/src/main.rs
+++ b/examples/tour/src/main.rs
@@ -1,6 +1,6 @@
use iced::widget::{
- button, checkbox, column, container, horizontal_space, image, radio, row,
- scrollable, slider, text, text_input, toggler, vertical_space,
+ button, center_x, center_y, checkbox, column, horizontal_space, image,
+ radio, row, scrollable, slider, text, text_input, toggler, vertical_space,
};
use iced::widget::{Button, Column, Container, Slider};
use iced::{Center, Color, Element, Fill, Font, Pixels};
@@ -166,16 +166,13 @@ impl Tour {
.padding(20)
.into();
- let scrollable = scrollable(
- container(if self.debug {
- content.explain(Color::BLACK)
- } else {
- content
- })
- .center_x(Fill),
- );
+ let scrollable = scrollable(center_x(if self.debug {
+ content.explain(Color::BLACK)
+ } else {
+ content
+ }));
- container(scrollable).center_y(Fill).into()
+ center_y(scrollable).into()
}
fn can_continue(&self) -> bool {
@@ -543,7 +540,7 @@ fn ferris<'a>(
width: u16,
filter_method: image::FilterMethod,
) -> Container<'a, Message> {
- container(
+ center_x(
// This should go away once we unify resource loading on native
// platforms
if cfg!(target_arch = "wasm32") {
@@ -554,7 +551,6 @@ fn ferris<'a>(
.filter_method(filter_method)
.width(width),
)
- .center_x(Fill)
}
fn padded_button<Message: Clone>(label: &str) -> Button<'_, Message> {
diff --git a/examples/visible_bounds/Cargo.toml b/examples/visible_bounds/Cargo.toml
index 37594b84..1193334d 100644
--- a/examples/visible_bounds/Cargo.toml
+++ b/examples/visible_bounds/Cargo.toml
@@ -8,5 +8,3 @@ publish = false
[dependencies]
iced.workspace = true
iced.features = ["debug"]
-
-once_cell.workspace = true
diff --git a/examples/visible_bounds/src/main.rs b/examples/visible_bounds/src/main.rs
index 77fec65e..f8f9f420 100644
--- a/examples/visible_bounds/src/main.rs
+++ b/examples/visible_bounds/src/main.rs
@@ -157,9 +157,9 @@ impl Example {
}
}
-use once_cell::sync::Lazy;
+use std::sync::LazyLock;
-static OUTER_CONTAINER: Lazy<container::Id> =
- Lazy::new(|| container::Id::new("outer"));
-static INNER_CONTAINER: Lazy<container::Id> =
- Lazy::new(|| container::Id::new("inner"));
+static OUTER_CONTAINER: LazyLock<container::Id> =
+ LazyLock::new(|| container::Id::new("outer"));
+static INNER_CONTAINER: LazyLock<container::Id> =
+ LazyLock::new(|| container::Id::new("inner"));
diff --git a/examples/websocket/Cargo.toml b/examples/websocket/Cargo.toml
index c7075fb3..787dbbe1 100644
--- a/examples/websocket/Cargo.toml
+++ b/examples/websocket/Cargo.toml
@@ -9,7 +9,6 @@ publish = false
iced.workspace = true
iced.features = ["debug", "tokio"]
-once_cell.workspace = true
warp = "0.3"
[dependencies.async-tungstenite]
diff --git a/examples/websocket/src/main.rs b/examples/websocket/src/main.rs
index 8b1efb41..ae658471 100644
--- a/examples/websocket/src/main.rs
+++ b/examples/websocket/src/main.rs
@@ -4,7 +4,7 @@ use iced::widget::{
self, button, center, column, row, scrollable, text, text_input,
};
use iced::{color, Center, Element, Fill, Subscription, Task};
-use once_cell::sync::Lazy;
+use std::sync::LazyLock;
pub fn main() -> iced::Result {
iced::application("WebSocket - Iced", WebSocket::update, WebSocket::view)
@@ -138,4 +138,5 @@ enum State {
Connected(echo::Connection),
}
-static MESSAGE_LOG: Lazy<scrollable::Id> = Lazy::new(scrollable::Id::unique);
+static MESSAGE_LOG: LazyLock<scrollable::Id> =
+ LazyLock::new(scrollable::Id::unique);