WIP: continued improvements to skinning

This commit is contained in:
Will McCormick 2026-03-26 15:58:13 -04:00
parent 3bfc65d634
commit 551565cdd8
26 changed files with 258 additions and 187 deletions

View file

@ -158,7 +158,7 @@ phf = { version = "0.13.1", features = ["macros"] }
[dependencies.icetron_assets] [dependencies.icetron_assets]
git = "ssh://git@bitbucket.org/playtron-one/icetron.git" git = "ssh://git@bitbucket.org/playtron-one/icetron.git"
rev = "a1bf042" rev = "6db4fa7"
[dependencies.cosmic-theme] [dependencies.cosmic-theme]
path = "cosmic-theme" path = "cosmic-theme"

View file

@ -32,6 +32,7 @@ pub enum Button {
MenuItem, MenuItem,
MenuRoot, MenuRoot,
NavToggle, NavToggle,
Secondary,
#[default] #[default]
Standard, Standard,
Suggested, Suggested,
@ -52,14 +53,32 @@ pub fn appearance(
let mut appearance = Style::new(); let mut appearance = Style::new();
let hc = theme.theme_type.is_high_contrast(); let hc = theme.theme_type.is_high_contrast();
match style { match style {
Button::Standard Button::Standard => {
| Button::Text corner_radii = &cosmic.corner_radii.radius_m;
| Button::Suggested appearance.background = Some(Background::Color(crate::theme::STATE_DEFAULT_COLOR));
appearance.text_color = Some(Color::WHITE);
appearance.icon_color = Some(Color::WHITE);
}
Button::Secondary => {
corner_radii = &cosmic.corner_radii.radius_m;
appearance.background = Some(Background::Color(Color::from_rgb8(224, 224, 224)));
appearance.text_color = Some(Color::BLACK);
appearance.icon_color = Some(Color::BLACK);
}
Button::Text => {
let (background, _, _) = color(&cosmic.text_button);
appearance.background = Some(Background::Color(background));
appearance.text_color = Some(crate::theme::STATE_DEFAULT_COLOR);
appearance.icon_color = Some(crate::theme::STATE_DEFAULT_COLOR);
corner_radii = &cosmic.corner_radii.radius_m;
}
Button::Suggested
| Button::Destructive | Button::Destructive
| Button::Transparent => { | Button::Transparent => {
let style_component = match style { let style_component = match style {
Button::Standard => &cosmic.button,
Button::Text => &cosmic.text_button,
Button::Suggested => &cosmic.accent_button, Button::Suggested => &cosmic.accent_button,
Button::Destructive => &cosmic.destructive_button, Button::Destructive => &cosmic.destructive_button,
Button::Transparent => &TRANSPARENT_COMPONENT, Button::Transparent => &TRANSPARENT_COMPONENT,
@ -68,13 +87,8 @@ pub fn appearance(
let (background, text, icon) = color(style_component); let (background, text, icon) = color(style_component);
appearance.background = Some(Background::Color(background)); appearance.background = Some(Background::Color(background));
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.;
}
} }
Button::Icon | Button::IconVertical | Button::HeaderBar | Button::NavToggle => { Button::Icon | Button::IconVertical | Button::HeaderBar | Button::NavToggle => {
@ -254,12 +268,18 @@ impl Catalog for crate::Theme {
Some(component.on.into()) Some(component.on.into())
}; };
if matches!(style, Button::ListItem) { if matches!(style, Button::ListItem | Button::Text) {
( (
crate::theme::STATE_DEFAULT_BG, crate::theme::STATE_DEFAULT_BG,
text_color, text_color,
text_color, text_color,
) )
} else if matches!(style, Button::MenuItem | Button::MenuFolder) {
(
Color::from_rgb8(230, 230, 230),
text_color,
text_color,
)
} else { } else {
(component.hover.into(), text_color, text_color) (component.hover.into(), text_color, text_color)
} }
@ -283,12 +303,18 @@ impl Catalog for crate::Theme {
Some(component.on.into()) Some(component.on.into())
}; };
if matches!(style, Button::ListItem) { if matches!(style, Button::ListItem | Button::Text) {
( (
crate::theme::STATE_DEFAULT_BG, crate::theme::STATE_DEFAULT_BG,
text_color, text_color,
text_color, text_color,
) )
} else if matches!(style, Button::MenuItem | Button::MenuFolder) {
(
Color::from_rgb8(220, 220, 220),
text_color,
text_color,
)
} else { } else {
(component.pressed.into(), text_color, text_color) (component.pressed.into(), text_color, text_color)
} }

View file

@ -654,16 +654,16 @@ impl iced_container::Catalog for Theme {
Container::Dialog => iced_container::Style { Container::Dialog => iced_container::Style {
icon_color: Some(Color::from(cosmic.primary.on)), icon_color: Some(Color::from(cosmic.primary.on)),
text_color: Some(Color::from(cosmic.primary.on)), text_color: Some(Color::from(cosmic.primary.on)),
background: Some(iced::Background::Color(cosmic.primary.base.into())), background: Some(iced::Background::Color(Color::from_rgb8(245, 245, 245))),
border: Border { border: Border {
color: cosmic.primary.divider.into(), color: Color::TRANSPARENT,
width: 1.0, width: 0.0,
radius: cosmic.corner_radii.radius_m.into(), radius: cosmic.corner_radii.radius_m.into(),
}, },
shadow: Shadow { shadow: Shadow {
color: cosmic.shade.into(), color: Color::from_rgba(0.0, 0.0, 0.0, 0.25),
offset: Vector::new(0.0, 4.0), offset: Vector::new(0.0, 8.0),
blur_radius: 16.0, blur_radius: 32.0,
}, },
}, },
} }
@ -698,7 +698,7 @@ impl slider::Catalog for Theme {
Slider::Standard => Slider::Standard =>
//TODO: no way to set rail thickness //TODO: no way to set rail thickness
{ {
let empty_track: Color = Color::from_rgb8(224, 224, 224); let empty_track: Color = Color::from_rgb8(240, 240, 240);
slider::Style { slider::Style {
rail: Rail { rail: Rail {
backgrounds: ( backgrounds: (
@ -715,7 +715,7 @@ impl slider::Catalog for Theme {
handle: slider::Handle { handle: slider::Handle {
shape: slider::HandleShape::Circle { shape: slider::HandleShape::Circle {
radius: 8.0, radius: 6.0,
}, },
border_color: Color::from_rgba8(0, 0, 0, 0.12), border_color: Color::from_rgba8(0, 0, 0, 0.12),
border_width: 1.0, border_width: 1.0,
@ -739,7 +739,7 @@ impl slider::Catalog for Theme {
slider::Status::Hovered => match class { slider::Status::Hovered => match class {
Slider::Standard => { Slider::Standard => {
appearance.handle.shape = slider::HandleShape::Circle { appearance.handle.shape = slider::HandleShape::Circle {
radius: 10.0, radius: 7.0,
}; };
appearance.handle.border_width = 1.0; appearance.handle.border_width = 1.0;
appearance.handle.border_color = Color::from_rgba8(0, 0, 0, 0.12); appearance.handle.border_color = Color::from_rgba8(0, 0, 0, 0.12);
@ -755,7 +755,7 @@ impl slider::Catalog for Theme {
slider::Status::Dragged => match class { slider::Status::Dragged => match class {
Slider::Standard => { Slider::Standard => {
appearance.handle.shape = slider::HandleShape::Circle { appearance.handle.shape = slider::HandleShape::Circle {
radius: 10.0, radius: 7.0,
}; };
appearance.handle.border_width = 1.0; appearance.handle.border_width = 1.0;
appearance.handle.border_color = Color::from_rgba8(0, 0, 0, 0.12); appearance.handle.border_color = Color::from_rgba8(0, 0, 0, 0.12);
@ -897,17 +897,22 @@ impl toggler::Catalog for Theme {
fn style(&self, class: &Self::Class<'_>, status: toggler::Status) -> toggler::Style { fn style(&self, class: &Self::Class<'_>, status: toggler::Status) -> toggler::Style {
let cosmic = self.cosmic(); let cosmic = self.cosmic();
const HANDLE_MARGIN: f32 = 2.0; const HANDLE_MARGIN: f32 = 2.0;
let neutral_10 = cosmic.palette.neutral_10.with_alpha(0.1);
let mut active = toggler::Style { let is_toggled = matches!(
background: if matches!(status, toggler::Status::Active { is_toggled: true }) { status,
cosmic.accent.base.into() toggler::Status::Active { is_toggled: true }
} else if cosmic.is_dark { | toggler::Status::Hovered { is_toggled: true }
cosmic.palette.neutral_6.into() );
} else {
cosmic.palette.neutral_5.into() let track_color = if is_toggled {
}, crate::theme::STATE_DEFAULT_COLOR
foreground: cosmic.palette.neutral_2.into(), } else {
Color::from_rgb8(224, 224, 224)
};
let mut style = toggler::Style {
background: track_color,
foreground: Color::WHITE,
border_radius: cosmic.radius_xl().into(), border_radius: cosmic.radius_xl().into(),
handle_radius: cosmic handle_radius: cosmic
.radius_xl() .radius_xl()
@ -920,30 +925,10 @@ impl toggler::Catalog for Theme {
foreground_border_color: Color::TRANSPARENT, foreground_border_color: Color::TRANSPARENT,
}; };
match status { match status {
toggler::Status::Active { is_toggled } => active, toggler::Status::Active { .. } | toggler::Status::Hovered { .. } => style,
toggler::Status::Hovered { is_toggled } => {
let is_active = matches!(status, toggler::Status::Hovered { is_toggled: true });
toggler::Style {
background: if is_active {
over(neutral_10, cosmic.accent_color())
} else {
over(
neutral_10,
if cosmic.is_dark {
cosmic.palette.neutral_6
} else {
cosmic.palette.neutral_5
},
)
}
.into(),
..active
}
}
toggler::Status::Disabled => { toggler::Status::Disabled => {
active.background.a /= 2.; style.background.a /= 2.;
active.foreground.a /= 2.; style
active
} }
} }
} }
@ -1334,7 +1319,6 @@ impl text_input::Catalog for Theme {
fn style(&self, class: &Self::Class<'_>, status: text_input::Status) -> text_input::Style { fn style(&self, class: &Self::Class<'_>, status: text_input::Status) -> text_input::Style {
let palette = self.cosmic(); let palette = self.cosmic();
let bg = self.current_container().small_widget.with_alpha(0.25);
let neutral_9 = palette.palette.neutral_9; let neutral_9 = palette.palette.neutral_9;
let value = neutral_9.into(); let value = neutral_9.into();
@ -1343,7 +1327,7 @@ impl text_input::Catalog for Theme {
let mut appearance = match class { let mut appearance = match class {
TextInput::Default => text_input::Style { TextInput::Default => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_s.into(), radius: palette.corner_radii.radius_s.into(),
width: 1.0, width: 1.0,
@ -1355,7 +1339,7 @@ impl text_input::Catalog for Theme {
selection, selection,
}, },
TextInput::Search => text_input::Style { TextInput::Search => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_m.into(), radius: palette.corner_radii.radius_m.into(),
..Default::default() ..Default::default()
@ -1370,11 +1354,9 @@ impl text_input::Catalog for Theme {
match status { match status {
text_input::Status::Active => appearance, text_input::Status::Active => appearance,
text_input::Status::Hovered => { text_input::Status::Hovered => {
let bg = self.current_container().small_widget.with_alpha(0.25);
match class { match class {
TextInput::Default => text_input::Style { TextInput::Default => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_s.into(), radius: palette.corner_radii.radius_s.into(),
width: 1.0, width: 1.0,
@ -1386,7 +1368,7 @@ impl text_input::Catalog for Theme {
selection, selection,
}, },
TextInput::Search => text_input::Style { TextInput::Search => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_m.into(), radius: palette.corner_radii.radius_m.into(),
..Default::default() ..Default::default()
@ -1399,11 +1381,9 @@ impl text_input::Catalog for Theme {
} }
} }
text_input::Status::Focused => { text_input::Status::Focused => {
let bg = self.current_container().small_widget.with_alpha(0.25);
match class { match class {
TextInput::Default => text_input::Style { TextInput::Default => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_s.into(), radius: palette.corner_radii.radius_s.into(),
width: 1.0, width: 1.0,
@ -1415,7 +1395,7 @@ impl text_input::Catalog for Theme {
selection, selection,
}, },
TextInput::Search => text_input::Style { TextInput::Search => text_input::Style {
background: Color::from(bg).into(), background: Color::WHITE.into(),
border: Border { border: Border {
radius: palette.corner_radii.radius_m.into(), radius: palette.corner_radii.radius_m.into(),
..Default::default() ..Default::default()

View file

@ -289,7 +289,7 @@ mod horizontal {
let rad_0 = cosmic.corner_radii.radius_0; let rad_0 = cosmic.corner_radii.radius_0;
ItemStatusAppearance { ItemStatusAppearance {
background: Some(Background::Color( background: Some(Background::Color(
cosmic.palette.neutral_5.with_alpha(0.2).into(), cosmic.palette.neutral_5.with_alpha(0.05).into(),
)), )),
first: ItemAppearance { first: ItemAppearance {
border: Border { border: Border {
@ -381,7 +381,7 @@ mod vertical {
pub fn tab_bar_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance { pub fn tab_bar_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance {
ItemStatusAppearance { ItemStatusAppearance {
background: Some(Background::Color( background: Some(Background::Color(
cosmic.palette.neutral_5.with_alpha(0.2).into(), cosmic.palette.neutral_5.with_alpha(0.05).into(),
)), )),
first: ItemAppearance { first: ItemAppearance {
border: Border { border: Border {

View file

@ -6,7 +6,6 @@
use crate::ext::ColorExt; use crate::ext::ColorExt;
use crate::widget::text_input::{Appearance, StyleSheet}; use crate::widget::text_input::{Appearance, StyleSheet};
use iced_core::Color; use iced_core::Color;
use palette::WithAlpha;
#[derive(Default)] #[derive(Default)]
pub enum TextInput { pub enum TextInput {
@ -32,13 +31,11 @@ impl StyleSheet for crate::Theme {
let palette = self.cosmic(); let palette = self.cosmic();
let container = self.current_container(); let container = self.current_container();
let background: Color = container.small_widget.with_alpha(0.25).into();
let corner = palette.corner_radii; let corner = palette.corner_radii;
let label_color = palette.palette.neutral_9; let label_color = palette.palette.neutral_9;
match style { match style {
TextInput::Default => Appearance { TextInput::Default => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_s.into(), border_radius: corner.radius_s.into(),
border_width: 2.0, border_width: 2.0,
border_offset: None, border_offset: None,
@ -47,7 +44,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -63,7 +60,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -79,14 +76,14 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
label_color: label_color.into(), label_color: label_color.into(),
}, },
TextInput::Search => Appearance { TextInput::Search => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_xl.into(), border_radius: corner.radius_xl.into(),
border_width: 2.0, border_width: 2.0,
border_offset: None, border_offset: None,
@ -95,7 +92,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -111,7 +108,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -125,15 +122,12 @@ impl StyleSheet for crate::Theme {
let palette = self.cosmic(); let palette = self.cosmic();
let container = self.current_container(); let container = self.current_container();
let mut background: Color = container.small_widget.into();
background.a = 0.25;
let corner = palette.corner_radii; let corner = palette.corner_radii;
let label_color = palette.palette.neutral_9; let label_color = palette.palette.neutral_9;
match style { match style {
TextInput::Default => Appearance { TextInput::Default => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_s.into(), border_radius: corner.radius_s.into(),
border_width: 2.0, border_width: 2.0,
border_offset: Some(2.0), border_offset: Some(2.0),
@ -142,14 +136,14 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
label_color: label_color.into(), label_color: label_color.into(),
}, },
TextInput::Search | TextInput::ExpandableSearch => Appearance { TextInput::Search | TextInput::ExpandableSearch => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_xl.into(), border_radius: corner.radius_xl.into(),
border_width: 0.0, border_width: 0.0,
border_offset: None, border_offset: None,
@ -158,7 +152,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -174,7 +168,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -188,15 +182,12 @@ impl StyleSheet for crate::Theme {
let palette = self.cosmic(); let palette = self.cosmic();
let container = self.current_container(); let container = self.current_container();
let mut background: Color = container.small_widget.into();
background.a = 0.25;
let corner = palette.corner_radii; let corner = palette.corner_radii;
let label_color = palette.palette.neutral_9; let label_color = palette.palette.neutral_9;
match style { match style {
TextInput::Default => Appearance { TextInput::Default => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_s.into(), border_radius: corner.radius_s.into(),
border_width: 2.0, border_width: 2.0,
border_offset: None, border_offset: None,
@ -205,14 +196,14 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
label_color: label_color.into(), label_color: label_color.into(),
}, },
TextInput::Search => Appearance { TextInput::Search => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_xl.into(), border_radius: corner.radius_xl.into(),
border_offset: None, border_offset: None,
border_width: 2.0, border_width: 2.0,
@ -221,14 +212,14 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
label_color: label_color.into(), label_color: label_color.into(),
}, },
TextInput::ExpandableSearch => Appearance { TextInput::ExpandableSearch => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_xl.into(), border_radius: corner.radius_xl.into(),
border_offset: None, border_offset: None,
border_width: 0.0, border_width: 0.0,
@ -237,7 +228,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -253,7 +244,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -269,7 +260,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -283,15 +274,12 @@ impl StyleSheet for crate::Theme {
let palette = self.cosmic(); let palette = self.cosmic();
let container = self.current_container(); let container = self.current_container();
let mut background: Color = container.small_widget.into();
background.a = 0.25;
let corner = palette.corner_radii; let corner = palette.corner_radii;
let label_color = palette.palette.neutral_9; let label_color = palette.palette.neutral_9;
match style { match style {
TextInput::Default => Appearance { TextInput::Default => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_s.into(), border_radius: corner.radius_s.into(),
border_width: 2.0, border_width: 2.0,
border_offset: Some(2.0), border_offset: Some(2.0),
@ -300,14 +288,14 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
label_color: label_color.into(), label_color: label_color.into(),
}, },
TextInput::Search | TextInput::ExpandableSearch => Appearance { TextInput::Search | TextInput::ExpandableSearch => Appearance {
background: background.into(), background: Color::WHITE.into(),
border_radius: corner.radius_xl.into(), border_radius: corner.radius_xl.into(),
border_width: 2.0, border_width: 2.0,
border_offset: Some(2.0), border_offset: Some(2.0),
@ -316,7 +304,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -332,7 +320,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),
@ -348,7 +336,7 @@ impl StyleSheet for crate::Theme {
text_color: None, text_color: None,
placeholder_color: { placeholder_color: {
let color: Color = container.on.into(); let color: Color = container.on.into();
color.blend_alpha(background, 0.7) color.blend_alpha(Color::WHITE, 0.7)
}, },
selected_text_color: palette.on_accent_color().into(), selected_text_color: palette.on_accent_color().into(),
selected_fill: palette.accent_color().into(), selected_fill: palette.accent_color().into(),

View file

@ -101,7 +101,7 @@ pub fn about<'a, Message: Clone + 'static>(
.push(widget::text(name)) .push(widget::text(name))
.push(horizontal_space()) .push(horizontal_space())
.push_maybe( .push_maybe(
(!url.is_empty()).then_some(crate::widget::icon::from_name("link-symbolic").icon()), (!url.is_empty()).then_some(crate::widget::icon::from_svg_bytes(icetron_assets::icons::system::EXTERNAL_LINK_LINE).icon()),
) )
.align_y(Alignment::Center) .align_y(Alignment::Center)
.apply(widget::button::custom) .apply(widget::button::custom)

View file

@ -61,7 +61,7 @@ impl<'a, Message> Button<'a, Message> {
#[inline(never)] #[inline(never)]
pub fn icon() -> Handle { pub fn icon() -> Handle {
icon::from_svg_bytes(&include_bytes!("external-link.svg")[..]).symbolic(true) icon::from_svg_bytes(icetron_assets::icons::system::EXTERNAL_LINK_LINE).symbolic(true)
} }
impl<'a, Message: Clone + 'static> From<Button<'a, Message>> for Element<'a, Message> { impl<'a, Message: Clone + 'static> From<Button<'a, Message>> for Element<'a, Message> {

View file

@ -32,7 +32,7 @@ mod text;
#[doc(inline)] #[doc(inline)]
pub use text::Button as TextButton; pub use text::Button as TextButton;
#[doc(inline)] #[doc(inline)]
pub use text::{destructive, standard, suggested, text}; pub use text::{destructive, secondary, standard, suggested, text};
mod widget; mod widget;
#[doc(inline)] #[doc(inline)]

View file

@ -35,6 +35,13 @@ pub fn text<'a, Message>(label: impl Into<Cow<'a, str>>) -> Button<'a, Message>
.class(ButtonClass::Text) .class(ButtonClass::Text)
} }
/// A text button with the secondary style
pub fn secondary<'a, Message>(label: impl Into<Cow<'a, str>>) -> Button<'a, Message> {
Button::new(Text::new())
.label(label)
.class(ButtonClass::Secondary)
}
/// The text variant of a button. /// The text variant of a button.
pub struct Text { pub struct Text {
pub(super) leading_icon: Option<icon::Handle>, pub(super) leading_icon: Option<icon::Handle>,

View file

@ -105,14 +105,7 @@ impl<'a, Message: Clone + 'a> Button<'a, Message> {
style: crate::theme::Button::default(), style: crate::theme::Button::default(),
variant: Variant::Image { variant: Variant::Image {
on_remove, on_remove,
close_icon: crate::widget::icon::from_name("window-close-symbolic") close_icon: iced_core::svg::Handle::from_memory(icetron_assets::icons::system::CLOSE_LINE),
.size(8)
.icon()
.into_svg_handle()
.unwrap_or_else(|| {
let bytes: &'static [u8] = &[];
iced_core::svg::Handle::from_memory(bytes)
}),
}, },
} }
} }

View file

@ -161,12 +161,12 @@ where
let month_controls = row::with_capacity(2) let month_controls = row::with_capacity(2)
.push( .push(
icon::from_name("go-previous-symbolic") icon::from_svg_bytes(icetron_assets::icons::system::ARROW_LEFT_S_LINE)
.apply(button::icon) .apply(button::icon)
.on_press((this.on_prev)()), .on_press((this.on_prev)()),
) )
.push( .push(
icon::from_name("go-next-symbolic") icon::from_svg_bytes(icetron_assets::icons::system::ARROW_RIGHT_S_LINE)
.apply(button::icon) .apply(button::icon)
.on_press((this.on_next)()), .on_press((this.on_next)()),
); );

View file

@ -30,7 +30,7 @@ use iced_widget::{Row, canvas, column, horizontal_space, row, scrollable, vertic
use palette::{FromColor, RgbHue}; use palette::{FromColor, RgbHue};
use super::divider::horizontal; use super::divider::horizontal;
use super::icon::{self, from_name}; use super::icon;
use super::segmented_button::{self, SingleSelect}; use super::segmented_button::{self, SingleSelect};
use super::{Icon, button, segmented_control, text, text_input, tooltip}; use super::{Icon, button, segmented_control, text, text_input, tooltip};
@ -404,8 +404,8 @@ where
// TODO copy paste input contents // TODO copy paste input contents
.trailing_icon({ .trailing_icon({
let button = button::custom(crate::widget::icon( let button = button::custom(crate::widget::icon(
from_name("edit-copy-symbolic").size(spacing.space_s).into(), icon::from_svg_bytes(icetron_assets::icons::document::FILE_COPY_LINE),
)) ).size(spacing.space_s))
.on_press(on_update(ColorPickerUpdate::Copied(Instant::now()))) .on_press(on_update(ColorPickerUpdate::Copied(Instant::now())))
.class(Button::Text); .class(Button::Text);
@ -819,9 +819,8 @@ pub fn color_button<'a, Message: Clone + 'static>(
row![ row![
horizontal_space().width(Length::FillPortion(6)), horizontal_space().width(Length::FillPortion(6)),
Icon::from( Icon::from(
icon::from_name("list-add-symbolic") icon::from_svg_bytes(icetron_assets::icons::system::ADD_LINE)
.prefer_svg(true) .icon()
.symbolic(true)
.size(64) .size(64)
) )
.width(icon_portion) .width(icon_portion)

View file

@ -1,18 +1,10 @@
use crate::widget::svg; use crate::widget::svg;
use std::sync::OnceLock; use std::sync::OnceLock;
/// Static `svg::Handle` to the `object-select-symbolic` icon.
pub fn object_select() -> &'static svg::Handle { pub fn object_select() -> &'static svg::Handle {
static SELECTION_ICON: OnceLock<svg::Handle> = OnceLock::new(); static SELECTION_ICON: OnceLock<svg::Handle> = OnceLock::new();
SELECTION_ICON.get_or_init(|| { SELECTION_ICON.get_or_init(|| {
crate::widget::icon::from_name("object-select-symbolic") iced_core::svg::Handle::from_memory(icetron_assets::icons::system::CHECK_LINE)
.size(16)
.icon()
.into_svg_handle()
.unwrap_or_else(|| {
let bytes: &'static [u8] = &[];
iced_core::svg::Handle::from_memory(bytes)
})
}) })
} }

View file

@ -71,7 +71,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
let header_row = row::with_capacity(2).push(actions_slot).push( let header_row = row::with_capacity(2).push(actions_slot).push(
button::text(fl!("close")) button::text(fl!("close"))
.trailing_icon(icon::from_name("go-next-symbolic")) .trailing_icon(icon::from_svg_bytes(icetron_assets::icons::system::ARROW_RIGHT_S_LINE))
.on_press(on_close), .on_press(on_close),
); );
let header = column::with_capacity(3) let header = column::with_capacity(3)

View file

@ -3,7 +3,6 @@
// SPDX-License-Identifier: MPL-2.0 AND MIT // SPDX-License-Identifier: MPL-2.0 AND MIT
use super::menu::{self, Menu}; use super::menu::{self, Menu};
use crate::widget::icon;
use derive_setters::Setters; use derive_setters::Setters;
use iced_core::event::{self, Event}; use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text}; use iced_core::text::{self, Paragraph, Text};
@ -229,10 +228,7 @@ impl<Item: Clone + PartialEq + 'static> State<Item> {
/// Creates a new [`State`] for a [`Dropdown`]. /// Creates a new [`State`] for a [`Dropdown`].
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
icon: match icon::from_name("pan-down-symbolic").size(16).handle().data { icon: Some(iced_core::svg::Handle::from_memory(icetron_assets::icons::system::ARROW_DOWN_S_LINE)),
icon::Data::Svg(handle) => Some(handle),
icon::Data::Image(_) => None,
},
menu: menu::State::default(), menu: menu::State::default(),
keyboard_modifiers: keyboard::Modifiers::default(), keyboard_modifiers: keyboard::Modifiers::default(),
is_open: false, is_open: false,

View file

@ -413,10 +413,7 @@ impl State {
/// Creates a new [`State`] for a [`Dropdown`]. /// Creates a new [`State`] for a [`Dropdown`].
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
icon: match icon::from_name("pan-down-symbolic").size(16).handle().data { icon: Some(iced_core::svg::Handle::from_memory(icetron_assets::icons::system::ARROW_DOWN_S_LINE)),
icon::Data::Svg(handle) => Some(handle),
icon::Data::Image(_) => None,
},
menu: menu::State::default(), menu: menu::State::default(),
keyboard_modifiers: keyboard::Modifiers::default(), keyboard_modifiers: keyboard::Modifiers::default(),
is_open: Arc::new(AtomicBool::new(false)), is_open: Arc::new(AtomicBool::new(false)),

View file

@ -552,10 +552,10 @@ impl<'a, Message: Clone + 'static> HeaderBar<'a, Message> {
/// Creates the widget for window controls. /// Creates the widget for window controls.
fn window_controls(&mut self) -> Element<'a, Message> { fn window_controls(&mut self) -> Element<'a, Message> {
const ICON_MINIMIZE: &[u8] = include_bytes!("../../res/icons/window-minimize.svg"); const ICON_MINIMIZE: &[u8] = icetron_assets::icons::system::SUBTRACT_LINE;
const ICON_MAXIMIZE: &[u8] = include_bytes!("../../res/icons/window-maximize.svg"); const ICON_MAXIMIZE: &[u8] = icetron_assets::icons::system::CHECKBOX_BLANK_LINE;
const ICON_RESTORE: &[u8] = include_bytes!("../../res/icons/window-restore.svg"); const ICON_RESTORE: &[u8] = icetron_assets::icons::system::CHECKBOX_MULTIPLE_BLANK_LINE;
const ICON_CLOSE: &[u8] = include_bytes!("../../res/icons/window-close.svg"); const ICON_CLOSE: &[u8] = icetron_assets::icons::system::CLOSE_LINE;
macro_rules! wc_icon { macro_rules! wc_icon {
($svg_bytes:expr, $size:expr, $on_press:expr, $is_close:expr) => {{ ($svg_bytes:expr, $size:expr, $on_press:expr, $is_close:expr) => {{

View file

@ -94,7 +94,7 @@ pub fn from_raster_pixels(
/// Create a SVG handle from memory. /// Create a SVG handle from memory.
pub fn from_svg_bytes(bytes: impl Into<Cow<'static, [u8]>>) -> Handle { pub fn from_svg_bytes(bytes: impl Into<Cow<'static, [u8]>>) -> Handle {
Handle { Handle {
symbolic: false, symbolic: true,
data: Data::Svg(svg::Handle::from_memory(bytes)), data: Data::Svg(svg::Handle::from_memory(bytes)),
} }
} }

View file

@ -290,9 +290,9 @@ pub fn menu_items<
let key = find_key(&action, key_binds); let key = find_key(&action, key_binds);
let mut items = vec![ let mut items = vec![
if value { if value {
widget::icon::from_name("object-select-symbolic") widget::icon::from_svg_bytes(icetron_assets::icons::system::CHECK_LINE)
.size(16)
.icon() .icon()
.size(16)
.class(theme::Svg::Custom(Rc::new(|theme| { .class(theme::Svg::Custom(Rc::new(|theme| {
iced_widget::svg::Style { iced_widget::svg::Style {
color: Some(theme.cosmic().accent_text_color().into()), color: Some(theme.cosmic().accent_text_color().into()),
@ -326,9 +326,9 @@ pub fn menu_items<
menu_button::<'static, _>(vec![ menu_button::<'static, _>(vec![
widget::text(l.clone()).into(), widget::text(l.clone()).into(),
widget::horizontal_space().into(), widget::horizontal_space().into(),
widget::icon::from_name("pan-end-symbolic") widget::icon::from_svg_bytes(icetron_assets::icons::system::ARROW_RIGHT_S_LINE)
.size(16)
.icon() .icon()
.size(16)
.into(), .into(),
]) ])
.class( .class(

View file

@ -343,7 +343,12 @@ where
position.x = position.x.round(); position.x = position.x.round();
position.y = position.y.round(); position.y = position.y.round();
node.move_to(position) if self.modal {
let child = node.move_to(Point::new(position.x, position.y));
layout::Node::with_children(bounds, vec![child])
} else {
node.move_to(position)
}
} }
fn operate( fn operate(
@ -352,9 +357,14 @@ where
renderer: &Renderer, renderer: &Renderer,
operation: &mut dyn Operation<()>, operation: &mut dyn Operation<()>,
) { ) {
let content_layout = if self.modal {
layout.children().next().unwrap()
} else {
layout
};
self.content self.content
.as_widget() .as_widget()
.operate(self.tree, layout, renderer, operation); .operate(self.tree, content_layout, renderer, operation);
} }
fn on_event( fn on_event(
@ -366,9 +376,15 @@ where
clipboard: &mut dyn Clipboard, clipboard: &mut dyn Clipboard,
shell: &mut Shell<'_, Message>, shell: &mut Shell<'_, Message>,
) -> event::Status { ) -> event::Status {
let content_layout = if self.modal {
layout.children().next().unwrap()
} else {
layout
};
if self.modal if self.modal
&& matches!(event, Event::Mouse(_) | Event::Touch(_)) && matches!(event, Event::Mouse(_) | Event::Touch(_))
&& !cursor_position.is_over(layout.bounds()) && !cursor_position.is_over(content_layout.bounds())
{ {
return event::Status::Captured; return event::Status::Captured;
} }
@ -376,12 +392,12 @@ where
self.content.as_widget_mut().on_event( self.content.as_widget_mut().on_event(
self.tree, self.tree,
event, event,
layout, content_layout,
cursor_position, cursor_position,
renderer, renderer,
clipboard, clipboard,
shell, shell,
&layout.bounds(), &content_layout.bounds(),
) )
} }
@ -392,13 +408,19 @@ where
viewport: &Rectangle, viewport: &Rectangle,
renderer: &Renderer, renderer: &Renderer,
) -> mouse::Interaction { ) -> mouse::Interaction {
if self.modal && !cursor_position.is_over(layout.bounds()) { let content_layout = if self.modal {
layout.children().next().unwrap()
} else {
layout
};
if self.modal && !cursor_position.is_over(content_layout.bounds()) {
return mouse::Interaction::None; return mouse::Interaction::None;
} }
self.content.as_widget().mouse_interaction( self.content.as_widget().mouse_interaction(
self.tree, self.tree,
layout, content_layout,
cursor_position, cursor_position,
viewport, viewport,
renderer, renderer,
@ -413,16 +435,42 @@ where
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: mouse::Cursor, cursor_position: mouse::Cursor,
) { ) {
let bounds = layout.bounds(); if self.modal {
self.content.as_widget().draw( // Draw over the full window (layout covers entire window)
self.tree, let full_bounds = layout.bounds();
renderer, renderer.fill_quad(
theme, renderer::Quad {
style, bounds: full_bounds,
layout, border: iced_core::Border::default(),
cursor_position, shadow: iced_core::Shadow::default(),
&bounds, },
); iced_core::Background::Color(iced_core::Color::from_rgba(0.0, 0.0, 0.0, 0.4)),
);
// Draw dialog content from the child node
let content_layout = layout.children().next().unwrap();
let content_bounds = content_layout.bounds();
self.content.as_widget().draw(
self.tree,
renderer,
theme,
style,
content_layout,
cursor_position,
&content_bounds,
);
} else {
let bounds = layout.bounds();
self.content.as_widget().draw(
self.tree,
renderer,
theme,
style,
layout,
cursor_position,
&bounds,
);
}
} }
fn overlay<'c>( fn overlay<'c>(
@ -430,9 +478,14 @@ where
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'c, Message, crate::Theme, Renderer>> { ) -> Option<overlay::Element<'c, Message, crate::Theme, Renderer>> {
let content_layout = if self.modal {
layout.children().next().unwrap()
} else {
layout
};
self.content self.content
.as_widget_mut() .as_widget_mut()
.overlay(self.tree, layout, renderer, Default::default()) .overlay(self.tree, content_layout, renderer, Default::default())
} }
} }

View file

@ -124,7 +124,7 @@ impl ResponsiveMenuBar {
id_container( id_container(
menu::bar(vec![menu::Tree::<_>::with_children( menu::bar(vec![menu::Tree::<_>::with_children(
Element::from( Element::from(
button::icon(icon::from_name("open-menu-symbolic")) button::icon(icon::from_svg_bytes(icetron_assets::icons::system::MENU_LINE))
.padding([4, 12]) .padding([4, 12])
.class(crate::theme::Button::MenuRoot), .class(crate::theme::Button::MenuRoot),
), ),

View file

@ -204,7 +204,7 @@ where
Self { Self {
model, model,
id: Id::unique(), id: Id::unique(),
close_icon: icon::from_name("window-close-symbolic").size(16).icon(), close_icon: icon::from_svg_bytes(icetron_assets::icons::system::CLOSE_LINE).icon().size(16),
scrollable_focus: false, scrollable_focus: false,
show_close_icon_on_hover: false, show_close_icon_on_hover: false,
button_alignment: Alignment::Start, button_alignment: Alignment::Start,
@ -855,6 +855,7 @@ where
tab_drag_candidate: None, tab_drag_candidate: None,
dragging_tab: None, dragging_tab: None,
drop_hint: None, drop_hint: None,
close_hovered: None,
offer_mimes: Vec::new(), offer_mimes: Vec::new(),
}) })
} }
@ -1009,6 +1010,7 @@ where
"offer leave id={my_id:?} entity={entity:?}" "offer leave id={my_id:?} entity={entity:?}"
); );
state.hovered = Item::None; state.hovered = Item::None;
state.close_hovered = None;
for key in self.model.order.iter().copied() { for key in self.model.order.iter().copied() {
self.update_entity_paragraph(state, key); self.update_entity_paragraph(state, key);
} }
@ -1063,6 +1065,7 @@ where
} }
} else if entity.is_some() { } else if entity.is_some() {
state.hovered = Item::None; state.hovered = Item::None;
state.close_hovered = None;
for key in self.model.order.iter().copied() { for key in self.model.order.iter().copied() {
self.update_entity_paragraph(state, key); self.update_entity_paragraph(state, key);
} }
@ -1153,6 +1156,7 @@ where
if let Some(event) = pending_reorder { if let Some(event) = pending_reorder {
state.focused_item = Item::Tab(event.dragged); state.focused_item = Item::Tab(event.dragged);
state.hovered = Item::None; state.hovered = Item::None;
state.close_hovered = None;
for key in self.model.order.iter().copied() { for key in self.model.order.iter().copied() {
self.update_entity_paragraph(state, key); self.update_entity_paragraph(state, key);
} }
@ -1241,6 +1245,13 @@ where
let over_close_button = self.model.items[key].closable let over_close_button = self.model.items[key].closable
&& cursor_position.is_over(close_button_bounds); && cursor_position.is_over(close_button_bounds);
// Track close button hover state
state.close_hovered = if over_close_button {
Some(key)
} else {
None
};
// If marked as closable, show a close icon. // If marked as closable, show a close icon.
if self.model.items[key].closable { if self.model.items[key].closable {
// Emit close message if the close button is pressed. // Emit close message if the close button is pressed.
@ -1353,6 +1364,7 @@ where
break; break;
} else if state.hovered == Item::Tab(key) { } else if state.hovered == Item::Tab(key) {
state.hovered = Item::None; state.hovered = Item::None;
state.close_hovered = None;
self.update_entity_paragraph(state, key); self.update_entity_paragraph(state, key);
} }
} }
@ -2030,6 +2042,28 @@ where
if show_close_button { if show_close_button {
let close_button_bounds = close_bounds(original_bounds, close_icon_width); let close_button_bounds = close_bounds(original_bounds, close_icon_width);
// Draw a red background on the close button when hovered
if state.close_hovered == Some(key) {
let padding = 4.0;
let bg_bounds = Rectangle {
x: close_button_bounds.x - padding,
y: close_button_bounds.y - padding,
width: close_button_bounds.width + padding * 2.0,
height: close_button_bounds.height + padding * 2.0,
};
renderer.fill_quad(
renderer::Quad {
bounds: bg_bounds,
border: Border {
radius: (bg_bounds.width / 2.0).into(),
..Default::default()
},
shadow: Shadow::default(),
},
Background::Color(iced_core::Color::from_rgba(1.0, 0.0, 0.0, 0.1)),
);
}
draw_icon::<Message>( draw_icon::<Message>(
renderer, renderer,
theme, theme,
@ -2338,6 +2372,8 @@ pub struct LocalState {
dragging_tab: Option<Entity>, dragging_tab: Option<Entity>,
/// Current drop hint for drag-and-drop indicator /// Current drop hint for drag-and-drop indicator
drop_hint: Option<DropHint>, drop_hint: Option<DropHint>,
/// Track whether the close button is hovered on a specific entity
close_hovered: Option<Entity>,
} }
#[derive(Debug, Default, PartialEq)] #[derive(Debug, Default, PartialEq)]
@ -2465,6 +2501,7 @@ mod tests {
tab_drag_candidate: None, tab_drag_candidate: None,
dragging_tab: Some(dragging), dragging_tab: Some(dragging),
drop_hint: None, drop_hint: None,
close_hovered: None,
offer_mimes: Vec::new(), offer_mimes: Vec::new(),
}; };
state.buttons_visible = len; state.buttons_visible = len;

View file

@ -103,8 +103,8 @@ where
.spacing(val.icon_spacing) .spacing(val.icon_spacing)
.push(widget::text::heading(category.to_string())) .push(widget::text::heading(category.to_string()))
.push_maybe(match sort_state { .push_maybe(match sort_state {
1 => Some(widget::icon::from_name("pan-up-symbolic").icon()), 1 => Some(widget::icon::from_svg_bytes(icetron_assets::icons::system::ARROW_UP_S_LINE).icon()),
2 => Some(widget::icon::from_name("pan-down-symbolic").icon()), 2 => Some(widget::icon::from_svg_bytes(icetron_assets::icons::system::ARROW_DOWN_S_LINE).icon()),
_ => None, _ => None,
}) })
.apply(container) .apply(container)

View file

@ -96,7 +96,8 @@ where
.padding([0, spacing]) .padding([0, spacing])
.style(crate::theme::TextInput::Search) .style(crate::theme::TextInput::Search)
.leading_icon( .leading_icon(
crate::widget::icon::from_name("system-search-symbolic") crate::widget::icon::from_svg_bytes(icetron_assets::icons::system::SEARCH_LINE)
.icon()
.size(16) .size(16)
.apply(crate::widget::container) .apply(crate::widget::container)
.padding(8) .padding(8)
@ -120,7 +121,8 @@ where
.padding([0, spacing]) .padding([0, spacing])
.style(crate::theme::TextInput::Default) .style(crate::theme::TextInput::Default)
.leading_icon( .leading_icon(
crate::widget::icon::from_name("system-lock-screen-symbolic") crate::widget::icon::from_svg_bytes(icetron_assets::icons::system::LOCK_LINE)
.icon()
.size(16) .size(16)
.apply(crate::widget::container) .apply(crate::widget::container)
.padding(8) .padding(8)
@ -131,11 +133,12 @@ where
} }
if let Some(msg) = on_visible_toggle { if let Some(msg) = on_visible_toggle {
input.trailing_icon( input.trailing_icon(
crate::widget::icon::from_name(if hidden { crate::widget::icon::from_svg_bytes(if hidden {
"document-properties-symbolic" icetron_assets::icons::system::EYE_LINE
} else { } else {
"image-red-eye-symbolic" icetron_assets::icons::system::EYE_OFF_LINE
}) })
.icon()
.size(16) .size(16)
.apply(crate::widget::button::custom) .apply(crate::widget::button::custom)
.class(crate::theme::Button::Icon) .class(crate::theme::Button::Icon)
@ -537,7 +540,8 @@ where
pub fn on_clear(self, on_clear: Message) -> Self { pub fn on_clear(self, on_clear: Message) -> Self {
self.trailing_icon( self.trailing_icon(
crate::widget::icon::from_name("edit-clear-symbolic") crate::widget::icon::from_svg_bytes(icetron_assets::icons::system::CLOSE_CIRCLE_LINE)
.icon()
.size(16) .size(16)
.apply(crate::widget::button::custom) .apply(crate::widget::button::custom)
.class(crate::theme::Button::Icon) .class(crate::theme::Button::Icon)

View file

@ -42,7 +42,7 @@ pub fn toaster<'a, Message: Clone + 'static>(
button::text(&action.description).on_press((action.message)(id)) button::text(&action.description).on_press((action.message)(id))
})) }))
.push( .push(
button::icon(icon::from_name("window-close-symbolic")) button::icon(icon::from_svg_bytes(icetron_assets::icons::system::CLOSE_LINE))
.on_press((toasts.on_close)(id)), .on_press((toasts.on_close)(id)),
) )
.align_y(iced::Alignment::Center) .align_y(iced::Alignment::Center)

View file

@ -33,8 +33,7 @@ impl<'a, Message: 'static + Clone> Warning<'a, Message> {
pub fn into_widget(self) -> widget::Container<'a, Message, crate::Theme, Renderer> { pub fn into_widget(self) -> widget::Container<'a, Message, crate::Theme, Renderer> {
let label = widget::container(crate::widget::text(self.message)).width(Length::Fill); let label = widget::container(crate::widget::text(self.message)).width(Length::Fill);
let close_button = icon::from_name("window-close-symbolic") let close_button = icon::from_svg_bytes(icetron_assets::icons::system::CLOSE_LINE)
.size(16)
.apply(widget::button::icon) .apply(widget::button::icon)
.on_press_maybe(self.on_close); .on_press_maybe(self.on_close);