summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpml68 <contact@pml68.dev>2025-04-19 11:12:59 +0200
committerpml68 <contact@pml68.dev>2025-04-19 11:12:59 +0200
commit4a17d1fa468caf89e33088b3be69a67a52b29a99 (patch)
tree6ff9e952d136b9cbeaa2a79b27583f58db04d863
parentfeat(material_theme): implement `rule::Catalog` (diff)
downloadiced-builder-4a17d1fa468caf89e33088b3be69a67a52b29a99.tar.gz
feat(material_theme): implement `slider::Catalog`
Diffstat (limited to '')
-rw-r--r--crates/material_theme/src/lib.rs1
-rw-r--r--crates/material_theme/src/toggler.rs80
-rw-r--r--theme_test/src/main.rs17
3 files changed, 92 insertions, 6 deletions
diff --git a/crates/material_theme/src/lib.rs b/crates/material_theme/src/lib.rs
index 2452d88..0df5b1c 100644
--- a/crates/material_theme/src/lib.rs
+++ b/crates/material_theme/src/lib.rs
@@ -24,6 +24,7 @@ pub mod slider;
pub mod svg;
pub mod text;
pub mod text_input;
+pub mod toggler;
pub mod utils;
pub static DARK: LazyLock<Theme> =
diff --git a/crates/material_theme/src/toggler.rs b/crates/material_theme/src/toggler.rs
new file mode 100644
index 0000000..1cc5082
--- /dev/null
+++ b/crates/material_theme/src/toggler.rs
@@ -0,0 +1,80 @@
+use iced_widget::core::Color;
+use iced_widget::toggler::{Catalog, Status, Style, StyleFn};
+
+use super::Theme;
+use crate::utils::{
+ DISABLED_CONTAINER_OPACITY, DISABLED_TEXT_OPACITY, HOVERED_LAYER_OPACITY,
+ mix,
+};
+
+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 styled(
+ background: Color,
+ foreground: Color,
+ border: Option<Color>,
+) -> Style {
+ Style {
+ background,
+ background_border_width: if border.is_some() { 2.0 } else { 0.0 },
+ background_border_color: border.unwrap_or(Color::TRANSPARENT),
+ foreground,
+ foreground_border_width: 0.0,
+ foreground_border_color: Color::TRANSPARENT,
+ }
+}
+
+pub fn default(theme: &Theme, status: Status) -> Style {
+ let surface = theme.colorscheme.surface;
+ let primary = theme.colorscheme.primary;
+
+ match status {
+ Status::Active { is_toggled } => {
+ if is_toggled {
+ styled(primary.color, primary.on_primary, None)
+ } else {
+ styled(
+ surface.surface_container.highest,
+ theme.colorscheme.outline.color,
+ Some(theme.colorscheme.outline.color),
+ )
+ }
+ }
+ Status::Hovered { is_toggled } => {
+ if is_toggled {
+ styled(primary.color, primary.primary_container, None)
+ } else {
+ styled(
+ mix(
+ surface.surface_container.highest,
+ surface.on_surface,
+ HOVERED_LAYER_OPACITY,
+ ),
+ surface.on_surface_variant,
+ Some(theme.colorscheme.outline.color),
+ )
+ }
+ }
+ Status::Disabled => styled(
+ Color {
+ a: DISABLED_CONTAINER_OPACITY,
+ ..surface.surface_container.highest
+ },
+ Color {
+ a: DISABLED_TEXT_OPACITY,
+ ..surface.on_surface
+ },
+ Some(surface.on_surface),
+ ),
+ }
+}
diff --git a/theme_test/src/main.rs b/theme_test/src/main.rs
index 7192785..d564ee5 100644
--- a/theme_test/src/main.rs
+++ b/theme_test/src/main.rs
@@ -1,7 +1,7 @@
use iced::Length::Fill;
use iced::widget::{
button, center, checkbox, column, container, horizontal_rule, pick_list,
- radio, row, slider, text_input,
+ radio, row, slider, text_input, toggler,
};
use iced::{Element, Length};
use iced_anim::{Animated, Animation, Event};
@@ -29,7 +29,7 @@ enum Message {
OpenDialog,
CloseDialog,
Input(String),
- CheckBox(bool),
+ Bool(bool),
Radio(Choice),
Slider(f32),
SwitchTheme(Event<Theme>),
@@ -63,7 +63,7 @@ impl State {
self.show_dialog = false;
}
Message::Input(content) => self.content = content,
- Message::CheckBox(is_checked) => self.is_checked = is_checked,
+ Message::Bool(is_checked) => self.is_checked = is_checked,
Message::Radio(choice) => self.selection = Some(choice),
Message::Slider(value) => self.value = value,
Message::SwitchTheme(event) => {
@@ -149,9 +149,9 @@ impl State {
horizontal_rule(1),
// Checkbox
checkbox("Normal", self.is_checked)
- .on_toggle(Message::CheckBox),
+ .on_toggle(Message::Bool),
checkbox("Error", self.is_checked)
- .on_toggle(Message::CheckBox)
+ .on_toggle(Message::Bool)
.style(material_theme::checkbox::error),
checkbox("Disabled", self.is_checked),
horizontal_rule(1),
@@ -164,7 +164,12 @@ impl State {
center(iced::widget::text!("{:.1}", self.value))
.width(Length::Fill)
.height(Length::Shrink),
- slider(0.0..=100.0, self.value, Message::Slider).step(0.1)
+ slider(0.0..=100.0, self.value, Message::Slider).step(0.1),
+ horizontal_rule(1),
+ // Toggler
+ toggler(self.is_checked)
+ .on_toggle(Message::Bool)
+ .size(24.0)
]
.spacing(10)
]