diff --git a/examples/cosmic/Cargo.toml b/examples/cosmic/Cargo.toml index 7332a695..4a741a28 100644 --- a/examples/cosmic/Cargo.toml +++ b/examples/cosmic/Cargo.toml @@ -8,7 +8,7 @@ publish = false [dependencies] apply = "0.3.0" fraction = "0.14.0" -libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "dbus-config"] } +libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "dbus-config", "wgpu"] } once_cell = "1.18" slotmap = "1.0.6" env_logger = "0.10" diff --git a/examples/multi-window/Cargo.toml b/examples/multi-window/Cargo.toml index 18e0fff2..7a8e3051 100644 --- a/examples/multi-window/Cargo.toml +++ b/examples/multi-window/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "multi-window", "dbus-config"] } +libcosmic = { path = "../..", features = ["debug", "winit", "tokio", "single-instance", "multi-window", "dbus-config", "wgpu"] } diff --git a/iced b/iced index 6115280d..32a0efcd 160000 --- a/iced +++ b/iced @@ -1 +1 @@ -Subproject commit 6115280d5277c50b8539d4eff6ab61050c51b592 +Subproject commit 32a0efcd05e827ba3ad9913e50dd103510e8bca7 diff --git a/src/app/cosmic.rs b/src/app/cosmic.rs index 471db012..211bfc2e 100644 --- a/src/app/cosmic.rs +++ b/src/app/cosmic.rs @@ -22,7 +22,6 @@ use iced::window; #[cfg(not(any(feature = "multi-window", feature = "wayland")))] use iced::Application as IcedApplication; use iced_futures::event::listen_raw; -use iced_futures::futures::executor::block_on; #[cfg(not(feature = "wayland"))] use iced_runtime::command::Action; #[cfg(not(feature = "wayland"))] @@ -86,6 +85,7 @@ where fn new((mut core, flags): Self::Flags) -> (Self, iced::Command) { #[cfg(feature = "dbus-config")] { + use iced_futures::futures::executor::block_on; core.settings_daemon = block_on(cosmic_config::dbus::settings_daemon_proxy()).ok(); } diff --git a/src/applet/mod.rs b/src/applet/mod.rs index 45d769fd..2e6c8e24 100644 --- a/src/applet/mod.rs +++ b/src/applet/mod.rs @@ -16,7 +16,7 @@ use crate::{ }; pub use cosmic_panel_config; use cosmic_panel_config::{CosmicPanelBackground, PanelAnchor, PanelSize}; -use iced_core::Padding; +use iced_core::{Padding, Shadow}; use iced_style::container::Appearance; use iced_widget::runtime::command::platform_specific::wayland::popup::{ SctkPopupSettings, SctkPositioner, @@ -142,7 +142,7 @@ impl Context { pub fn popup_container<'a, Message: 'static>( &self, content: impl Into>, - ) -> Container<'a, Message, Renderer> { + ) -> Container<'a, Message, crate::Theme, Renderer> { let (vertical_align, horizontal_align) = match self.anchor { PanelAnchor::Left => (Vertical::Center, Horizontal::Left), PanelAnchor::Right => (Vertical::Center, Horizontal::Right), @@ -150,20 +150,25 @@ impl Context { PanelAnchor::Bottom => (Vertical::Bottom, Horizontal::Center), }; - Container::::new(Container::::new(content).style( - theme::Container::custom(|theme| { - let cosmic = theme.cosmic(); - let corners = cosmic.corner_radii.clone(); - Appearance { - text_color: Some(cosmic.background.on.into()), - background: Some(Color::from(cosmic.background.base).into()), - border_radius: corners.radius_m.into(), - border_width: 1.0, - border_color: cosmic.background.divider.into(), - icon_color: Some(cosmic.background.on.into()), - } - }), - )) + Container::::new( + Container::::new(content).style(theme::Container::custom( + |theme| { + let cosmic = theme.cosmic(); + let corners = cosmic.corner_radii.clone(); + Appearance { + text_color: Some(cosmic.background.on.into()), + background: Some(Color::from(cosmic.background.base).into()), + border: iced::Border { + radius: corners.radius_m.into(), + width: 1.0, + color: cosmic.background.divider.into(), + }, + shadow: Shadow::default(), + icon_color: Some(cosmic.background.on.into()), + } + }, + )), + ) .width(Length::Shrink) .height(Length::Shrink) .align_x(horizontal_align) @@ -306,7 +311,7 @@ pub fn menu_button<'a, Message>( pub fn padded_control<'a, Message>( content: impl Into>, -) -> crate::widget::container::Container<'a, Message, crate::Renderer> { +) -> crate::widget::container::Container<'a, Message, crate::Theme, crate::Renderer> { crate::widget::container(content) .padding(menu_control_padding()) .width(Length::Fill) diff --git a/src/ext.rs b/src/ext.rs index f182371f..beb18c56 100644 --- a/src/ext.rs +++ b/src/ext.rs @@ -20,7 +20,8 @@ impl<'a, Message: 'static> ElementExt for crate::Element<'a, Message> { } /// Additional methods for the [`Column`] and [`Row`] widgets. -pub trait CollectionWidget<'a, Message: 'a>: Widget +pub trait CollectionWidget<'a, Message: 'a>: + Widget where Self: Sized, { diff --git a/src/keyboard_nav.rs b/src/keyboard_nav.rs index 32bea5b2..eed4f84c 100644 --- a/src/keyboard_nav.rs +++ b/src/keyboard_nav.rs @@ -3,12 +3,9 @@ //! Subscribe to common application keyboard shortcuts. -use iced::{ - event, - keyboard::{self, KeyCode}, - mouse, Command, Event, Subscription, -}; +use iced::{event, keyboard, mouse, Command, Event, Subscription}; use iced_core::{ + keyboard::key::Named, widget::{operation, Id, Operation}, Rectangle, }; @@ -32,10 +29,11 @@ pub fn subscription() -> Subscription { match event { Event::Keyboard(keyboard::Event::KeyPressed { - key_code, + key: keyboard::Key::Named(key), modifiers, - }) => match key_code { - KeyCode::Tab => { + .. + }) => match key { + Named::Tab => { return Some(if modifiers.shift() { Message::FocusPrevious } else { @@ -43,24 +41,23 @@ pub fn subscription() -> Subscription { }); } - KeyCode::Escape => { + Named::Escape => { return Some(Message::Escape); } - KeyCode::F11 => { + Named::F11 => { return Some(Message::Fullscreen); } - KeyCode::F => { - return if modifiers.control() { - Some(Message::Search) - } else { - None - }; - } - _ => (), }, + Event::Keyboard(keyboard::Event::KeyPressed { + key: keyboard::Key::Character(c), + modifiers, + .. + }) if c == "f" && modifiers.control() => { + return Some(Message::Search); + } Event::Mouse(mouse::Event::ButtonPressed { .. }) => { return Some(Message::Unfocus); diff --git a/src/lib.rs b/src/lib.rs index 2f22aac1..abb49e30 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -69,5 +69,5 @@ pub use theme::{style, Theme}; pub mod widget; type Paragraph = ::Paragraph; -pub type Renderer = iced::Renderer; -pub type Element<'a, Message> = iced::Element<'a, Message, Renderer>; +pub type Renderer = iced::Renderer; +pub type Element<'a, Message> = iced::Element<'a, Message, crate::Theme, Renderer>; diff --git a/src/theme/style/iced.rs b/src/theme/style/iced.rs index 7a307588..18eda420 100644 --- a/src/theme/style/iced.rs +++ b/src/theme/style/iced.rs @@ -5,9 +5,7 @@ use crate::theme::{CosmicComponent, Theme, TRANSPARENT_COMPONENT}; use cosmic_theme::composite::over; -use iced_core::gradient::Linear; -use iced_core::BorderRadius; -use iced_core::Radians; +use iced_core::Border; use iced_core::{Background, Color}; use iced_style::application; use iced_style::button as iced_button; @@ -25,7 +23,7 @@ use iced_style::slider::Rail; use iced_style::svg; use iced_style::text_input; use iced_style::toggler; -use std::f32::consts::PI; + use std::rc::Rc; #[derive(Default)] @@ -203,14 +201,17 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.accent.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.accent.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.accent.base + } else { + cosmic.button.border + } + .into(), + }, + text_color: None, }, Checkbox::Secondary => checkbox::Appearance { @@ -220,9 +221,11 @@ impl checkbox::StyleSheet for Theme { cosmic.background.base.into() }), icon_color: cosmic.background.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: cosmic.button.border.into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: cosmic.button.border.into(), + }, text_color: None, }, Checkbox::Success => checkbox::Appearance { @@ -232,14 +235,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.success.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.success.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.success.base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, Checkbox::Danger => checkbox::Appearance { @@ -249,14 +254,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.destructive.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.destructive.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.destructive.base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, } @@ -274,14 +281,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.accent.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.accent.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.accent.base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, Checkbox::Secondary => checkbox::Appearance { @@ -291,14 +300,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: self.current_container().on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - self.current_container().base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + self.current_container().base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, Checkbox::Success => checkbox::Appearance { @@ -308,14 +319,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.success.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.success.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.success.base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, Checkbox::Danger => checkbox::Appearance { @@ -325,14 +338,16 @@ impl checkbox::StyleSheet for Theme { cosmic.button.base.into() }), icon_color: cosmic.destructive.on.into(), - border_radius: corners.radius_xs.into(), - border_width: if is_checked { 0.0 } else { 1.0 }, - border_color: if is_checked { - cosmic.destructive.base - } else { - cosmic.button.border - } - .into(), + border: Border { + radius: corners.radius_xs.into(), + width: if is_checked { 0.0 } else { 1.0 }, + color: if is_checked { + cosmic.destructive.base + } else { + cosmic.button.border + } + .into(), + }, text_color: None, }, } @@ -371,61 +386,50 @@ impl container::StyleSheet for Theme { match style { Container::Transparent => container::Appearance::default(), Container::Custom(f) => f(self), - Container::Background => { - let palette = self.cosmic(); - - container::Appearance { - icon_color: Some(Color::from(palette.background.on)), - text_color: Some(Color::from(palette.background.on)), - background: Some(iced::Background::Color(palette.background.base.into())), - border_radius: cosmic.corner_radii.radius_xs.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - } + Container::Background => container::Appearance { + icon_color: Some(Color::from(cosmic.background.on)), + text_color: Some(Color::from(cosmic.background.on)), + background: Some(iced::Background::Color(cosmic.background.base.into())), + border: Border { + radius: cosmic.corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Default::default(), + }, Container::HeaderBar => { - let palette = self.cosmic(); - let header_top = palette.background.base; + let header_top = cosmic.background.base; container::Appearance { - icon_color: Some(Color::from(palette.accent.base)), - text_color: Some(Color::from(palette.background.on)), + icon_color: Some(Color::from(cosmic.accent.base)), + text_color: Some(Color::from(cosmic.background.on)), background: Some(iced::Background::Color(header_top.into())), - border_radius: BorderRadius::from([ - palette.corner_radii.radius_xs[0], - palette.corner_radii.radius_xs[3], - 0.0, - 0.0, - ]), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Default::default(), } } - Container::Primary => { - let palette = self.cosmic(); - - container::Appearance { - icon_color: Some(Color::from(palette.primary.on)), - text_color: Some(Color::from(palette.primary.on)), - background: Some(iced::Background::Color(palette.primary.base.into())), - border_radius: cosmic.corner_radii.radius_xs.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - } - Container::Secondary => { - let palette = self.cosmic(); - - container::Appearance { - icon_color: Some(Color::from(palette.secondary.on)), - text_color: Some(Color::from(palette.secondary.on)), - background: Some(iced::Background::Color(palette.secondary.base.into())), - border_radius: cosmic.corner_radii.radius_xs.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, - } - } - + Container::Primary => container::Appearance { + icon_color: Some(Color::from(cosmic.primary.on)), + text_color: Some(Color::from(cosmic.primary.on)), + background: Some(iced::Background::Color(cosmic.primary.base.into())), + border: Border { + radius: cosmic.corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Default::default(), + }, + Container::Secondary => container::Appearance { + icon_color: Some(Color::from(cosmic.secondary.on)), + text_color: Some(Color::from(cosmic.secondary.on)), + background: Some(iced::Background::Color(cosmic.secondary.base.into())), + border: Border { + radius: cosmic.corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Default::default(), + }, Container::Dropdown => { let theme = self.cosmic(); @@ -433,58 +437,63 @@ impl container::StyleSheet for Theme { icon_color: None, text_color: None, background: Some(iced::Background::Color(theme.primary.base.into())), - border_radius: theme.corner_radii.radius_xs.into(), - border_width: 1.0, - border_color: theme.bg_divider().into(), - } - } - - Container::Tooltip => { - let theme = self.cosmic(); - - container::Appearance { - icon_color: None, - text_color: None, - background: Some(iced::Background::Color(theme.palette.neutral_2.into())), - border_radius: theme.corner_radii.radius_l.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_xs.into(), + ..Default::default() + }, + shadow: Default::default(), } } + Container::Tooltip => container::Appearance { + icon_color: None, + text_color: None, + background: Some(iced::Background::Color(cosmic.palette.neutral_2.into())), + border: Border { + radius: cosmic.corner_radii.radius_l.into(), + ..Default::default() + }, + shadow: Default::default(), + }, Container::Card => { - let palette = self.cosmic(); + let cosmic = self.cosmic(); match self.layer { cosmic_theme::Layer::Background => container::Appearance { - icon_color: Some(Color::from(palette.background.component.on)), - text_color: Some(Color::from(palette.background.component.on)), + icon_color: Some(Color::from(cosmic.background.component.on)), + text_color: Some(Color::from(cosmic.background.component.on)), background: Some(iced::Background::Color( - palette.background.component.base.into(), + cosmic.background.component.base.into(), )), - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, + shadow: Default::default(), }, cosmic_theme::Layer::Primary => container::Appearance { - icon_color: Some(Color::from(palette.primary.component.on)), - text_color: Some(Color::from(palette.primary.component.on)), + icon_color: Some(Color::from(cosmic.primary.component.on)), + text_color: Some(Color::from(cosmic.primary.component.on)), background: Some(iced::Background::Color( - palette.primary.component.base.into(), + cosmic.primary.component.base.into(), )), - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, + shadow: Default::default(), }, cosmic_theme::Layer::Secondary => container::Appearance { - icon_color: Some(Color::from(palette.secondary.component.on)), - text_color: Some(Color::from(palette.secondary.component.on)), + icon_color: Some(Color::from(cosmic.secondary.component.on)), + text_color: Some(Color::from(cosmic.secondary.component.on)), background: Some(iced::Background::Color( - palette.secondary.component.base.into(), + cosmic.secondary.component.base.into(), )), - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, + shadow: Default::default(), }, } } @@ -581,9 +590,10 @@ impl menu::StyleSheet for Theme { menu::Appearance { text_color: cosmic.on_bg_color().into(), background: Background::Color(cosmic.background.base.into()), - border_width: 0.0, - border_radius: cosmic.corner_radii.radius_m.into(), - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_m.into(), + ..Default::default() + }, selected_text_color: cosmic.accent.base.into(), selected_background: Background::Color(cosmic.background.component.hover.into()), } @@ -603,9 +613,10 @@ impl pick_list::StyleSheet for Theme { text_color: cosmic.on_bg_color().into(), background: Color::TRANSPARENT.into(), placeholder_color: cosmic.on_bg_color().into(), - border_radius: cosmic.corner_radii.radius_m.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_m.into(), + ..Default::default() + }, // icon_size: 0.7, // TODO: how to replace handle_color: cosmic.on_bg_color().into(), } @@ -740,9 +751,11 @@ impl pane_grid::StyleSheet for Theme { let theme = self.cosmic(); pane_grid::Appearance { background: Background::Color(theme.bg_color().into()), - border_width: 2.0, - border_color: theme.bg_divider().into(), - border_radius: theme.corner_radii.radius_0.into(), + border: Border { + radius: theme.corner_radii.radius_0.into(), + width: 2.0, + color: theme.bg_divider().into(), + }, } } } @@ -857,14 +870,16 @@ impl scrollable::StyleSheet for Theme { neutral_5.alpha = 0.7; let mut a = scrollable::Scrollbar { background: None, - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, scroller: scrollable::Scroller { color: neutral_5.into(), - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, }, }; @@ -889,14 +904,16 @@ impl scrollable::StyleSheet for Theme { } let mut a = scrollable::Scrollbar { background: None, - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, scroller: scrollable::Scroller { color: neutral_5.into(), - border_radius: cosmic.corner_radii.radius_s.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: cosmic.corner_radii.radius_s.into(), + ..Default::default() + }, }, }; if matches!(style, Scrollable::Permanent) { @@ -934,6 +951,10 @@ impl svg::StyleSheet for Theme { Svg::Custom(appearance) => appearance(self), } } + + fn hovered(&self, style: &Self::Style) -> svg::Appearance { + self.appearance(style) + } } /* @@ -990,16 +1011,19 @@ impl text_input::StyleSheet for Theme { match style { TextInput::Default => text_input::Appearance { background: Color::from(bg).into(), - border_radius: palette.corner_radii.radius_s.into(), - border_width: 1.0, - border_color: self.current_container().component.divider.into(), + border: Border { + radius: palette.corner_radii.radius_s.into(), + width: 1.0, + 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: palette.corner_radii.radius_m.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: palette.corner_radii.radius_m.into(), + ..Default::default() + }, icon_color: self.current_container().on.into(), }, } @@ -1013,16 +1037,19 @@ impl text_input::StyleSheet for Theme { match style { TextInput::Default => text_input::Appearance { background: Color::from(bg).into(), - border_radius: palette.corner_radii.radius_s.into(), - border_width: 1.0, - border_color: palette.accent.base.into(), + border: Border { + radius: palette.corner_radii.radius_s.into(), + width: 1.0, + color: self.current_container().on.into(), + }, icon_color: self.current_container().on.into(), }, TextInput::Search => text_input::Appearance { background: Color::from(bg).into(), - border_radius: palette.corner_radii.radius_m.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: palette.corner_radii.radius_m.into(), + ..Default::default() + }, icon_color: self.current_container().on.into(), }, } @@ -1036,16 +1063,19 @@ impl text_input::StyleSheet for Theme { match style { TextInput::Default => text_input::Appearance { background: Color::from(bg).into(), - border_radius: palette.corner_radii.radius_s.into(), - border_width: 1.0, - border_color: palette.accent.base.into(), + border: Border { + radius: palette.corner_radii.radius_s.into(), + width: 1.0, + color: palette.accent.base.into(), + }, icon_color: self.current_container().on.into(), }, TextInput::Search => text_input::Appearance { background: Color::from(bg).into(), - border_radius: palette.corner_radii.radius_m.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: palette.corner_radii.radius_m.into(), + ..Default::default() + }, icon_color: self.current_container().on.into(), }, } @@ -1121,9 +1151,11 @@ impl iced_style::text_editor::StyleSheet for Theme { let cosmic = self.cosmic(); iced_style::text_editor::Appearance { background: iced::Color::from(cosmic.bg_color()).into(), - border_radius: cosmic.corner_radii.radius_0.into(), - border_width: f32::from(cosmic.space_xxxs()), - border_color: iced::Color::from(cosmic.bg_divider()), + border: Border { + radius: cosmic.corner_radii.radius_0.into(), + width: f32::from(cosmic.space_xxxs()), + color: iced::Color::from(cosmic.bg_divider()), + }, } } @@ -1135,9 +1167,11 @@ impl iced_style::text_editor::StyleSheet for Theme { let cosmic = self.cosmic(); iced_style::text_editor::Appearance { background: iced::Color::from(cosmic.bg_color()).into(), - border_radius: cosmic.corner_radii.radius_0.into(), - border_width: f32::from(cosmic.space_xxxs()), - border_color: iced::Color::from(cosmic.accent.base), + border: Border { + radius: cosmic.corner_radii.radius_0.into(), + width: f32::from(cosmic.space_xxxs()), + color: iced::Color::from(cosmic.accent.base), + }, } } diff --git a/src/theme/style/segmented_button.rs b/src/theme/style/segmented_button.rs index 8d6b2c12..c3c87a64 100644 --- a/src/theme/style/segmented_button.rs +++ b/src/theme/style/segmented_button.rs @@ -5,7 +5,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::{border::Radius, Background}; #[derive(Default)] pub enum SegmentedButton { @@ -66,9 +66,7 @@ impl StyleSheet for Theme { inactive: ItemStatusAppearance { background: Some(Background::Color(neutral_5.into())), first: ItemAppearance { - border_radius: BorderRadius::from([ - rad_m[0], rad_0[1], rad_0[2], rad_m[3], - ]), + border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]), ..Default::default() }, middle: ItemAppearance { @@ -76,9 +74,7 @@ impl StyleSheet for Theme { ..Default::default() }, last: ItemAppearance { - border_radius: BorderRadius::from([ - rad_0[0], rad_m[1], rad_m[2], rad_0[3], - ]), + border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]), ..Default::default() }, text_color: cosmic.on_bg_color().into(), @@ -123,9 +119,7 @@ impl StyleSheet for Theme { inactive: ItemStatusAppearance { background: Some(Background::Color(neutral_5.into())), first: ItemAppearance { - border_radius: BorderRadius::from([ - rad_m[0], rad_m[1], rad_0[0], rad_0[0], - ]), + border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[0], rad_0[0]]), ..Default::default() }, middle: ItemAppearance { @@ -133,9 +127,7 @@ impl StyleSheet for Theme { ..Default::default() }, last: ItemAppearance { - border_radius: BorderRadius::from([ - rad_0[0], rad_0[1], rad_m[2], rad_m[3], - ]), + border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]), ..Default::default() }, text_color: cosmic.on_bg_color().into(), @@ -153,7 +145,7 @@ impl StyleSheet for Theme { mod horizontal { use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance}; - use iced_core::{Background, BorderRadius}; + use iced_core::{border::Radius, Background}; pub fn selection_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance { let mut neutral_5 = cosmic.palette.neutral_5; @@ -163,7 +155,7 @@ mod horizontal { ItemStatusAppearance { background: Some(Background::Color(neutral_5.into())), first: ItemAppearance { - border_radius: BorderRadius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]), + border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]), ..Default::default() }, middle: ItemAppearance { @@ -171,7 +163,7 @@ mod horizontal { ..Default::default() }, last: ItemAppearance { - border_radius: BorderRadius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]), + border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]), ..Default::default() }, text_color: cosmic.accent.base.into(), @@ -186,17 +178,17 @@ mod horizontal { ItemStatusAppearance { background: Some(Background::Color(neutral_5.into())), first: ItemAppearance { - border_radius: BorderRadius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), + border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), border_bottom: Some((4.0, cosmic.accent.base.into())), ..Default::default() }, middle: ItemAppearance { - border_radius: BorderRadius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), + border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), border_bottom: Some((4.0, cosmic.accent.base.into())), ..Default::default() }, last: ItemAppearance { - border_radius: BorderRadius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), + border_radius: Radius::from([rad_s[0], rad_s[1], rad_0[2], rad_0[3]]), border_bottom: Some((4.0, cosmic.accent.base.into())), ..Default::default() }, @@ -229,7 +221,7 @@ pub fn hover(cosmic: &cosmic_theme::Theme, default: &ItemStatusAppearance) -> It mod vertical { use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance}; - use iced_core::{Background, BorderRadius}; + use iced_core::{border::Radius, Background}; pub fn selection_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance { let mut neutral_5 = cosmic.palette.neutral_5; @@ -239,7 +231,7 @@ mod vertical { ItemStatusAppearance { background: Some(Background::Color(neutral_5.into())), first: ItemAppearance { - border_radius: BorderRadius::from([rad_m[0], rad_m[1], rad_0[2], rad_0[3]]), + border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[2], rad_0[3]]), ..Default::default() }, middle: ItemAppearance { @@ -247,7 +239,7 @@ mod vertical { ..Default::default() }, last: ItemAppearance { - border_radius: BorderRadius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]), + border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]), ..Default::default() }, text_color: cosmic.accent.base.into(), diff --git a/src/widget/aspect_ratio.rs b/src/widget/aspect_ratio.rs index 471cfaaf..32ef16e5 100644 --- a/src/widget/aspect_ratio.rs +++ b/src/widget/aspect_ratio.rs @@ -16,7 +16,7 @@ pub fn aspect_ratio_container<'a, Message: 'static, T>( ratio: f32, ) -> AspectRatio<'a, Message, crate::Renderer> where - T: Into>, + T: Into>, { AspectRatio::new(content, ratio) } @@ -28,16 +28,14 @@ where pub struct AspectRatio<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { ratio: f32, - container: Container<'a, Message, Renderer>, + container: Container<'a, Message, crate::Theme, Renderer>, } impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { fn constrain_limits(&self, size: Size) -> Size { let Size { @@ -56,12 +54,11 @@ where impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { /// Creates an empty [`Container`]. pub(crate) fn new(content: T, ratio: f32) -> Self where - T: Into>, + T: Into>, { AspectRatio { ratio, @@ -134,16 +131,16 @@ where /// Sets the style of the [`Container`]. #[must_use] - pub fn style(mut self, style: impl Into<::Style>) -> Self { + pub fn style(mut self, style: impl Into<::Style>) -> Self { self.container = self.container.style(style); self } } -impl<'a, Message, Renderer> Widget for AspectRatio<'a, Message, Renderer> +impl<'a, Message, Renderer> Widget + for AspectRatio<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { fn children(&self) -> Vec { self.container.children() @@ -153,12 +150,8 @@ where self.container.diff(tree); } - fn width(&self) -> Length { - Widget::width(&self.container) - } - - fn height(&self) -> Length { - Widget::height(&self.container) + fn size(&self) -> Size { + self.container.size() } fn layout( @@ -226,7 +219,7 @@ where &self, tree: &Tree, renderer: &mut Renderer, - theme: &Renderer::Theme, + theme: &crate::Theme, renderer_style: &renderer::Style, layout: Layout<'_>, cursor_position: mouse::Cursor, @@ -248,19 +241,20 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, - ) -> Option> { + ) -> Option> { self.container.overlay(tree, layout, renderer) } } impl<'a, Message, Renderer> From> - for Element<'a, Message, Renderer> + for Element<'a, Message, crate::Theme, Renderer> where Message: 'a, Renderer: 'a + iced_core::Renderer, - Renderer::Theme: StyleSheet, { - fn from(column: AspectRatio<'a, Message, Renderer>) -> Element<'a, Message, Renderer> { + fn from( + column: AspectRatio<'a, Message, Renderer>, + ) -> Element<'a, Message, crate::Theme, Renderer> { Element::new(column) } } diff --git a/src/widget/button/style.rs b/src/widget/button/style.rs index 88a22539..9cda41e9 100644 --- a/src/widget/button/style.rs +++ b/src/widget/button/style.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MPL-2.0 //! Change the apperance of a button. -use iced_core::{Background, BorderRadius, Color, Vector}; +use iced_core::{border::Radius, Background, Color, Vector}; use crate::theme::THEME; @@ -17,7 +17,7 @@ pub struct Appearance { pub background: Option, /// The border radius of the button. - pub border_radius: BorderRadius, + pub border_radius: Radius, /// The border width of the button. pub border_width: f32, @@ -39,13 +39,13 @@ pub struct Appearance { } impl Appearance { - // TODO: `BorderRadius` is not `const fn` compatible. + // TODO: `Radius` is not `const fn` compatible. pub fn new() -> Self { let rad_0 = THEME.with(|t| t.borrow().cosmic().corner_radii.radius_0); Self { shadow_offset: Vector::new(0.0, 0.0), background: None, - border_radius: BorderRadius::from(rad_0), + border_radius: Radius::from(rad_0), border_width: 0.0, border_color: Color::TRANSPARENT, outline_width: 0.0, diff --git a/src/widget/button/widget.rs b/src/widget/button/widget.rs index 7e5e301b..ffc94c3f 100644 --- a/src/widget/button/widget.rs +++ b/src/widget/button/widget.rs @@ -10,13 +10,13 @@ use iced_runtime::core::widget::Id; use iced_runtime::{keyboard, Command}; use iced_core::event::{self, Event}; -use iced_core::mouse; -use iced_core::overlay; use iced_core::renderer::{self, Quad}; use iced_core::touch; use iced_core::widget::tree::{self, Tree}; use iced_core::widget::Operation; use iced_core::{layout, svg}; +use iced_core::{mouse, Border}; +use iced_core::{overlay, Shadow}; use iced_core::{ Background, Clipboard, Color, Element, Layout, Length, Padding, Point, Rectangle, Shell, Vector, Widget, @@ -43,7 +43,6 @@ enum Variant { pub struct Button<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { id: Id, #[cfg(feature = "a11y")] @@ -52,23 +51,22 @@ where description: Option>, #[cfg(feature = "a11y")] label: Option>, - content: Element<'a, Message, Renderer>, + content: Element<'a, Message, crate::Theme, Renderer>, on_press: Option, width: Length, height: Length, padding: Padding, selected: bool, - style: ::Style, + style: ::Style, variant: Variant, } impl<'a, Message, Renderer> Button<'a, Message, Renderer> where Renderer: iced_core::Renderer, - Renderer::Theme: StyleSheet, { /// Creates a new [`Button`] with the given content. - pub fn new(content: impl Into>) -> Self { + pub fn new(content: impl Into>) -> Self { Self { id: Id::unique(), #[cfg(feature = "a11y")] @@ -83,13 +81,13 @@ where height: Length::Shrink, padding: Padding::new(5.0), selected: false, - style: ::Style::default(), + style: ::Style::default(), variant: Variant::Normal, } } pub fn new_image( - content: impl Into>, + content: impl Into>, on_remove: Option, ) -> Self { Self { @@ -106,7 +104,7 @@ where height: Length::Shrink, padding: Padding::new(5.0), selected: false, - style: ::Style::default(), + style: ::Style::default(), variant: Variant::Image { on_remove, close_icon: crate::widget::icon::from_name("window-close-symbolic") @@ -180,7 +178,7 @@ where } /// Sets the style variant of this [`Button`]. - pub fn style(mut self, style: ::Style) -> Self { + pub fn style(mut self, style: ::Style) -> Self { self.style = style; self } @@ -216,11 +214,11 @@ where } } -impl<'a, Message, Renderer> Widget for Button<'a, Message, Renderer> +impl<'a, Message, Renderer> Widget + for Button<'a, Message, Renderer> where Message: 'a + Clone, Renderer: 'a + iced_core::Renderer + svg::Renderer, - Renderer::Theme: StyleSheet, { fn tag(&self) -> tree::Tag { tree::Tag::of::() @@ -238,12 +236,8 @@ where tree.diff_children(std::slice::from_mut(&mut self.content)); } - fn width(&self) -> Length { - self.width - } - - fn height(&self) -> Length { - self.height + fn size(&self) -> iced_core::Size { + iced_core::Size::new(self.width, self.height) } fn layout( @@ -346,7 +340,7 @@ where &self, tree: &Tree, renderer: &mut Renderer, - theme: &Renderer::Theme, + theme: &crate::Theme, renderer_style: &renderer::Style, layout: Layout<'_>, cursor: mouse::Cursor, @@ -400,15 +394,17 @@ where x: bounds.x + styling.border_width, y: bounds.y + (bounds.height - 20.0 - styling.border_width), }, - border_radius: [ - c_rad.radius_0[0], - c_rad.radius_s[1], - c_rad.radius_0[2], - c_rad.radius_s[3], - ] - .into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + border: Border { + radius: [ + c_rad.radius_0[0], + c_rad.radius_s[1], + c_rad.radius_0[2], + c_rad.radius_s[3], + ] + .into(), + ..Default::default() + }, + shadow: Default::default(), }, selection_background, ); @@ -433,9 +429,11 @@ where renderer.fill_quad( renderer::Quad { bounds, - border_radius: c_rad.radius_m.into(), - border_width: 0.0, - border_color: Color::TRANSPARENT, + shadow: Default::default(), + border: Border { + radius: c_rad.radius_m.into(), + ..Default::default() + }, }, selection_background, ); @@ -473,7 +471,7 @@ where tree: &'b mut Tree, layout: Layout<'_>, renderer: &Renderer, - ) -> Option> { + ) -> Option> { self.content.as_widget_mut().overlay( &mut tree.children[0], layout.children().next().unwrap(), @@ -556,11 +554,11 @@ where } } -impl<'a, Message, Renderer> From> for Element<'a, Message, Renderer> +impl<'a, Message, Renderer> From> + for Element<'a, Message, crate::Theme, Renderer> where Message: Clone + 'a, Renderer: iced_core::Renderer + svg::Renderer + 'a, - Renderer::Theme: StyleSheet, { fn from(button: Button<'a, Message, Renderer>) -> Self { Self::new(button) @@ -660,10 +658,10 @@ pub fn update<'a, Message: Clone>( } return event::Status::Captured; } - Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. }) => { + Event::Keyboard(keyboard::Event::KeyPressed { key, .. }) => { if let Some(on_press) = on_press.clone() { let state = state(); - if state.is_focused && key_code == keyboard::KeyCode::Enter { + if state.is_focused && key == keyboard::Key::Named(keyboard::key::Named::Enter) { state.is_pressed = true; shell.publish(on_press); return event::Status::Captured; @@ -688,13 +686,12 @@ pub fn draw<'a, Renderer: iced_core::Renderer>( cursor: mouse::Cursor, is_enabled: bool, is_selected: bool, - style_sheet: &dyn StyleSheet