From 911cd4ffc291d2d9b92f90ede1d03d41edc97920 Mon Sep 17 00:00:00 2001 From: pml68 Date: Tue, 15 Apr 2025 23:45:14 +0200 Subject: feat(material_theme): implement `text_input::Catalog` --- Cargo.lock | 6 +-- crates/material_theme/src/lib.rs | 1 + crates/material_theme/src/text_input.rs | 81 +++++++++++++++++++++++++++++++++ theme_test/src/main.rs | 26 +++++++---- 4 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 crates/material_theme/src/text_input.rs diff --git a/Cargo.lock b/Cargo.lock index c8379a9..4d8371f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2054,7 +2054,7 @@ dependencies = [ [[package]] name = "iced_dialog" version = "0.14.0-dev" -source = "git+https://github.com/pml68/iced_dialog?branch=iced%2Fpersonal#a41468011f8e4f566e9301565f3276fb10cc9551" +source = "git+https://github.com/pml68/iced_dialog?branch=iced%2Fpersonal#6e901c21dbb259d337ed1ad2054da3862172b8b3" dependencies = [ "iced_core", "iced_widget", @@ -2563,9 +2563,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libfuzzer-sys" diff --git a/crates/material_theme/src/lib.rs b/crates/material_theme/src/lib.rs index 521af2c..adffe09 100644 --- a/crates/material_theme/src/lib.rs +++ b/crates/material_theme/src/lib.rs @@ -12,6 +12,7 @@ pub mod menu; pub mod pick_list; pub mod scrollable; pub mod text; +pub mod text_input; pub mod utils; const DARK_THEME_CONTENT: &str = include_str!("../assets/themes/dark.toml"); diff --git a/crates/material_theme/src/text_input.rs b/crates/material_theme/src/text_input.rs new file mode 100644 index 0000000..5fa65ef --- /dev/null +++ b/crates/material_theme/src/text_input.rs @@ -0,0 +1,81 @@ +use iced_widget::core::{Background, Border, Color}; +use iced_widget::text_input::{Catalog, Status, Style, StyleFn}; + +use super::Theme; +use crate::utils::{DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY}; + +impl Catalog for Theme { + type Class<'a> = StyleFn<'a, Self>; + + fn default<'a>() -> Self::Class<'a> { + Box::new(default) + } + + fn style(&self, class: &Self::Class<'_>, status: Status) -> Style { + class(self, status) + } +} + +pub fn default(theme: &Theme, status: Status) -> Style { + let surface = theme.colorscheme.surface; + let primary = theme.colorscheme.primary; + + let active = Style { + background: Background::Color(surface.surface_container.highest), + border: Border { + color: theme.colorscheme.outline.color, + width: 1.0, + radius: 4.into(), + }, + icon: surface.on_surface_variant, + placeholder: surface.on_surface_variant, + value: surface.on_surface, + selection: surface.on_surface, + }; + + match status { + Status::Active => active, + Status::Hovered => Style { + border: Border { + color: surface.on_surface, + ..active.border + }, + ..active + }, + Status::Disabled => Style { + background: Color::TRANSPARENT.into(), + border: Border { + color: Color { + a: DISABLED_CONTAINER_OPACITY, + ..surface.on_surface + }, + ..active.border + }, + icon: Color { + a: DISABLED_TEXT_OPACITY, + ..surface.on_surface + }, + placeholder: Color { + a: DISABLED_TEXT_OPACITY, + ..surface.on_surface + }, + value: Color { + a: DISABLED_TEXT_OPACITY, + ..surface.on_surface + }, + selection: Color { + a: DISABLED_TEXT_OPACITY, + ..surface.on_surface + }, + }, + Status::Focused { .. } => Style { + border: Border { + color: primary.color, + width: 2.0, + ..active.border + }, + placeholder: primary.color, + ..active + }, + } +} diff --git a/theme_test/src/main.rs b/theme_test/src/main.rs index bcf16de..799d68d 100644 --- a/theme_test/src/main.rs +++ b/theme_test/src/main.rs @@ -1,6 +1,6 @@ use iced::Element; use iced::Length::Fill; -use iced::widget::{button, column, container, pick_list, row}; +use iced::widget::{button, column, container, pick_list, row, text_input}; use iced_anim::{Animated, Animation, Event}; use iced_dialog::dialog; use material_theme::button::{elevated, filled_tonal, outlined, text}; @@ -25,13 +25,15 @@ enum Message { Noop, OpenDialog, CloseDialog, + Input(String), SwitchTheme(Event), } #[derive(Debug, Default)] pub struct State { - show_dialog: bool, theme: Animated, + show_dialog: bool, + content: String, } impl State { @@ -44,6 +46,7 @@ impl State { Message::CloseDialog => { self.show_dialog = false; } + Message::Input(content) => self.content = content, Message::SwitchTheme(event) => { self.theme.update(event); } @@ -109,13 +112,18 @@ impl State { .style(surface_container_highest), ] .spacing(10), - pick_list( - [LIGHT.clone(), DARK.clone()], - Some(self.theme.target()), - |theme| Message::SwitchTheme(theme.into()) - ) - .placeholder("Select a theme..."), - button("Open Dialog").on_press(Message::OpenDialog) + column![ + pick_list( + [LIGHT.clone(), DARK.clone()], + Some(self.theme.target()), + |theme| Message::SwitchTheme(theme.into()) + ) + .placeholder("Select a theme..."), + button("Open Dialog").on_press(Message::OpenDialog), + text_input("Type something here...", &self.content) + .on_input(Message::Input) + ] + .spacing(10) ] .spacing(20), ) -- cgit v1.2.3