use iced::keyboard; use iced::widget::{ Button, center, checkbox, column, container, pick_list, progress_bar, row, rule, scrollable, slider, space, text, text_input, toggler, }; use iced::{Center, Fill, Subscription, border}; use iced_material::{ Theme, button, utils::{disabled_container, disabled_text}, }; type Element<'a, Message> = iced::Element<'a, Message, Theme>; pub fn main() -> iced::Result { iced::application(Styling::new, Styling::update, Styling::view) .subscription(Styling::subscription) .theme(Styling::theme) .run() } struct Styling { theme: Theme, system_theme: bool, input_value: String, slider_value: f32, checkbox_value: bool, toggler_value: bool, } #[derive(Debug, Clone)] enum Message { ThemeChanged(Theme), SystemTheme(bool), InputChanged(String), ButtonPressed, SliderChanged(f32), CheckboxToggled(bool), TogglerToggled(bool), PreviousTheme, NextTheme, } impl Styling { fn new() -> Self { Self { theme: Theme::Dark, system_theme: false, input_value: String::new(), slider_value: 0.0, checkbox_value: false, toggler_value: false, } } fn update(&mut self, message: Message) { match message { Message::ThemeChanged(theme) => { self.theme = theme; } Message::SystemTheme(system_theme) => { self.system_theme = system_theme } Message::InputChanged(value) => self.input_value = value, Message::ButtonPressed => {} 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 !self.system_theme => { 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() }; } } Message::PreviousTheme | Message::NextTheme => {} } } fn view(&self) -> Element<'_, Message> { let choose_theme = column![ text("Theme:"), row![ if self.system_theme { Element::from( container(text(self.theme.to_string())) .padding([5, 10]) .width(Fill) .style(|theme: &Theme| { let color = theme.colors().surface.text; container::Style { background: Some( disabled_container(color).into(), ), text_color: Some(disabled_text(color)), border: border::rounded(4), ..Default::default() } }), ) } else { pick_list( Theme::ALL, Some(&self.theme), Message::ThemeChanged, ) .width(Fill) .into() }, checkbox("Use system theme", self.system_theme) .on_toggle(Message::SystemTheme) ] .spacing(10) .align_y(Center), ] .spacing(10); let text_input = text_input("Type something...", &self.input_value) .on_input(Message::InputChanged) .padding(10) .size(20); let styled_button = |label| { Button::new(text(label).width(Fill).center()) .padding(10) .on_press(Message::ButtonPressed) }; let filled = styled_button("Filled"); let elevated = styled_button("Elevated").style(button::elevated); let filled_tonal = styled_button("Filled Tonal").style(button::filled_tonal); let outlined = styled_button("Outlined").style(button::outlined); let text_button = styled_button("Text").style(button::text); let slider = || slider(0.0..=100.0, self.slider_value, Message::SliderChanged); let progress_bar = || progress_bar(0.0..=100.0, self.slider_value); let scrollable = scrollable( column!["Scroll me!", space::vertical().height(800), "You did it!"] .padding(10), ) .width(Fill) .height(100); let checkbox = checkbox("Check me!", self.checkbox_value) .on_toggle(Message::CheckboxToggled); let toggler = toggler(self.toggler_value) .label("Toggle me!") .on_toggle(Message::TogglerToggled) .spacing(10); let card = { container( column![ text("Card Example").size(24), slider(), progress_bar(), ] .spacing(20), ) .width(Fill) .padding(20) .style(|theme| { let style = iced_material::container::surface_container_lowest(theme); let border_color = theme.colors().surface.container.high; container::Style { border: style.border.color(border_color).width(1), ..style } }) }; let content = column![ choose_theme, rule::horizontal(1), text_input, row![filled, elevated, filled_tonal, outlined, text_button] .spacing(10) .align_y(Center), slider(), progress_bar(), row![ scrollable, row![rule::vertical(1), column![checkbox, toggler].spacing(20)] .spacing(20) ] .spacing(10) .height(100) .align_y(Center), card ] .spacing(20) .padding(20) .max_width(650); center(content).into() } fn subscription(&self) -> Subscription { 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) -> Option { (!self.system_theme).then_some(self.theme.clone()) } }