Match shell squircle outlines with compositor masks
Use shared corner geometry for shell controls, window clipping, materials and blur masks. Preserve circular pills and controls where appropriate, track contour changes in damage, and use tagged ferese-shape and libcosmic dependencies.
This commit is contained in:
1 parent
03a265b97f
commit
d75c93db85
31 files changed
+453
-80
No files matched your search
@@ -10,7 +10,7 @@ jiff.workspace = true
|
||||
ferese-theme-model = { path = "../ferese-theme-model" }
|
||||
libcosmic = { workspace = true, features = ["a11y"] }
|
||||
|
||||
iced_accessibility = { git = "https://github.com/pop-os/libcosmic", rev = "03d7dcb832bc6d15bc1bb07327a1aa426b2d5bc0" }
|
||||
iced_accessibility = { git = "https://github.com/ferese-wm/libcosmic", tag = "ferese-v0.1.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
ferese-config = { path = "../ferese-config" }
|
||||
@@ -1,3 +1,4 @@
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
use cosmic::iced::{Background, Color};
|
||||
use cosmic::theme;
|
||||
use cosmic::widget::button;
|
||||
@@ -27,6 +28,8 @@ pub(crate) fn accent_button_style(theme: &cosmic::Theme, state: State, focused:
|
||||
let background = composite(fill, native.primary(false).base.into());
|
||||
let foreground = foreground(background, component.on.into());
|
||||
button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Some(Background::Color(background)),
|
||||
text_color: Some(foreground),
|
||||
icon_color: Some(foreground),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//! Date/time labels and a calendar grid; callers own navigation and popup behavior.
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
use cosmic::iced::{Alignment, Background, Border, Length};
|
||||
use cosmic::widget::{column, container, row};
|
||||
use cosmic::{Element, theme};
|
||||
@@ -124,6 +125,7 @@ pub fn grid<'a, M: Clone + 'a>(
|
||||
.class(theme::Container::custom(move |_| container::Style {
|
||||
background: is_today.then_some(Background::Color(palette.accent.scale_alpha(0.2 * opacity))),
|
||||
border: Border {
|
||||
shape: BorderShape::Continuous,
|
||||
radius: palette.radius.min(12.).into(),
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
use cosmic::iced::{Background, Border, Color, Vector};
|
||||
use cosmic::widget::{button, container};
|
||||
use cosmic::{theme, widget};
|
||||
@@ -66,6 +67,8 @@ pub fn text_button<'a, M: Clone + 'a>(
|
||||
|
||||
pub fn switch<'a, M: Clone + 'a>(enabled: bool, palette: Palette) -> button::Button<'a, M> {
|
||||
let paint = move |focused| button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: None,
|
||||
text_color: Some(palette.text),
|
||||
icon_color: Some(palette.text),
|
||||
@@ -100,6 +103,8 @@ pub fn navigation_style(p: Palette, selected: bool) -> theme::Button {
|
||||
|
||||
pub fn settings_input(p: Palette) -> theme::TextInput {
|
||||
let appearance = move |focused: bool, hovered: bool| cosmic::widget::text_input::Appearance {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: mix(p.card, p.text, if hovered { 0.06 } else { 0.035 }).into(),
|
||||
border_radius: p.radius.min(7.).into(),
|
||||
border_width: 1.,
|
||||
@@ -133,9 +138,11 @@ pub fn select<'a, M: 'a>(
|
||||
widget::container(content).class(theme::Container::custom(move |_| container::Style {
|
||||
background: Some(mix(p.card, p.text, 0.035).into()),
|
||||
border: Border {
|
||||
shape: BorderShape::Continuous,
|
||||
width: 1.,
|
||||
color: mix(p.card, p.text, 0.18),
|
||||
radius: p.radius.min(7.).into(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
}))
|
||||
@@ -170,6 +177,8 @@ fn styled_button(p: Palette, selected: bool, navigation: bool, opacity: f32, foc
|
||||
};
|
||||
|
||||
button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Some(Background::Color(background)),
|
||||
text_color: Some(on),
|
||||
icon_color: Some(on),
|
||||
@@ -208,6 +217,8 @@ pub fn authentication_button(palette: Palette) -> theme::Button {
|
||||
(crate::composite(palette.card, palette.background), palette.muted)
|
||||
};
|
||||
button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Some(Background::Color(fill)),
|
||||
text_color: Some(foreground),
|
||||
icon_color: Some(foreground),
|
||||
@@ -231,6 +242,8 @@ pub fn authentication_input(palette: Palette) -> theme::TextInput {
|
||||
let accent = palette.accent;
|
||||
let radius = palette.radius.min(10.);
|
||||
let appearance = move |focused: bool| widget::text_input::Appearance {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Color::from_rgba(text.r, text.g, text.b, 0.045).into(),
|
||||
border_radius: radius.into(),
|
||||
border_width: 1.,
|
||||
@@ -258,6 +271,8 @@ pub fn authentication_input(palette: Palette) -> theme::TextInput {
|
||||
|
||||
pub fn lock_input(radius: f32, accent: cosmic::iced::Color, surface: cosmic::iced::Color) -> theme::TextInput {
|
||||
let appearance = move |focused: bool| widget::text_input::Appearance {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: cosmic::iced::Color::from_rgba(
|
||||
(surface.r + 1.) * 0.5,
|
||||
(surface.g + 1.) * 0.5,
|
||||
@@ -299,6 +314,8 @@ pub fn shell_button(
|
||||
pressed: bool,
|
||||
) -> button::Style {
|
||||
button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
text_color: Some(foreground),
|
||||
icon_color: Some(foreground),
|
||||
border_radius: radius.into(),
|
||||
@@ -318,6 +335,7 @@ pub fn surface_appearance(background: Color, radius: f32) -> container::Style {
|
||||
container::Style {
|
||||
background: Some(Background::Color(background)),
|
||||
border: Border {
|
||||
shape: BorderShape::Continuous,
|
||||
radius: radius.into(),
|
||||
..Default::default()
|
||||
},
|
||||
@@ -327,6 +345,8 @@ pub fn surface_appearance(background: Color, radius: f32) -> container::Style {
|
||||
|
||||
pub fn notification_button(foreground: Color, hover: Color, radius: f32, filled: bool) -> theme::Button {
|
||||
let style = move |active: bool| button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
text_color: Some(foreground),
|
||||
icon_color: Some(foreground),
|
||||
background: (active || filled).then_some(Background::Color(hover)),
|
||||
@@ -343,6 +363,8 @@ pub fn notification_button(foreground: Color, hover: Color, radius: f32, filled:
|
||||
|
||||
pub fn filled_button(fill: Color, foreground: Color, radius: f32, opacity: f32) -> theme::Button {
|
||||
let paint = move |outline| button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Some(Color { a: opacity, ..fill }.into()),
|
||||
text_color: Some(foreground),
|
||||
icon_color: Some(foreground),
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
use cosmic::iced::advanced::widget::{Id, Operation, Tree, tree};
|
||||
use cosmic::iced::advanced::{Clipboard, Layout, Shell, Widget, layout, mouse, renderer};
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
use cosmic::iced::{Event, Length, Rectangle, Size, keyboard};
|
||||
use cosmic::{Element, Renderer, Theme};
|
||||
use ferese_theme_model::Appearance;
|
||||
@@ -65,6 +66,8 @@ pub fn tile<M: Clone + 'static>(
|
||||
|
||||
fn tile_style(palette: crate::Palette, selected: bool) -> cosmic::theme::Button {
|
||||
let style = move |focused: bool, hovered: bool| cosmic::widget::button::Style {
|
||||
shape: Some(BorderShape::Continuous),
|
||||
outline: None,
|
||||
background: Some(if hovered { palette.sidebar } else { palette.card }.into()),
|
||||
border_width: if selected { 2. } else { 0. },
|
||||
border_color: palette.accent,
|
||||
@@ -395,9 +398,11 @@ impl<M: Clone> Widget<M, Theme, Renderer> for Radio<'_, M> {
|
||||
renderer::Quad {
|
||||
bounds: layout.bounds(),
|
||||
border: cosmic::iced::Border {
|
||||
shape: BorderShape::Continuous,
|
||||
color: style.text_color,
|
||||
width: 2.,
|
||||
radius: 10.into(),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/// Radius of a concentric inset, in the same units as the outer radius.
|
||||
/// Radius of a circular inset. Squircle insets retain an `Outline` and its distance offset.
|
||||
pub fn inner_radius(outer: f32, padding: f32) -> f32 {
|
||||
(outer - padding).max(0.0)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Shared menu layouts and paint; callers own actions and animation timing.
|
||||
use cosmic::Element;
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
use cosmic::iced::{Alignment, Color, Length};
|
||||
use cosmic::widget::{button, container, row as iced_row};
|
||||
|
||||
@@ -115,11 +116,13 @@ pub fn slider(foreground: Color, opacity: f32) -> cosmic::theme::iced::Slider {
|
||||
),
|
||||
width: 4.,
|
||||
border: cosmic::iced::Border {
|
||||
shape: BorderShape::Continuous,
|
||||
radius: 2.into(),
|
||||
..Default::default()
|
||||
},
|
||||
},
|
||||
handle: Handle {
|
||||
corner_shape: BorderShape::Circular,
|
||||
shape: HandleShape::Circle { radius: 6. },
|
||||
background: foreground.into(),
|
||||
border_width: 0.,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use cosmic::iced::Color;
|
||||
use cosmic::iced::border::Shape as BorderShape;
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
pub struct Palette {
|
||||
@@ -68,8 +69,9 @@ impl Palette {
|
||||
.text_tint(rgba(self.text).color)
|
||||
.accent(rgba(self.accent).color)
|
||||
.build();
|
||||
|
||||
crate::apply(&mut native, self.on_accent);
|
||||
cosmic::Theme::custom(std::sync::Arc::new(native))
|
||||
cosmic::Theme::custom(std::sync::Arc::new(native)).corner_shape(BorderShape::Continuous)
|
||||
}
|
||||
|
||||
pub fn application_style(self, background: Color) -> cosmic::iced::theme::Style {
|
||||
@@ -135,7 +137,9 @@ mod tests {
|
||||
resolved.accessibility.increase_contrast = high_contrast;
|
||||
let palette = Palette::from_resolved(&resolved);
|
||||
assert_eq!(palette.high_contrast, high_contrast);
|
||||
assert_eq!(palette.native_theme().cosmic().is_high_contrast, high_contrast);
|
||||
let native = palette.native_theme();
|
||||
assert_eq!(native.cosmic().is_high_contrast, high_contrast);
|
||||
assert_eq!(native.corner_shape, BorderShape::Continuous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user