summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-11 00:44:56 +0100
committerLibravatar Héctor Ramón Jiménez <hector0193@gmail.com>2020-01-11 00:44:56 +0100
commitde71776e02495df5dc962fb8b8853f666ab8be4f (patch)
tree1f87cc68dc554783c6102f3587377f9956bcddba /examples
parente879982cfdf0c6a1c6781a9bc46e0a77839de88f (diff)
parent84f1a936db93c16255a07f079c47e351635586f4 (diff)
downloadiced-de71776e02495df5dc962fb8b8853f666ab8be4f.tar.gz
iced-de71776e02495df5dc962fb8b8853f666ab8be4f.tar.bz2
iced-de71776e02495df5dc962fb8b8853f666ab8be4f.zip
Merge branch 'master' into paint-example
Diffstat (limited to 'examples')
-rw-r--r--examples/custom_widget.rs10
-rw-r--r--examples/events.rs12
-rw-r--r--examples/geometry.rs3
-rw-r--r--examples/pokedex.rs52
-rw-r--r--examples/progress_bar.rs22
-rw-r--r--examples/stopwatch.rs49
-rw-r--r--examples/styling.rs514
-rw-r--r--examples/svg.rs12
-rw-r--r--examples/todos.rs110
-rw-r--r--examples/tour.rs67
10 files changed, 727 insertions, 124 deletions
diff --git a/examples/custom_widget.rs b/examples/custom_widget.rs
index cf2f7792..0a570745 100644
--- a/examples/custom_widget.rs
+++ b/examples/custom_widget.rs
@@ -13,7 +13,7 @@ mod circle {
layout, Background, Color, Element, Hasher, Layout, Length,
MouseCursor, Point, Size, Widget,
};
- use iced_wgpu::{Primitive, Renderer};
+ use iced_wgpu::{Defaults, Primitive, Renderer};
pub struct Circle {
radius: u16,
@@ -54,6 +54,7 @@ mod circle {
fn draw(
&self,
_renderer: &mut Renderer,
+ _defaults: &Defaults,
layout: Layout<'_>,
_cursor_position: Point,
) -> (Primitive, MouseCursor) {
@@ -62,6 +63,8 @@ mod circle {
bounds: layout.bounds(),
background: Background::Color(Color::BLACK),
border_radius: self.radius,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
},
MouseCursor::OutOfBounds,
)
@@ -124,10 +127,7 @@ impl Sandbox for Example {
.max_width(500)
.align_items(Align::Center)
.push(Circle::new(self.radius))
- .push(
- Text::new(format!("Radius: {}", self.radius.to_string()))
- .width(Length::Shrink),
- )
+ .push(Text::new(format!("Radius: {}", self.radius.to_string())))
.push(Slider::new(
&mut self.slider,
1.0..=100.0,
diff --git a/examples/events.rs b/examples/events.rs
index 7d83fbd8..74542171 100644
--- a/examples/events.rs
+++ b/examples/events.rs
@@ -57,13 +57,9 @@ impl Application for Events {
fn view(&mut self) -> Element<Message> {
let events = self.last.iter().fold(
- Column::new().width(Length::Shrink).spacing(10),
+ Column::new().spacing(10),
|column, event| {
- column.push(
- Text::new(format!("{:?}", event))
- .size(40)
- .width(Length::Shrink),
- )
+ column.push(Text::new(format!("{:?}", event)).size(40))
},
);
@@ -71,11 +67,9 @@ impl Application for Events {
self.enabled,
"Listen to runtime events",
Message::Toggled,
- )
- .width(Length::Shrink);
+ );
let content = Column::new()
- .width(Length::Shrink)
.align_items(Align::Center)
.spacing(20)
.push(events)
diff --git a/examples/geometry.rs b/examples/geometry.rs
index ae6c9ca0..9d5fd611 100644
--- a/examples/geometry.rs
+++ b/examples/geometry.rs
@@ -16,7 +16,7 @@ mod rainbow {
};
use iced_wgpu::{
triangle::{Mesh2D, Vertex2D},
- Primitive, Renderer,
+ Defaults, Primitive, Renderer,
};
pub struct Rainbow;
@@ -51,6 +51,7 @@ mod rainbow {
fn draw(
&self,
_renderer: &mut Renderer,
+ _defaults: &Defaults,
layout: Layout<'_>,
cursor_position: Point,
) -> (Primitive, MouseCursor) {
diff --git a/examples/pokedex.rs b/examples/pokedex.rs
index 2d595ec4..7326f94f 100644
--- a/examples/pokedex.rs
+++ b/examples/pokedex.rs
@@ -1,6 +1,6 @@
use iced::{
- button, image, Align, Application, Button, Color, Column, Command,
- Container, Element, Image, Length, Row, Settings, Text,
+ button, image, Align, Application, Button, Column, Command, Container,
+ Element, Image, Length, Row, Settings, Text,
};
pub fn main() {
@@ -77,11 +77,8 @@ impl Application for Pokedex {
fn view(&mut self) -> Element<Message> {
let content = match self {
- Pokedex::Loading => Column::new().width(Length::Shrink).push(
- Text::new("Searching for Pokémon...")
- .width(Length::Shrink)
- .size(40),
- ),
+ Pokedex::Loading => Column::new()
+ .push(Text::new("Searching for Pokémon...").size(40)),
Pokedex::Loaded { pokemon, search } => Column::new()
.max_width(500)
.spacing(20)
@@ -91,14 +88,9 @@ impl Application for Pokedex {
button(search, "Keep searching!").on_press(Message::Search),
),
Pokedex::Errored { try_again, .. } => Column::new()
- .width(Length::Shrink)
.spacing(20)
.align_items(Align::End)
- .push(
- Text::new("Whoops! Something went wrong...")
- .width(Length::Shrink)
- .size(40),
- )
+ .push(Text::new("Whoops! Something went wrong...").size(40))
.push(button(try_again, "Try again").on_press(Message::Search)),
};
@@ -134,10 +126,13 @@ impl Pokemon {
Row::new()
.align_items(Align::Center)
.spacing(20)
- .push(Text::new(&self.name).size(30))
+ .push(
+ Text::new(&self.name)
+ .size(30)
+ .width(Length::Fill),
+ )
.push(
Text::new(format!("#{}", self.number))
- .width(Length::Shrink)
.size(20)
.color([0.5, 0.5, 0.5]),
),
@@ -219,8 +214,29 @@ impl From<surf::Exception> for Error {
}
fn button<'a>(state: &'a mut button::State, text: &str) -> Button<'a, Message> {
- Button::new(state, Text::new(text).color(Color::WHITE))
- .background(Color::from_rgb(0.11, 0.42, 0.87))
- .border_radius(10)
+ Button::new(state, Text::new(text))
.padding(10)
+ .style(style::Button::Primary)
+}
+
+mod style {
+ use iced::{button, Background, Color, Vector};
+
+ pub enum Button {
+ Primary,
+ }
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(match self {
+ Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
+ })),
+ border_radius: 12,
+ shadow_offset: Vector::new(1.0, 1.0),
+ text_color: Color::WHITE,
+ ..button::Style::default()
+ }
+ }
+ }
}
diff --git a/examples/progress_bar.rs b/examples/progress_bar.rs
index 525019b4..43b09928 100644
--- a/examples/progress_bar.rs
+++ b/examples/progress_bar.rs
@@ -1,16 +1,7 @@
-use iced::{
- settings::Window, slider, Background, Color, Column, Element, Length,
- ProgressBar, Sandbox, Settings, Slider,
-};
+use iced::{slider, Column, Element, ProgressBar, Sandbox, Settings, Slider};
pub fn main() {
- Progress::run(Settings {
- window: Window {
- size: (700, 300),
- resizable: true,
- decorations: true,
- },
- })
+ Progress::run(Settings::default())
}
#[derive(Default)]
@@ -44,14 +35,7 @@ impl Sandbox for Progress {
fn view(&mut self) -> Element<Message> {
Column::new()
.padding(20)
- .push(
- ProgressBar::new(0.0..=100.0, self.value)
- .background(Background::Color(Color::from_rgb(
- 0.6, 0.6, 0.6,
- )))
- .active_color(Color::from_rgb(0.0, 0.95, 0.0))
- .height(Length::Units(30)),
- )
+ .push(ProgressBar::new(0.0..=100.0, self.value))
.push(Slider::new(
&mut self.progress_bar_slider,
0.0..=100.0,
diff --git a/examples/stopwatch.rs b/examples/stopwatch.rs
index 7a7f0793..c9a61ee9 100644
--- a/examples/stopwatch.rs
+++ b/examples/stopwatch.rs
@@ -1,7 +1,6 @@
use iced::{
- button, Align, Application, Background, Button, Color, Column, Command,
- Container, Element, HorizontalAlignment, Length, Row, Settings,
- Subscription, Text,
+ button, Align, Application, Button, Column, Command, Container, Element,
+ HorizontalAlignment, Length, Row, Settings, Subscription, Text,
};
use std::time::{Duration, Instant};
@@ -96,42 +95,38 @@ impl Application for Stopwatch {
seconds % MINUTE,
self.duration.subsec_millis() / 10,
))
- .width(Length::Shrink)
.size(40);
- let button = |state, label, color: [f32; 3]| {
+ let button = |state, label, style| {
Button::new(
state,
Text::new(label)
- .color(Color::WHITE)
.horizontal_alignment(HorizontalAlignment::Center),
)
.min_width(80)
- .background(Background::Color(color.into()))
- .border_radius(10)
.padding(10)
+ .style(style)
};
let toggle_button = {
let (label, color) = match self.state {
- State::Idle => ("Start", [0.11, 0.42, 0.87]),
- State::Ticking { .. } => ("Stop", [0.9, 0.4, 0.4]),
+ State::Idle => ("Start", style::Button::Primary),
+ State::Ticking { .. } => ("Stop", style::Button::Destructive),
};
button(&mut self.toggle, label, color).on_press(Message::Toggle)
};
- let reset_button = button(&mut self.reset, "Reset", [0.7, 0.7, 0.7])
- .on_press(Message::Reset);
+ let reset_button =
+ button(&mut self.reset, "Reset", style::Button::Secondary)
+ .on_press(Message::Reset);
let controls = Row::new()
- .width(Length::Shrink)
.spacing(20)
.push(toggle_button)
.push(reset_button);
let content = Column::new()
- .width(Length::Shrink)
.align_items(Align::Center)
.spacing(20)
.push(duration)
@@ -180,3 +175,29 @@ mod time {
}
}
}
+
+mod style {
+ use iced::{button, Background, Color, Vector};
+
+ pub enum Button {
+ Primary,
+ Secondary,
+ Destructive,
+ }
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(match self {
+ Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
+ Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5),
+ Button::Destructive => Color::from_rgb(0.8, 0.2, 0.2),
+ })),
+ border_radius: 12,
+ shadow_offset: Vector::new(1.0, 1.0),
+ text_color: Color::WHITE,
+ ..button::Style::default()
+ }
+ }
+ }
+}
diff --git a/examples/styling.rs b/examples/styling.rs
new file mode 100644
index 00000000..50095ec7
--- /dev/null
+++ b/examples/styling.rs
@@ -0,0 +1,514 @@
+use iced::{
+ button, scrollable, slider, text_input, Align, Button, Checkbox, Column,
+ Container, Element, Length, ProgressBar, Radio, Row, Sandbox, Scrollable,
+ Settings, Slider, Space, Text, TextInput,
+};
+
+pub fn main() {
+ Styling::run(Settings::default())
+}
+
+#[derive(Default)]
+struct Styling {
+ theme: style::Theme,
+ scroll: scrollable::State,
+ input: text_input::State,
+ input_value: String,
+ button: button::State,
+ slider: slider::State,
+ slider_value: f32,
+ toggle_value: bool,
+}
+
+#[derive(Debug, Clone)]
+enum Message {
+ ThemeChanged(style::Theme),
+ InputChanged(String),
+ ButtonPressed,
+ SliderChanged(f32),
+ CheckboxToggled(bool),
+}
+
+impl Sandbox for Styling {
+ type Message = Message;
+
+ fn new() -> Self {
+ Styling::default()
+ }
+
+ fn title(&self) -> String {
+ String::from("Styling - Iced")
+ }
+
+ fn update(&mut self, message: Message) {
+ match message {
+ Message::ThemeChanged(theme) => self.theme = theme,
+ Message::InputChanged(value) => self.input_value = value,
+ Message::ButtonPressed => (),
+ Message::SliderChanged(value) => self.slider_value = value,
+ Message::CheckboxToggled(value) => self.toggle_value = value,
+ }
+ }
+
+ fn view(&mut self) -> Element<Message> {
+ let choose_theme = style::Theme::ALL.iter().fold(
+ Column::new().spacing(10).push(Text::new("Choose a theme:")),
+ |column, theme| {
+ column.push(
+ Radio::new(
+ *theme,
+ &format!("{:?}", theme),
+ Some(self.theme),
+ Message::ThemeChanged,
+ )
+ .style(self.theme),
+ )
+ },
+ );
+
+ let text_input = TextInput::new(
+ &mut self.input,
+ "Type something...",
+ &self.input_value,
+ Message::InputChanged,
+ )
+ .padding(10)
+ .size(20)
+ .style(self.theme);
+
+ let button = Button::new(&mut self.button, Text::new("Submit"))
+ .padding(10)
+ .on_press(Message::ButtonPressed)
+ .style(self.theme);
+
+ let slider = Slider::new(
+ &mut self.slider,
+ 0.0..=100.0,
+ self.slider_value,
+ Message::SliderChanged,
+ )
+ .style(self.theme);
+
+ let progress_bar =
+ ProgressBar::new(0.0..=100.0, self.slider_value).style(self.theme);
+
+ let scrollable = Scrollable::new(&mut self.scroll)
+ .height(Length::Units(100))
+ .style(self.theme)
+ .push(Text::new("Scroll me!"))
+ .push(Space::with_height(Length::Units(800)))
+ .push(Text::new("You did it!"));
+
+ let checkbox = Checkbox::new(
+ self.toggle_value,
+ "Toggle me!",
+ Message::CheckboxToggled,
+ )
+ .style(self.theme);
+
+ let content = Column::new()
+ .spacing(20)
+ .padding(20)
+ .max_width(600)
+ .push(choose_theme)
+ .push(Row::new().spacing(10).push(text_input).push(button))
+ .push(slider)
+ .push(progress_bar)
+ .push(
+ Row::new()
+ .spacing(10)
+ .align_items(Align::Center)
+ .push(scrollable)
+ .push(checkbox),
+ );
+
+ Container::new(content)
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .center_x()
+ .center_y()
+ .style(self.theme)
+ .into()
+ }
+}
+
+mod style {
+ use iced::{
+ button, checkbox, container, progress_bar, radio, scrollable, slider,
+ text_input,
+ };
+
+ #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+ pub enum Theme {
+ Light,
+ Dark,
+ }
+
+ impl Theme {
+ pub const ALL: [Theme; 2] = [Theme::Light, Theme::Dark];
+ }
+
+ impl Default for Theme {
+ fn default() -> Theme {
+ Theme::Light
+ }
+ }
+
+ impl From<Theme> for Box<dyn container::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Container.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn radio::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Radio.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn text_input::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::TextInput.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn button::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => light::Button.into(),
+ Theme::Dark => dark::Button.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn scrollable::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Scrollable.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn slider::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Slider.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn progress_bar::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::ProgressBar.into(),
+ }
+ }
+ }
+
+ impl From<Theme> for Box<dyn checkbox::StyleSheet> {
+ fn from(theme: Theme) -> Self {
+ match theme {
+ Theme::Light => Default::default(),
+ Theme::Dark => dark::Checkbox.into(),
+ }
+ }
+ }
+
+ mod light {
+ use iced::{button, Background, Color, Vector};
+
+ pub struct Button;
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(Color::from_rgb(
+ 0.11, 0.42, 0.87,
+ ))),
+ border_radius: 12,
+ shadow_offset: Vector::new(1.0, 1.0),
+ text_color: Color::from_rgb8(0xEE, 0xEE, 0xEE),
+ ..button::Style::default()
+ }
+ }
+
+ fn hovered(&self) -> button::Style {
+ button::Style {
+ text_color: Color::WHITE,
+ shadow_offset: Vector::new(1.0, 2.0),
+ ..self.active()
+ }
+ }
+ }
+ }
+
+ mod dark {
+ use iced::{
+ button, checkbox, container, progress_bar, radio, scrollable,
+ slider, text_input, Background, Color,
+ };
+
+ const SURFACE: Color = Color::from_rgb(
+ 0x40 as f32 / 255.0,
+ 0x44 as f32 / 255.0,
+ 0x4B as f32 / 255.0,
+ );
+
+ const ACCENT: Color = Color::from_rgb(
+ 0x6F as f32 / 255.0,
+ 0xFF as f32 / 255.0,
+ 0xE9 as f32 / 255.0,
+ );
+
+ const ACTIVE: Color = Color::from_rgb(
+ 0x72 as f32 / 255.0,
+ 0x89 as f32 / 255.0,
+ 0xDA as f32 / 255.0,
+ );
+
+ const HOVERED: Color = Color::from_rgb(
+ 0x67 as f32 / 255.0,
+ 0x7B as f32 / 255.0,
+ 0xC4 as f32 / 255.0,
+ );
+
+ pub struct Container;
+
+ impl container::StyleSheet for Container {
+ fn style(&self) -> container::Style {
+ container::Style {
+ background: Some(Background::Color(Color::from_rgb8(
+ 0x36, 0x39, 0x3F,
+ ))),
+ text_color: Some(Color::WHITE),
+ ..container::Style::default()
+ }
+ }
+ }
+
+ pub struct Radio;
+
+ impl radio::StyleSheet for Radio {
+ fn active(&self) -> radio::Style {
+ radio::Style {
+ background: Background::Color(SURFACE),
+ dot_color: ACTIVE,
+ border_width: 1,
+ border_color: ACTIVE,
+ }
+ }
+
+ fn hovered(&self) -> radio::Style {
+ radio::Style {
+ background: Background::Color(Color { a: 0.5, ..SURFACE }),
+ ..self.active()
+ }
+ }
+ }
+
+ pub struct TextInput;
+
+ impl text_input::StyleSheet for TextInput {
+ fn active(&self) -> text_input::Style {
+ text_input::Style {
+ background: Background::Color(SURFACE),
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ }
+ }
+
+ fn focused(&self) -> text_input::Style {
+ text_input::Style {
+ border_width: 1,
+ border_color: ACCENT,
+ ..self.active()
+ }
+ }
+
+ fn hovered(&self) -> text_input::Style {
+ text_input::Style {
+ border_width: 1,
+ border_color: Color { a: 0.3, ..ACCENT },
+ ..self.focused()
+ }
+ }
+
+ fn placeholder_color(&self) -> Color {
+ Color::from_rgb(0.4, 0.4, 0.4)
+ }
+
+ fn value_color(&self) -> Color {
+ Color::WHITE
+ }
+ }
+
+ pub struct Button;
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(ACTIVE)),
+ border_radius: 3,
+ text_color: Color::WHITE,
+ ..button::Style::default()
+ }
+ }
+
+ fn hovered(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(HOVERED)),
+ text_color: Color::WHITE,
+ ..self.active()
+ }
+ }
+
+ fn pressed(&self) -> button::Style {
+ button::Style {
+ border_width: 1,
+ border_color: Color::WHITE,
+ ..self.hovered()
+ }
+ }
+ }
+
+ pub struct Scrollable;
+
+ impl scrollable::StyleSheet for Scrollable {
+ fn active(&self) -> scrollable::Scrollbar {
+ scrollable::Scrollbar {
+ background: Some(Background::Color(SURFACE)),
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ scroller: scrollable::Scroller {
+ color: ACTIVE,
+ border_radius: 2,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ },
+ }
+ }
+
+ fn hovered(&self) -> scrollable::Scrollbar {
+ let active = self.active();
+
+ scrollable::Scrollbar {
+ background: Some(Background::Color(Color {
+ a: 0.5,
+ ..SURFACE
+ })),
+ scroller: scrollable::Scroller {
+ color: HOVERED,
+ ..active.scroller
+ },
+ ..active
+ }
+ }
+
+ fn dragging(&self) -> scrollable::Scrollbar {
+ let hovered = self.hovered();
+
+ scrollable::Scrollbar {
+ scroller: scrollable::Scroller {
+ color: Color::from_rgb(0.85, 0.85, 0.85),
+ ..hovered.scroller
+ },
+ ..hovered
+ }
+ }
+ }
+
+ pub struct Slider;
+
+ impl slider::StyleSheet for Slider {
+ fn active(&self) -> slider::Style {
+ slider::Style {
+ rail_colors: (ACTIVE, Color { a: 0.1, ..ACTIVE }),
+ handle: slider::Handle {
+ shape: slider::HandleShape::Circle { radius: 9 },
+ color: ACTIVE,
+ border_width: 0,
+ border_color: Color::TRANSPARENT,
+ },
+ }
+ }
+
+ fn hovered(&self) -> slider::Style {
+ let active = self.active();
+
+ slider::Style {
+ handle: slider::Handle {
+ color: HOVERED,
+ ..active.handle
+ },
+ ..active
+ }
+ }
+
+ fn dragging(&self) -> slider::Style {
+ let active = self.active();
+
+ slider::Style {
+ handle: slider::Handle {
+ color: Color::from_rgb(0.85, 0.85, 0.85),
+ ..active.handle
+ },
+ ..active
+ }
+ }
+ }
+
+ pub struct ProgressBar;
+
+ impl progress_bar::StyleSheet for ProgressBar {
+ fn style(&self) -> progress_bar::Style {
+ progress_bar::Style {
+ background: Background::Color(SURFACE),
+ bar: Background::Color(ACTIVE),
+ border_radius: 10,
+ }
+ }
+ }
+
+ pub struct Checkbox;
+
+ impl checkbox::StyleSheet for Checkbox {
+ fn active(&self, is_checked: bool) -> checkbox::Style {
+ checkbox::Style {
+ background: Background::Color(if is_checked {
+ ACTIVE
+ } else {
+ SURFACE
+ }),
+ checkmark_color: Color::WHITE,
+ border_radius: 2,
+ border_width: 1,
+ border_color: ACTIVE,
+ }
+ }
+
+ fn hovered(&self, is_checked: bool) -> checkbox::Style {
+ checkbox::Style {
+ background: Background::Color(Color {
+ a: 0.8,
+ ..if is_checked { ACTIVE } else { SURFACE }
+ }),
+ ..self.active(is_checked)
+ }
+ }
+ }
+ }
+}
diff --git a/examples/svg.rs b/examples/svg.rs
index cdf238f0..1895039d 100644
--- a/examples/svg.rs
+++ b/examples/svg.rs
@@ -25,13 +25,14 @@ impl Sandbox for Tiger {
let content = {
use iced::{Column, Svg};
- Column::new()
- .width(Length::Shrink)
- .padding(20)
- .push(Svg::new(format!(
+ Column::new().padding(20).push(
+ Svg::new(format!(
"{}/examples/resources/tiger.svg",
env!("CARGO_MANIFEST_DIR")
- )))
+ ))
+ .width(Length::Fill)
+ .height(Length::Fill),
+ )
};
#[cfg(not(feature = "svg"))]
@@ -39,7 +40,6 @@ impl Sandbox for Tiger {
use iced::{HorizontalAlignment, Text};
Text::new("You need to enable the `svg` feature!")
- .width(Length::Shrink)
.horizontal_alignment(HorizontalAlignment::Center)
.size(30)
};
diff --git a/examples/todos.rs b/examples/todos.rs
index 42e88f65..4166f75a 100644
--- a/examples/todos.rs
+++ b/examples/todos.rs
@@ -1,7 +1,7 @@
use iced::{
button, scrollable, text_input, Align, Application, Button, Checkbox,
- Color, Column, Command, Container, Element, Font, HorizontalAlignment,
- Length, Row, Scrollable, Settings, Text, TextInput,
+ Column, Command, Container, Element, Font, HorizontalAlignment, Length,
+ Row, Scrollable, Settings, Text, TextInput,
};
use serde::{Deserialize, Serialize};
@@ -146,6 +146,7 @@ impl Application for Todos {
..
}) => {
let title = Text::new("todos")
+ .width(Length::Fill)
.size(100)
.color([0.5, 0.5, 0.5])
.horizontal_alignment(HorizontalAlignment::Center);
@@ -284,19 +285,18 @@ impl Task {
self.completed,
&self.description,
TaskMessage::Completed,
- );
+ )
+ .width(Length::Fill);
Row::new()
.spacing(20)
.align_items(Align::Center)
.push(checkbox)
.push(
- Button::new(
- edit_button,
- edit_icon().color([0.5, 0.5, 0.5]),
- )
- .on_press(TaskMessage::Edit)
- .padding(10),
+ Button::new(edit_button, edit_icon())
+ .on_press(TaskMessage::Edit)
+ .padding(10)
+ .style(style::Button::Icon),
)
.into()
}
@@ -322,17 +322,12 @@ impl Task {
delete_button,
Row::new()
.spacing(10)
- .push(delete_icon().color(Color::WHITE))
- .push(
- Text::new("Delete")
- .width(Length::Shrink)
- .color(Color::WHITE),
- ),
+ .push(delete_icon())
+ .push(Text::new("Delete")),
)
.on_press(TaskMessage::Delete)
.padding(10)
- .border_radius(5)
- .background(Color::from_rgb(0.8, 0.2, 0.2)),
+ .style(style::Button::Destructive),
)
.into()
}
@@ -358,18 +353,13 @@ impl Controls {
let tasks_left = tasks.iter().filter(|task| !task.completed).count();
let filter_button = |state, label, filter, current_filter| {
- let label = Text::new(label).size(16).width(Length::Shrink);
- let button = if filter == current_filter {
- Button::new(state, label.color(Color::WHITE))
- .background(Color::from_rgb(0.2, 0.2, 0.7))
- } else {
- Button::new(state, label)
- };
-
- button
- .on_press(Message::FilterChanged(filter))
- .padding(8)
- .border_radius(10)
+ let label = Text::new(label).size(16);
+ let button =
+ Button::new(state, label).style(style::Button::Filter {
+ selected: filter == current_filter,
+ });
+
+ button.on_press(Message::FilterChanged(filter)).padding(8)
};
Row::new()
@@ -381,11 +371,11 @@ impl Controls {
tasks_left,
if tasks_left == 1 { "task" } else { "tasks" }
))
+ .width(Length::Fill)
.size(16),
)
.push(
Row::new()
- .width(Length::Shrink)
.spacing(10)
.push(filter_button(
all_button,
@@ -562,3 +552,63 @@ impl SavedState {
Ok(())
}
}
+
+mod style {
+ use iced::{button, Background, Color, Vector};
+
+ pub enum Button {
+ Filter { selected: bool },
+ Icon,
+ Destructive,
+ }
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ match self {
+ Button::Filter { selected } => {
+ if *selected {
+ button::Style {
+ background: Some(Background::Color(
+ Color::from_rgb(0.2, 0.2, 0.7),
+ )),
+ border_radius: 10,
+ text_color: Color::WHITE,
+ ..button::Style::default()
+ }
+ } else {
+ button::Style::default()
+ }
+ }
+ Button::Icon => button::Style {
+ text_color: Color::from_rgb(0.5, 0.5, 0.5),
+ ..button::Style::default()
+ },
+ Button::Destructive => button::Style {
+ background: Some(Background::Color(Color::from_rgb(
+ 0.8, 0.2, 0.2,
+ ))),
+ border_radius: 5,
+ text_color: Color::WHITE,
+ shadow_offset: Vector::new(1.0, 1.0),
+ ..button::Style::default()
+ },
+ }
+ }
+
+ fn hovered(&self) -> button::Style {
+ let active = self.active();
+
+ button::Style {
+ text_color: match self {
+ Button::Icon => Color::from_rgb(0.2, 0.2, 0.7),
+ Button::Filter { selected } if !selected => {
+ Color::from_rgb(0.2, 0.2, 0.7)
+ }
+ _ => active.text_color,
+ },
+ shadow_offset: active.shadow_offset + Vector::new(0.0, 1.0),
+ ..active
+ }
+ }
+ }
+}
diff --git a/examples/tour.rs b/examples/tour.rs
index 91b75296..b0ee4d96 100644
--- a/examples/tour.rs
+++ b/examples/tour.rs
@@ -62,8 +62,9 @@ impl Sandbox for Tour {
if steps.has_previous() {
controls = controls.push(
- secondary_button(back_button, "Back")
- .on_press(Message::BackPressed),
+ button(back_button, "Back")
+ .on_press(Message::BackPressed)
+ .style(style::Button::Secondary),
);
}
@@ -71,8 +72,9 @@ impl Sandbox for Tour {
if steps.can_continue() {
controls = controls.push(
- primary_button(next_button, "Next")
- .on_press(Message::NextPressed),
+ button(next_button, "Next")
+ .on_press(Message::NextPressed)
+ .style(style::Button::Primary),
);
}
@@ -401,6 +403,7 @@ impl<'a> Step {
))
.push(
Text::new(&value.to_string())
+ .width(Length::Fill)
.horizontal_alignment(HorizontalAlignment::Center),
)
}
@@ -447,6 +450,7 @@ impl<'a> Step {
))
.push(
Text::new(&format!("{} px", spacing))
+ .width(Length::Fill)
.horizontal_alignment(HorizontalAlignment::Center),
);
@@ -561,6 +565,7 @@ impl<'a> Step {
))
.push(
Text::new(&format!("Width: {} px", width.to_string()))
+ .width(Length::Fill)
.horizontal_alignment(HorizontalAlignment::Center),
)
}
@@ -580,6 +585,7 @@ impl<'a> Step {
.push(Column::new().height(Length::Units(4096)))
.push(
Text::new("You are halfway there!")
+ .width(Length::Fill)
.size(30)
.horizontal_alignment(HorizontalAlignment::Center),
)
@@ -587,6 +593,7 @@ impl<'a> Step {
.push(ferris(300))
.push(
Text::new("You made it!")
+ .width(Length::Fill)
.size(50)
.horizontal_alignment(HorizontalAlignment::Center),
)
@@ -629,6 +636,7 @@ impl<'a> Step {
} else {
value
})
+ .width(Length::Fill)
.horizontal_alignment(HorizontalAlignment::Center),
)
}
@@ -692,29 +700,12 @@ fn button<'a, Message>(
) -> Button<'a, Message> {
Button::new(
state,
- Text::new(label)
- .color(Color::WHITE)
- .horizontal_alignment(HorizontalAlignment::Center),
+ Text::new(label).horizontal_alignment(HorizontalAlignment::Center),
)
.padding(12)
- .border_radius(12)
.min_width(100)
}
-fn primary_button<'a, Message>(
- state: &'a mut button::State,
- label: &str,
-) -> Button<'a, Message> {
- button(state, label).background(Color::from_rgb(0.11, 0.42, 0.87))
-}
-
-fn secondary_button<'a, Message>(
- state: &'a mut button::State,
- label: &str,
-) -> Button<'a, Message> {
- button(state, label).background(Color::from_rgb(0.4, 0.4, 0.4))
-}
-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Language {
Rust,
@@ -757,6 +748,38 @@ pub enum Layout {
Column,
}
+mod style {
+ use iced::{button, Background, Color, Vector};
+
+ pub enum Button {
+ Primary,
+ Secondary,
+ }
+
+ impl button::StyleSheet for Button {
+ fn active(&self) -> button::Style {
+ button::Style {
+ background: Some(Background::Color(match self {
+ Button::Primary => Color::from_rgb(0.11, 0.42, 0.87),
+ Button::Secondary => Color::from_rgb(0.5, 0.5, 0.5),
+ })),
+ border_radius: 12,
+ shadow_offset: Vector::new(1.0, 1.0),
+ text_color: Color::from_rgb8(0xEE, 0xEE, 0xEE),
+ ..button::Style::default()
+ }
+ }
+
+ fn hovered(&self) -> button::Style {
+ button::Style {
+ text_color: Color::WHITE,
+ shadow_offset: Vector::new(1.0, 2.0),
+ ..self.active()
+ }
+ }
+ }
+}
+
// This should be gracefully handled by Iced in the future. Probably using our
// own proc macro, or maybe the whole process is streamlined by `wasm-pack` at
// some point.