Cosmic advanced text (#103)

* wip: update to use cosmic-advanced-text

* use cosmic-advanced-text branch of iced

* fix: line height and spacing for segmented button and update to get svg fix

* fix: spin button styling & spacing

* update iced to fix segmented button border radius

* feat: example improvements

* feat: helper for loading fonts

* feat: add focus style to button

* fix: slider height and iced fixed

* feat: hash icon width and height

* cleanup

* update ci

* refactor: always use lazy feature of iced

* update iced

* update iced

* cleanup & update iced

* update iced: new slider & tiny-skia quad updates

* update iced: fixes for tiny-skia quad rendering with edge case border radius

* re-export iced_runtime & iced_widget

* merge master

* udpate iced

* update iced

* update iced

* update iced

* fix: make rectangle_tracker subscription only return update if there is some

* feat: derive macro for loading a cosmic-config

* feat (cosmic-config): iced subscription

* fix (example): update to rectangle tracker subscription

* fix (cosmic-config)

* refactor(cosmic-config-derive): add support for types with generic parameters

* fix (cosmic-config): feature gate updates for subscription helpers

* feat: support for custom & system themes + move cosmic-theme to libcosmic

* feat: sorta hacky way of creating header bars for libcosmic + update iced to get support for resizable windows in iced-sctk

* update iced

* update and reexport sctk

* fix: applet border radius

* feat (cosmic-theme): add id and name methods

* fix(cosmic-theme): reexport palette from cosmic-theme

* fix(cosmic-config-derive): allow use with reexported cosmic-config

* feat: update iced with fix and refactor applet env vars

* update iced
This commit is contained in:
Ashley Wulber 2023-05-30 12:03:15 -04:00 committed by GitHub
parent a173794bed
commit e056e8c830
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
65 changed files with 3431 additions and 405 deletions

View file

@ -7,12 +7,13 @@ mod segmented_button;
use std::hash::Hash;
use std::hash::Hasher;
use std::rc::Rc;
use std::sync::Arc;
pub use self::segmented_button::SegmentedButton;
use cosmic_theme::Component;
use cosmic_theme::LayeredTheme;
use iced_core::BorderRadius;
use iced_core::renderer::BorderRadius;
use iced_style::application;
use iced_style::button;
use iced_style::checkbox;
@ -25,18 +26,18 @@ use iced_style::radio;
use iced_style::rule;
use iced_style::scrollable;
use iced_style::slider;
use iced_style::slider::Rail;
use iced_style::svg;
use iced_style::text;
use iced_style::text_input;
use iced_style::toggler;
use iced_core::{Background, Color};
use palette::Srgba;
type CosmicColor = ::palette::rgb::Srgba;
type CosmicComponent = cosmic_theme::Component<CosmicColor>;
type CosmicTheme = cosmic_theme::Theme<CosmicColor>;
type CosmicThemeCss = cosmic_theme::Theme<cosmic_theme::util::CssColor>;
pub type CosmicColor = ::palette::rgb::Srgba;
pub type CosmicComponent = cosmic_theme::Component<CosmicColor>;
pub type CosmicTheme = cosmic_theme::Theme<CosmicColor>;
pub type CosmicThemeCss = cosmic_theme::Theme<cosmic_theme::util::CssColor>;
lazy_static::lazy_static! {
pub static ref COSMIC_DARK: CosmicTheme = CosmicThemeCss::dark_default().into_srgba();
@ -57,16 +58,17 @@ lazy_static::lazy_static! {
};
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub enum ThemeType {
#[default]
Dark,
Light,
HighContrastDark,
HighContrastLight,
Custom(Arc<CosmicTheme>),
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Default)]
#[derive(Debug, Clone, Eq, PartialEq, Default)]
pub struct Theme {
pub theme_type: ThemeType,
pub layer: cosmic_theme::Layer,
@ -80,6 +82,7 @@ impl Theme {
ThemeType::Light => &COSMIC_LIGHT,
ThemeType::HighContrastDark => &COSMIC_HC_DARK,
ThemeType::HighContrastLight => &COSMIC_HC_LIGHT,
ThemeType::Custom(ref t) => t.as_ref(),
}
}
@ -115,6 +118,14 @@ impl Theme {
}
}
#[must_use]
pub fn custom(theme: Arc<CosmicTheme>) -> Self {
Self {
theme_type: ThemeType::Custom(theme),
..Default::default()
}
}
/// get current container
/// can be used in a component that is intended to be a child of a `CosmicContainer`
#[must_use]
@ -218,8 +229,8 @@ impl button::StyleSheet for Theme {
let component = style.cosmic(self);
button::Appearance {
border_radius: match style {
Button::Link => BorderRadius::from(0.0),
_ => BorderRadius::from(24.0),
Button::Link => 0.0,
_ => 24.0,
},
background: match style {
Button::Link | Button::Text => None,
@ -301,7 +312,7 @@ impl checkbox::StyleSheet for Theme {
} else {
palette.background.base.into()
}),
checkmark_color: palette.accent.on.into(),
icon_color: palette.accent.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -318,7 +329,7 @@ impl checkbox::StyleSheet for Theme {
} else {
palette.background.base.into()
}),
checkmark_color: palette.background.on.into(),
icon_color: palette.background.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: neutral_7.into(),
@ -330,7 +341,7 @@ impl checkbox::StyleSheet for Theme {
} else {
palette.background.base.into()
}),
checkmark_color: palette.success.on.into(),
icon_color: palette.success.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -347,7 +358,7 @@ impl checkbox::StyleSheet for Theme {
} else {
palette.background.base.into()
}),
checkmark_color: palette.destructive.on.into(),
icon_color: palette.destructive.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -374,7 +385,7 @@ impl checkbox::StyleSheet for Theme {
} else {
neutral_10.into()
}),
checkmark_color: palette.accent.on.into(),
icon_color: palette.accent.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -391,7 +402,7 @@ impl checkbox::StyleSheet for Theme {
} else {
neutral_10.into()
}),
checkmark_color: self.current_container().on.into(),
icon_color: self.current_container().on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -408,7 +419,7 @@ impl checkbox::StyleSheet for Theme {
} else {
neutral_10.into()
}),
checkmark_color: palette.success.on.into(),
icon_color: palette.success.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -425,7 +436,7 @@ impl checkbox::StyleSheet for Theme {
} else {
neutral_10.into()
}),
checkmark_color: palette.destructive.on.into(),
icon_color: palette.destructive.on.into(),
border_radius: 4.0,
border_width: if is_checked { 0.0 } else { 1.0 },
border_color: if is_checked {
@ -474,6 +485,7 @@ pub enum Container {
Secondary,
#[default]
Transparent,
HeaderBar,
Custom(Box<dyn Fn(&Theme) -> container::Appearance>),
}
@ -496,7 +508,18 @@ impl container::StyleSheet for Theme {
container::Appearance {
text_color: Some(Color::from(palette.background.on)),
background: Some(iced::Background::Color(palette.background.base.into())),
border_radius: 2.0,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
Container::HeaderBar => {
let palette = self.cosmic();
container::Appearance {
text_color: Some(Color::from(palette.background.on)),
background: Some(iced::Background::Color(palette.background.base.into())),
border_radius: BorderRadius::from([16.0, 16.0, 0.0, 0.0]),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
@ -507,7 +530,7 @@ impl container::StyleSheet for Theme {
container::Appearance {
text_color: Some(Color::from(palette.primary.on)),
background: Some(iced::Background::Color(palette.primary.base.into())),
border_radius: 2.0,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
@ -518,7 +541,7 @@ impl container::StyleSheet for Theme {
container::Appearance {
text_color: Some(Color::from(palette.secondary.on)),
background: Some(iced::Background::Color(palette.secondary.base.into())),
border_radius: 2.0,
border_radius: 2.0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
@ -538,11 +561,15 @@ impl slider::StyleSheet for Theme {
//TODO: no way to set rail thickness
slider::Appearance {
rail_colors: (
cosmic.accent.base.into(),
//TODO: no way to set color before/after slider
Color::TRANSPARENT,
),
rail: Rail {
colors: (
cosmic.accent.base.into(),
//TODO: no way to set color before/after slider
Color::TRANSPARENT,
),
width: 4.0,
},
handle: slider::Handle {
shape: slider::HandleShape::Circle { radius: 10.0 },
color: cosmic.accent.base.into(),
@ -610,7 +637,8 @@ impl pick_list::StyleSheet for Theme {
border_radius: 24.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
icon_size: 0.7,
// icon_size: 0.7, // TODO: how to replace
handle_color: cosmic.on_bg_color().into(),
}
}
@ -856,7 +884,11 @@ impl scrollable::StyleSheet for Theme {
}
}
fn hovered(&self, _style: &Self::Style) -> scrollable::Scrollbar {
fn hovered(
&self,
_style: &Self::Style,
_is_mouse_over_scrollbar: bool,
) -> scrollable::Scrollbar {
let theme = self.cosmic();
scrollable::Scrollbar {
@ -948,7 +980,7 @@ pub enum Text {
Default,
Color(Color),
// TODO: Can't use dyn Fn since this must be copy
Custom(fn(&Theme) -> text::Appearance),
Custom(fn(&Theme) -> iced_widget::text::Appearance),
}
impl From<Color> for Text {
@ -957,16 +989,16 @@ impl From<Color> for Text {
}
}
impl text::StyleSheet for Theme {
impl iced_widget::text::StyleSheet for Theme {
type Style = Text;
fn appearance(&self, style: Self::Style) -> text::Appearance {
fn appearance(&self, style: Self::Style) -> iced_widget::text::Appearance {
match style {
Text::Accent => text::Appearance {
Text::Accent => iced_widget::text::Appearance {
color: Some(self.cosmic().accent.base.into()),
},
Text::Default => text::Appearance { color: None },
Text::Color(c) => text::Appearance { color: Some(c) },
Text::Default => iced_widget::text::Appearance { color: None },
Text::Color(c) => iced_widget::text::Appearance { color: Some(c) },
Text::Custom(f) => f(self),
}
}
@ -995,12 +1027,14 @@ impl text_input::StyleSheet for Theme {
border_radius: 8.0,
border_width: 1.0,
border_color: self.current_container().component.divider.into(),
icon_color: self.current_container().on.into(),
},
TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(),
border_radius: 24.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
icon_color: self.current_container().on.into(),
},
}
}
@ -1016,12 +1050,14 @@ impl text_input::StyleSheet for Theme {
border_radius: 8.0,
border_width: 1.0,
border_color: palette.accent.base.into(),
icon_color: self.current_container().on.into(),
},
TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(),
border_radius: 24.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
icon_color: self.current_container().on.into(),
},
}
}
@ -1037,12 +1073,14 @@ impl text_input::StyleSheet for Theme {
border_radius: 8.0,
border_width: 1.0,
border_color: palette.accent.base.into(),
icon_color: self.current_container().on.into(),
},
TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(),
border_radius: 24.0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
icon_color: self.current_container().on.into(),
},
}
}
@ -1065,4 +1103,12 @@ impl text_input::StyleSheet for Theme {
palette.accent.base.into()
}
fn disabled_color(&self, _style: &Self::Style) -> Color {
todo!()
}
fn disabled(&self, _style: &Self::Style) -> text_input::Appearance {
todo!()
}
}

View file

@ -3,7 +3,7 @@
use crate::widget::segmented_button::{Appearance, ItemAppearance, StyleSheet};
use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance};
use iced_core::{Background, BorderRadius};
use iced_core::{renderer::BorderRadius, Background};
use palette::{rgb::Rgb, Alpha};
#[derive(Default)]
@ -141,7 +141,7 @@ impl StyleSheet for Theme {
mod horizontal {
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
use iced_core::{Background, BorderRadius};
use iced_core::{renderer::BorderRadius, Background};
use palette::{rgb::Rgb, Alpha};
pub fn selection_active(cosmic: &cosmic_theme::Theme<Alpha<Rgb, f32>>) -> ItemStatusAppearance {
@ -222,7 +222,7 @@ pub fn hover(
mod vertical {
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance};
use iced_core::{Background, BorderRadius};
use iced_core::{renderer::BorderRadius, Background};
use palette::{rgb::Rgb, Alpha};
pub fn selection_active(cosmic: &cosmic_theme::Theme<Alpha<Rgb, f32>>) -> ItemStatusAppearance {