Merge branch 'master' into paint-example
This commit is contained in:
commit
de71776e02
93 changed files with 2376 additions and 657 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
514
examples/styling.rs
Normal file
514
examples/styling.rs
Normal file
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
};
|
||||
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)
|
||||
.border_radius(10)
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue