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, base: Srgba,
on: Srgba, on: Srgba,
mut small_widget: Srgba, mut small_widget: Srgba,
is_high_contrast: bool,
) -> Self { ) -> Self {
let mut divider_c = on; 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; small_widget.alpha = 0.25;

View file

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

View file

@ -50,7 +50,7 @@ pub fn appearance(
let cosmic = theme.cosmic(); let cosmic = theme.cosmic();
let mut corner_radii = &cosmic.corner_radii.radius_xl; let mut corner_radii = &cosmic.corner_radii.radius_xl;
let mut appearance = Style::new(); let mut appearance = Style::new();
let hc = theme.theme_type.is_high_contrast();
match style { match style {
Button::Standard Button::Standard
| Button::Text | Button::Text
@ -71,6 +71,9 @@ pub fn appearance(
if !matches!(style, Button::Standard) { if !matches!(style, Button::Standard) {
appearance.text_color = text; appearance.text_color = text;
appearance.icon_color = icon; 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 { if focused || selected {
appearance.border_width = 2.0; appearance.border_width = 2.0;
appearance.border_color = cosmic.accent.base.into(); 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; 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), 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 { fn style(&self, class: &Self::Class<'_>, status: slider::Status) -> slider::Style {
let cosmic: &cosmic_theme::Theme = self.cosmic(); 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 { let mut appearance = match class {
Slider::Standard => Slider::Standard =>
//TODO: no way to set rail thickness //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 { slider::Style {
rail: Rail { rail: Rail {
backgrounds: ( backgrounds: (
Background::Color(cosmic.accent.base.into()), Background::Color(active_track.into()),
Background::Color(cosmic.palette.neutral_6.into()), Background::Color(inactive_track.into()),
), ),
border: Border { border: Border {
radius: cosmic.corner_radii.radius_xs.into(), 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, width: 4.0,
}, },
@ -745,9 +773,6 @@ impl menu::Catalog for Theme {
} }
} }
/*
* TODO: Pick List
*/
impl pick_list::Catalog for Theme { impl pick_list::Catalog for Theme {
type Class<'a> = (); type Class<'a> = ();
@ -761,18 +786,24 @@ impl pick_list::Catalog for Theme {
status: pick_list::Status, status: pick_list::Status,
) -> pick_list::Style { ) -> pick_list::Style {
let cosmic = &self.cosmic(); let cosmic = &self.cosmic();
let hc = cosmic.is_high_contrast;
let appearance = pick_list::Style { let appearance = pick_list::Style {
text_color: cosmic.on_bg_color().into(), text_color: cosmic.on_bg_color().into(),
background: Color::TRANSPARENT.into(), background: Color::TRANSPARENT.into(),
placeholder_color: cosmic.on_bg_color().into(), placeholder_color: cosmic.on_bg_color().into(),
border: Border { border: Border {
radius: cosmic.corner_radii.radius_m.into(), 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 // icon_size: 0.7, // TODO: how to replace
handle_color: cosmic.on_bg_color().into(), handle_color: cosmic.on_bg_color().into(),
}; };
match status { match status {
pick_list::Status::Active => appearance, pick_list::Status::Active => appearance,
pick_list::Status::Hovered => pick_list::Style { 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 { fn style(&self, class: &Self::Class<'_>) -> progress_bar::Style {
let theme = self.cosmic(); 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 { match class {
ProgressBar::Primary => progress_bar::Style { ProgressBar::Primary => progress_bar::Style {
background: Color::from(theme.background.divider).into(), background: Color::from(inactive_track).into(),
bar: Color::from(theme.accent.base).into(), bar: Color::from(active_track).into(),
border: Border { border,
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
}, },
ProgressBar::Success => progress_bar::Style { 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(), bar: Color::from(theme.success.base).into(),
border: Border { border,
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
}, },
ProgressBar::Danger => progress_bar::Style { 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(), bar: Color::from(theme.destructive.base).into(),
border: Border { border,
color: Color::default(),
width: 0.0,
radius: theme.corner_radii.radius_xs.into(),
},
}, },
ProgressBar::Custom(f) => f(self), ProgressBar::Custom(f) => f(self),
} }

View file

@ -30,6 +30,16 @@ impl StyleSheet for Theme {
SegmentedButton::TabBar => { SegmentedButton::TabBar => {
let cosmic = self.cosmic(); let cosmic = self.cosmic();
let active = horizontal::tab_bar_active(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 { Appearance {
border_radius: cosmic.corner_radii.radius_0.into(), border_radius: cosmic.corner_radii.radius_0.into(),
inactive: ItemStatusAppearance { inactive: ItemStatusAppearance {
@ -37,17 +47,23 @@ impl StyleSheet for Theme {
first: ItemAppearance { first: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(), border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())), border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default() border_end,
border_start,
border_top,
}, },
middle: ItemAppearance { middle: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(), border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())), border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default() border_end,
border_start,
border_top,
}, },
last: ItemAppearance { last: ItemAppearance {
border_radius: cosmic.corner_radii.radius_0.into(), border_radius: cosmic.corner_radii.radius_0.into(),
border_bottom: Some((1.0, cosmic.accent.base.into())), border_bottom: Some((1.0, cosmic.accent.base.into())),
..Default::default() border_end,
border_start,
border_top,
}, },
text_color: container.component.on.into(), 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; neutral_10.alpha = 0.1;
let accent = &cosmic_theme.accent; let accent = &cosmic_theme.accent;
let corners = &cosmic_theme.corner_radii; 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 { iced_widget::container::Style {
icon_color: Some(accent.base.into()), icon_color: Some(accent.base.into()),
text_color: Some(cosmic_theme.palette.neutral_10.into()), text_color: Some(cosmic_theme.palette.neutral_10.into()),
background: None, background: None,
border: Border { border,
radius: corners.radius_s.into(),
width: 0.0,
color: accent.base.into(),
},
shadow: Shadow::default(), shadow: Shadow::default(),
} }
} }