feat: high contrast theme updates

This commit is contained in:
Ashley Wulber 2025-03-07 16:53:22 -05:00 committed by Michael Murphy
parent 50d2104485
commit 508753ae69
6 changed files with 119 additions and 38 deletions

View file

@ -25,9 +25,10 @@ impl Container {
base: Srgba,
on: Srgba,
mut small_widget: Srgba,
is_high_contrast: bool,
) -> Self {
let mut divider_c = on;
divider_c.alpha = 0.2;
divider_c.alpha = if is_high_contrast { 0.5 } else { 0.2 };
small_widget.alpha = 0.25;

View file

@ -894,6 +894,7 @@ impl ThemeBuilder {
text_steps_array.as_deref(),
),
get_small_widget_color(base_index, 5, &neutral_steps, &p_ref.neutral_6),
is_high_contrast,
);
container
@ -968,6 +969,7 @@ impl ThemeBuilder {
text_steps_array.as_deref(),
),
get_small_widget_color(bg_index, 5, &neutral_steps, &p_ref.neutral_6),
is_high_contrast,
),
primary,
secondary: {
@ -1014,6 +1016,7 @@ impl ThemeBuilder {
text_steps_array.as_deref(),
),
get_small_widget_color(base_index, 5, &neutral_steps, &p_ref.neutral_6),
is_high_contrast,
)
},
accent: Component::colored_component(

View file

@ -50,7 +50,7 @@ pub fn appearance(
let cosmic = theme.cosmic();
let mut corner_radii = &cosmic.corner_radii.radius_xl;
let mut appearance = Style::new();
let hc = theme.theme_type.is_high_contrast();
match style {
Button::Standard
| Button::Text
@ -71,6 +71,9 @@ pub fn appearance(
if !matches!(style, Button::Standard) {
appearance.text_color = text;
appearance.icon_color = icon;
} else if hc {
appearance.border_color = style_component.border.into();
appearance.border_width = 1.;
}
}
@ -105,6 +108,9 @@ pub fn appearance(
if focused || selected {
appearance.border_width = 2.0;
appearance.border_color = cosmic.accent.base.into();
} else if hc {
appearance.border_color = theme.current_container().component.divider.into();
appearance.border_width = 1.;
}
return appearance;

View file

@ -528,7 +528,15 @@ impl iced_container::Catalog for Theme {
}
}
Container::ContextDrawer => Container::primary(cosmic),
Container::ContextDrawer => {
let mut a = Container::primary(cosmic);
if cosmic.is_high_contrast {
a.border.width = 1.;
a.border.color = cosmic.primary.divider.into();
}
a
}
Container::Background => Container::background(cosmic),
@ -644,19 +652,39 @@ impl slider::Catalog for Theme {
fn style(&self, class: &Self::Class<'_>, status: slider::Status) -> slider::Style {
let cosmic: &cosmic_theme::Theme = self.cosmic();
let hc = self.theme_type.is_high_contrast();
let is_dark = self.theme_type.is_dark();
let mut appearance = match class {
Slider::Standard =>
//TODO: no way to set rail thickness
{
let (active_track, inactive_track) = if hc {
(
cosmic.accent_text_color(),
if is_dark {
cosmic.palette.neutral_6
} else {
cosmic.palette.neutral_4
},
)
} else {
(cosmic.accent.base, cosmic.palette.neutral_6)
};
slider::Style {
rail: Rail {
backgrounds: (
Background::Color(cosmic.accent.base.into()),
Background::Color(cosmic.palette.neutral_6.into()),
Background::Color(active_track.into()),
Background::Color(inactive_track.into()),
),
border: Border {
radius: cosmic.corner_radii.radius_xs.into(),
..Border::default()
color: if hc && !is_dark {
self.current_container().component.border.into()
} else {
Color::TRANSPARENT
},
width: if hc && !is_dark { 1. } else { 0. },
},
width: 4.0,
},
@ -745,9 +773,6 @@ impl menu::Catalog for Theme {
}
}
/*
* TODO: Pick List
*/
impl pick_list::Catalog for Theme {
type Class<'a> = ();
@ -761,18 +786,24 @@ impl pick_list::Catalog for Theme {
status: pick_list::Status,
) -> pick_list::Style {
let cosmic = &self.cosmic();
let hc = cosmic.is_high_contrast;
let appearance = pick_list::Style {
text_color: cosmic.on_bg_color().into(),
background: Color::TRANSPARENT.into(),
placeholder_color: cosmic.on_bg_color().into(),
border: Border {
radius: cosmic.corner_radii.radius_m.into(),
..Default::default()
width: if hc { 1. } else { 0. },
color: if hc {
self.current_container().component.border.into()
} else {
Color::TRANSPARENT
},
},
// icon_size: 0.7, // TODO: how to replace
handle_color: cosmic.on_bg_color().into(),
};
match status {
pick_list::Status::Active => appearance,
pick_list::Status::Hovered => pick_list::Style {
@ -957,33 +988,46 @@ impl progress_bar::Catalog for Theme {
fn style(&self, class: &Self::Class<'_>) -> progress_bar::Style {
let theme = self.cosmic();
let (active_track, inactive_track) = if theme.is_high_contrast {
(
theme.accent_text_color(),
if theme.is_dark {
theme.palette.neutral_6
} else {
theme.palette.neutral_4
},
)
} else {
(theme.accent.base, theme.background.divider)
};
let border = Border {
radius: theme.corner_radii.radius_xs.into(),
color: if theme.is_high_contrast && !theme.is_dark {
self.current_container().component.border.into()
} else {
Color::TRANSPARENT
},
width: if theme.is_high_contrast && !theme.is_dark {
1.
} else {
0.
},
};
match class {
ProgressBar::Primary => progress_bar::Style {
background: Color::from(theme.background.divider).into(),
bar: Color::from(theme.accent.base).into(),
border: Border {
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
background: Color::from(inactive_track).into(),
bar: Color::from(active_track).into(),
border,
},
ProgressBar::Success => progress_bar::Style {
background: Color::from(theme.background.divider).into(),
background: Color::from(inactive_track).into(),
bar: Color::from(theme.success.base).into(),
border: Border {
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
border,
},
ProgressBar::Danger => progress_bar::Style {
background: Color::from(theme.background.divider).into(),
background: Color::from(inactive_track).into(),
bar: Color::from(theme.destructive.base).into(),
border: Border {
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
border,
},
ProgressBar::Custom(f) => f(self),
}

View file

@ -30,6 +30,16 @@ impl StyleSheet for Theme {
SegmentedButton::TabBar => {
let cosmic = self.cosmic();
let active = horizontal::tab_bar_active(cosmic);
let hc = cosmic.is_high_contrast;
let (border_end, border_start, border_top) = if hc {
(
Some((1., container.component.border.into())),
Some((1., container.component.border.into())),
Some((1., container.component.border.into())),
)
} else {
(None, None, None)
};
Appearance {
border_radius: cosmic.corner_radii.radius_0.into(),
inactive: ItemStatusAppearance {
@ -37,17 +47,23 @@ impl StyleSheet for Theme {
first: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default()
border_end,
border_start,
border_top,
},
middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default()
border_end,
border_start,
border_top,
},
last: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default()
border_end,
border_start,
border_top,
},
text_color: container.component.on.into(),
},

View file

@ -238,15 +238,26 @@ fn container_style(theme: &crate::Theme) -> iced_widget::container::Style {
neutral_10.alpha = 0.1;
let accent = &cosmic_theme.accent;
let corners = &cosmic_theme.corner_radii;
let border = if theme.theme_type.is_high_contrast() {
let current_container = theme.current_container();
Border {
radius: corners.radius_s.into(),
width: 1.,
color: current_container.component.border.into(),
}
} else {
Border {
radius: corners.radius_s.into(),
width: 0.0,
color: accent.base.into(),
}
};
iced_widget::container::Style {
icon_color: Some(accent.base.into()),
text_color: Some(cosmic_theme.palette.neutral_10.into()),
background: None,
border: Border {
radius: corners.radius_s.into(),
width: 0.0,
color: accent.base.into(),
},
border,
shadow: Shadow::default(),
}
}