wip: update to use latest iced

This commit is contained in:
Ashley Wulber 2024-01-30 22:14:00 -05:00 committed by Ashley Wulber
parent ca1469a6b2
commit f4ad098647
49 changed files with 956 additions and 854 deletions

View file

@ -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"

View file

@ -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"] }

2
iced

@ -1 +1 @@
Subproject commit 6115280d5277c50b8539d4eff6ab61050c51b592
Subproject commit 32a0efcd05e827ba3ad9913e50dd103510e8bca7

View file

@ -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<Self::Message>) {
#[cfg(feature = "dbus-config")]
{
use iced_futures::futures::executor::block_on;
core.settings_daemon = block_on(cosmic_config::dbus::settings_daemon_proxy()).ok();
}

View file

@ -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<Element<'a, Message>>,
) -> 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::<Message, Renderer>::new(Container::<Message, Renderer>::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::<Message, _, Renderer>::new(
Container::<Message, _, Renderer>::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<Element<'a, Message>>,
) -> 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)

View file

@ -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<Message, crate::Renderer>
pub trait CollectionWidget<'a, Message: 'a>:
Widget<Message, crate::Theme, crate::Renderer>
where
Self: Sized,
{

View file

@ -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<Message> {
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<Message> {
});
}
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);

View file

@ -69,5 +69,5 @@ pub use theme::{style, Theme};
pub mod widget;
type Paragraph = <Renderer as iced_core::text::Renderer>::Paragraph;
pub type Renderer = iced::Renderer<Theme>;
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>;

View file

@ -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),
},
}
}

View file

@ -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(),

View file

@ -16,7 +16,7 @@ pub fn aspect_ratio_container<'a, Message: 'static, T>(
ratio: f32,
) -> AspectRatio<'a, Message, crate::Renderer>
where
T: Into<Element<'a, Message, crate::Renderer>>,
T: Into<Element<'a, Message, crate::Theme, crate::Renderer>>,
{
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<T>(content: T, ratio: f32) -> Self
where
T: Into<Element<'a, Message, Renderer>>,
T: Into<Element<'a, Message, crate::Theme, Renderer>>,
{
AspectRatio {
ratio,
@ -134,16 +131,16 @@ where
/// Sets the style of the [`Container`].
#[must_use]
pub fn style(mut self, style: impl Into<<Renderer::Theme as StyleSheet>::Style>) -> Self {
pub fn style(mut self, style: impl Into<<crate::Theme as StyleSheet>::Style>) -> Self {
self.container = self.container.style(style);
self
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for AspectRatio<'a, Message, Renderer>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer>
for AspectRatio<'a, Message, Renderer>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{
fn children(&self) -> Vec<Tree> {
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<Length> {
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<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.container.overlay(tree, layout, renderer)
}
}
impl<'a, Message, Renderer> From<AspectRatio<'a, Message, Renderer>>
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)
}
}

View file

@ -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<Background>,
/// 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,

View file

@ -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<Message> {
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<iced_accessibility::Description<'a>>,
#[cfg(feature = "a11y")]
label: Option<Vec<iced_accessibility::accesskit::NodeId>>,
content: Element<'a, Message, Renderer>,
content: Element<'a, Message, crate::Theme, Renderer>,
on_press: Option<Message>,
width: Length,
height: Length,
padding: Padding,
selected: bool,
style: <Renderer::Theme as StyleSheet>::Style,
style: <crate::Theme as StyleSheet>::Style,
variant: Variant<Message>,
}
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<Element<'a, Message, Renderer>>) -> Self {
pub fn new(content: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self {
Self {
id: Id::unique(),
#[cfg(feature = "a11y")]
@ -83,13 +81,13 @@ where
height: Length::Shrink,
padding: Padding::new(5.0),
selected: false,
style: <Renderer::Theme as StyleSheet>::Style::default(),
style: <crate::Theme as StyleSheet>::Style::default(),
variant: Variant::Normal,
}
}
pub fn new_image(
content: impl Into<Element<'a, Message, Renderer>>,
content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
on_remove: Option<Message>,
) -> Self {
Self {
@ -106,7 +104,7 @@ where
height: Length::Shrink,
padding: Padding::new(5.0),
selected: false,
style: <Renderer::Theme as StyleSheet>::Style::default(),
style: <crate::Theme as StyleSheet>::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: <Renderer::Theme as StyleSheet>::Style) -> Self {
pub fn style(mut self, style: <crate::Theme as StyleSheet>::Style) -> Self {
self.style = style;
self
}
@ -216,11 +214,11 @@ where
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for Button<'a, Message, Renderer>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer>
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::<State>()
@ -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<Length> {
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<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.content.as_widget_mut().overlay(
&mut tree.children[0],
layout.children().next().unwrap(),
@ -556,11 +554,11 @@ where
}
}
impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>> for Element<'a, Message, Renderer>
impl<'a, Message, Renderer> From<Button<'a, Message, Renderer>>
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<Style = <Renderer::Theme as StyleSheet>::Style>,
style: &<Renderer::Theme as StyleSheet>::Style,
style_sheet: &dyn StyleSheet<Style = <crate::Theme as StyleSheet>::Style>,
style: &<crate::Theme as StyleSheet>::Style,
state: impl FnOnce() -> &'a State,
draw_contents: impl FnOnce(&mut Renderer, Appearance),
) -> Appearance
where
Renderer::Theme: StyleSheet,
{
let is_mouse_over = cursor.position().is_some_and(|p| bounds.contains(p));
@ -724,9 +721,12 @@ where
width: bounds.width + doubled_border_width + doubled_outline_width,
height: bounds.height + doubled_border_width + doubled_outline_width,
},
border_radius: styling.border_radius,
border_width: styling.outline_width,
border_color: styling.outline_color,
border: Border {
width: styling.outline_width,
color: styling.outline_color,
radius: styling.border_radius,
},
shadow: Default::default(),
},
Color::TRANSPARENT,
);
@ -743,9 +743,11 @@ where
width: bounds.width,
height: bounds.height,
},
border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: styling.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
Background::Color([0.0, 0.0, 0.0, 0.5].into()),
);
@ -756,9 +758,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: styling.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: styling.border_radius,
..Default::default()
},
shadow: Default::default(),
},
background,
);
@ -771,9 +775,12 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: styling.border_radius,
border_width: styling.border_width,
border_color: styling.border_color,
border: Border {
width: styling.border_width,
color: styling.border_color,
radius: styling.border_radius,
},
shadow: Default::default(),
},
Color::TRANSPARENT,
);
@ -795,11 +802,14 @@ pub fn layout<Renderer>(
) -> layout::Node {
let limits = limits.width(width).height(height);
let mut content = layout_content(renderer, &limits.pad(padding));
let mut content = layout_content(renderer, &limits.shrink(padding));
let padding = padding.fit(content.size(), limits.max());
let size = limits.pad(padding).resolve(content.size()).pad(padding);
let size = limits
.shrink(padding)
.resolve(width, height, content.size())
.expand(padding);
content.move_to(Point::new(padding.left, padding.top));
content = content.move_to(Point::new(padding.left, padding.top));
layout::Node::with_children(size, vec![content])
}

View file

@ -17,8 +17,8 @@ use iced_core::gradient::{ColorStop, Linear};
use iced_core::renderer::Quad;
use iced_core::widget::{tree, Tree};
use iced_core::{
layout, mouse, renderer, Background, Clipboard, Color, Layout, Length, Radians, Rectangle,
Renderer, Shell, Vector, Widget,
layout, mouse, renderer, Background, Border, Clipboard, Color, Layout, Length, Radians,
Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
};
use iced_style::slider::{HandleShape, RailBackground};
@ -414,7 +414,7 @@ where
)
.into()
})
.collect(),
.collect::<Vec<_>>(),
)
.spacing(spacing.space_xxs),
)
@ -487,7 +487,7 @@ pub struct ColorPicker<'a, Message> {
must_clear_cache: Rc<AtomicBool>,
}
impl<'a, Message> Widget<Message, crate::Renderer> for ColorPicker<'a, Message>
impl<'a, Message> Widget<Message, crate::Theme, crate::Renderer> for ColorPicker<'a, Message>
where
Message: Clone + 'static,
{
@ -507,14 +507,6 @@ where
vec![Tree::new(&self.inner)]
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
}
fn layout(
&self,
tree: &mut Tree,
@ -531,7 +523,7 @@ where
&self,
tree: &Tree,
renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme,
theme: &crate::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor: mouse::Cursor,
@ -611,9 +603,12 @@ where
width: handle_radius.mul_add(2.0, 1.0),
height: handle_radius.mul_add(2.0, 1.0),
},
border_radius: (1.0 + handle_radius).into(),
border_width: 1.0,
border_color: t.palette.neutral_5.into(),
border: Border {
width: 1.0,
color: t.palette.neutral_5.into(),
radius: (1.0 + handle_radius).into(),
},
shadow: Shadow::default(),
},
Color::TRANSPARENT,
);
@ -625,9 +620,12 @@ where
width: handle_radius * 2.0,
height: handle_radius * 2.0,
},
border_radius: handle_radius.into(),
border_width: 1.0,
border_color: t.palette.neutral_10.into(),
border: Border {
width: 1.0,
color: t.palette.neutral_10.into(),
radius: handle_radius.into(),
},
shadow: Shadow::default(),
},
Color::TRANSPARENT,
);
@ -638,7 +636,7 @@ where
state: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
) -> Option<iced_core::overlay::Element<'b, Message, crate::Renderer>> {
) -> Option<iced_core::overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
self.inner
.as_widget_mut()
.overlay(&mut state.children[0], layout, renderer)
@ -723,6 +721,10 @@ where
_ => event::Status::Ignored,
}
}
fn size(&self) -> Size<Length> {
Size::new(self.width, Length::Shrink)
}
}
#[derive(Debug, Default)]
@ -867,11 +869,14 @@ pub fn color_button<'a, Message: 'static>(
})
}
impl<'a, Message> From<ColorPicker<'a, Message>> for iced::Element<'a, Message, crate::Renderer>
impl<'a, Message> From<ColorPicker<'a, Message>>
for iced::Element<'a, Message, crate::Theme, crate::Renderer>
where
Message: 'static + Clone,
{
fn from(picker: ColorPicker<'a, Message>) -> iced::Element<'a, Message, crate::Renderer> {
fn from(
picker: ColorPicker<'a, Message>,
) -> iced::Element<'a, Message, crate::Theme, crate::Renderer> {
Element::new(picker)
}
}

View file

@ -8,7 +8,6 @@ use iced::advanced::widget::{self, Operation, OperationOutputWrapper};
use iced::advanced::{overlay, renderer};
use iced::advanced::{Clipboard, Shell};
use iced::{event, mouse, Event, Point, Rectangle, Size};
use iced_core::Widget;
pub(super) struct Overlay<'a, 'b, Message> {
pub(super) content: &'b mut Element<'a, Message>,
@ -16,7 +15,8 @@ pub(super) struct Overlay<'a, 'b, Message> {
pub(super) width: f32,
}
impl<'a, 'b, Message> overlay::Overlay<Message, crate::Renderer> for Overlay<'a, 'b, Message>
impl<'a, 'b, Message> overlay::Overlay<Message, crate::Theme, crate::Renderer>
for Overlay<'a, 'b, Message>
where
Message: Clone,
{
@ -31,13 +31,13 @@ where
.width(self.width)
.height(bounds.height - 8.0 - position.y);
let mut node = self
let node = self
.content
.as_widget()
.layout(self.tree, renderer, &limits);
let node_size = node.size();
node.move_to(Point {
node.clone().move_to(Point {
x: if bounds.width > node_size.width - 8.0 {
bounds.width - node_size.width - 8.0
} else {
@ -48,9 +48,7 @@ where
} else {
0.0
},
});
node
})
}
fn on_event(
@ -82,7 +80,7 @@ where
layout: Layout<'_>,
cursor: mouse::Cursor,
) {
self.content.draw(
self.content.as_widget().draw(
self.tree,
renderer,
theme,
@ -120,7 +118,7 @@ where
&'c mut self,
layout: Layout<'_>,
renderer: &crate::Renderer,
) -> Option<overlay::Element<'c, Message, crate::Renderer>> {
) -> Option<overlay::Element<'c, Message, crate::Theme, crate::Renderer>> {
self.content
.as_widget_mut()
.overlay(self.tree, layout, renderer)

View file

@ -8,9 +8,9 @@ use crate::{Apply, Element, Renderer, Theme};
use super::overlay::Overlay;
use iced_core::alignment;
use iced_core::event::{self, Event};
use iced_core::widget::{Operation, Tree};
use iced_core::{alignment, Border};
use iced_core::{
layout, mouse, overlay as iced_overlay, renderer, Clipboard, Color, Layout, Length, Padding,
Rectangle, Shell, Widget,
@ -84,9 +84,11 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
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: palette.corner_radii.radius_s.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: palette.corner_radii.radius_s.into(),
..Default::default()
},
..Default::default()
}
}))
.layer(cosmic_theme::Layer::Primary)
@ -105,7 +107,7 @@ impl<'a, Message: Clone + 'static> ContextDrawer<'a, Message> {
}
}
impl<'a, Message: Clone> Widget<Message, Renderer> for ContextDrawer<'a, Message> {
impl<'a, Message: Clone> Widget<Message, crate::Theme, Renderer> for ContextDrawer<'a, Message> {
fn children(&self) -> Vec<Tree> {
vec![Tree::new(&self.content), Tree::new(&self.drawer)]
}
@ -114,12 +116,8 @@ impl<'a, Message: Clone> Widget<Message, Renderer> for ContextDrawer<'a, Message
tree.diff_children(&mut [&mut self.content, &mut self.drawer]);
}
fn width(&self) -> Length {
self.content.as_widget().width()
}
fn height(&self) -> Length {
self.content.as_widget().height()
fn size(&self) -> iced_core::Size<Length> {
self.content.as_widget().size()
}
fn layout(
@ -211,7 +209,7 @@ impl<'a, Message: Clone> Widget<Message, Renderer> for ContextDrawer<'a, Message
tree: &'b mut Tree,
layout: Layout<'_>,
_renderer: &Renderer,
) -> Option<iced_overlay::Element<'b, Message, Renderer>> {
) -> Option<iced_overlay::Element<'b, Message, crate::Theme, Renderer>> {
let bounds = layout.bounds();
Some(iced_overlay::Element::new(

View file

@ -14,7 +14,7 @@ pub fn container<'a, Message: 'static, T>(
content: T,
) -> LayerContainer<'a, Message, crate::Renderer>
where
T: Into<Element<'a, Message, crate::Renderer>>,
T: Into<Element<'a, Message, crate::Theme, crate::Renderer>>,
{
LayerContainer::new(content)
}
@ -26,22 +26,19 @@ where
pub struct LayerContainer<'a, Message, Renderer>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet + Clone + cosmic_theme::LayeredTheme,
{
layer: Option<cosmic_theme::Layer>,
container: Container<'a, Message, Renderer>,
container: Container<'a, Message, crate::Theme, Renderer>,
}
impl<'a, Message, Renderer> LayerContainer<'a, Message, Renderer>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet + Clone + cosmic_theme::LayeredTheme,
<Renderer::Theme as StyleSheet>::Style: std::convert::From<crate::theme::Container>,
{
/// Creates an empty [`Container`].
pub(crate) fn new<T>(content: T) -> Self
where
T: Into<Element<'a, Message, Renderer>>,
T: Into<Element<'a, Message, crate::Theme, Renderer>>,
{
LayerContainer {
layer: None,
@ -125,16 +122,16 @@ where
/// Sets the style of the [`LayerContainer`].
#[must_use]
pub fn style(mut self, style: impl Into<<Renderer::Theme as StyleSheet>::Style>) -> Self {
pub fn style(mut self, style: impl Into<<crate::Theme as StyleSheet>::Style>) -> Self {
self.container = self.container.style(style);
self
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for LayerContainer<'a, Message, Renderer>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer>
for LayerContainer<'a, Message, Renderer>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet + Clone + cosmic_theme::LayeredTheme,
{
fn children(&self) -> Vec<Tree> {
self.container.children()
@ -152,12 +149,8 @@ where
self.container.state()
}
fn width(&self) -> Length {
Widget::width(&self.container)
}
fn height(&self) -> Length {
Widget::height(&self.container)
fn size(&self) -> iced_core::Size<Length> {
self.container.size()
}
fn layout(
@ -220,7 +213,7 @@ where
&self,
tree: &Tree,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &crate::Theme,
renderer_style: &renderer::Style,
layout: Layout<'_>,
cursor_position: mouse::Cursor,
@ -249,19 +242,20 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.container.overlay(tree, layout, renderer)
}
}
impl<'a, Message, Renderer> From<LayerContainer<'a, Message, Renderer>>
for Element<'a, Message, Renderer>
for Element<'a, Message, crate::Theme, Renderer>
where
Message: 'a,
Renderer: 'a + iced_core::Renderer,
Renderer::Theme: StyleSheet + Clone + cosmic_theme::LayeredTheme,
{
fn from(column: LayerContainer<'a, Message, Renderer>) -> Element<'a, Message, Renderer> {
fn from(
column: LayerContainer<'a, Message, Renderer>,
) -> Element<'a, Message, crate::Theme, Renderer> {
Element::new(column)
}
}

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MPL-2.0 AND MIT
//! Change the appearance of menus.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{border::Radius, Background, Color};
/// The appearance of a menu.
#[derive(Debug, Clone, Copy)]
@ -15,7 +15,7 @@ pub struct Appearance {
/// Menu border width
pub border_width: f32,
/// Menu border radius
pub border_radius: BorderRadius,
pub border_radius: Radius,
/// Menu border color
pub border_color: Color,
/// Text color when hovered

View file

@ -13,8 +13,8 @@ use iced_core::layout::{self, Layout};
use iced_core::text::{self, Text};
use iced_core::widget::Tree;
use iced_core::{
alignment, mouse, overlay, renderer, svg, touch, Clipboard, Color, Element, Length, Padding,
Pixels, Point, Rectangle, Renderer, Shell, Size, Vector, Widget,
alignment, mouse, overlay, renderer, svg, touch, Border, Clipboard, Element, Length, Padding,
Pixels, Point, Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
};
use iced_widget::scrollable::Scrollable;
@ -98,7 +98,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Menu<'a, S, Message> {
self,
position: Point,
target_height: f32,
) -> overlay::Element<'a, Message, crate::Renderer> {
) -> overlay::Element<'a, Message, crate::Theme, crate::Renderer> {
overlay::Element::new(position, Box::new(Overlay::new(self, target_height)))
}
}
@ -127,7 +127,7 @@ impl Default for State {
struct Overlay<'a, Message> {
state: &'a mut Tree,
container: Container<'a, Message, crate::Renderer>,
container: Container<'a, Message, crate::Theme, crate::Renderer>,
width: f32,
target_height: f32,
style: (),
@ -174,7 +174,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
.padding(padding)
.style(crate::style::Container::Dropdown);
state.tree.diff(&mut container as &mut dyn Widget<_, _>);
state.tree.diff(&mut container as &mut dyn Widget<_, _, _>);
Self {
state: &mut state.tree,
@ -186,7 +186,9 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
}
}
impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, Message> {
impl<'a, Message> iced_core::Overlay<Message, crate::Theme, crate::Renderer>
for Overlay<'a, Message>
{
fn layout(
&mut self,
renderer: &crate::Renderer,
@ -210,15 +212,13 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
)
.width(self.width);
let mut node = self.container.layout(self.state, renderer, &limits);
let node = self.container.layout(self.state, renderer, &limits);
node.move_to(if space_below > space_above {
node.clone().move_to(if space_below > space_above {
position + Vector::new(0.0, self.target_height)
} else {
position - Vector::new(0.0, node.size().height)
});
node
})
}
fn on_event(
@ -262,9 +262,12 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: appearance.border_color,
border_width: appearance.border_width,
border_radius: appearance.border_radius,
border: Border {
width: appearance.border_width,
color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow::default(),
},
appearance.background,
);
@ -286,13 +289,11 @@ struct List<'a, S: AsRef<str>, Message> {
selected_icon: Option<svg::Handle>,
}
impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S, Message> {
fn width(&self) -> Length {
Length::Fill
}
fn height(&self) -> Length {
Length::Shrink
impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Theme, crate::Renderer>
for List<'a, S, Message>
{
fn size(&self) -> Size<Length> {
Size::new(Length::Fill, Length::Shrink)
}
fn layout(
@ -316,7 +317,7 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S
(f32::from(text_line_height) + self.padding.vertical()) * self.options.len() as f32,
);
limits.resolve(intrinsic)
limits.resolve(Length::Fill, Length::Shrink, intrinsic)
};
layout::Node::new(size)
@ -450,9 +451,11 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S
width: item_width,
..bounds
},
border_color: Color::TRANSPARENT,
border_width: 0.0,
border_radius: appearance.border_radius,
border: Border {
radius: appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
appearance.selected_background,
);
@ -483,9 +486,11 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S
width: item_width,
..bounds
},
border_color: Color::TRANSPARENT,
border_width: 0.0,
border_radius: appearance.border_radius,
border: Border {
radius: appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
appearance.hovered_background,
);
@ -522,7 +527,7 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S
}
impl<'a, S: AsRef<str>, Message: 'a> From<List<'a, S, Message>>
for Element<'a, Message, crate::Renderer>
for Element<'a, Message, crate::Theme, crate::Renderer>
{
fn from(list: List<'a, S, Message>) -> Self {
Element::new(list)

View file

@ -9,8 +9,8 @@ use iced_core::layout::{self, Layout};
use iced_core::text::{self, Text};
use iced_core::widget::Tree;
use iced_core::{
alignment, mouse, overlay, renderer, svg, touch, Clipboard, Color, Element, Length, Padding,
Pixels, Point, Rectangle, Renderer, Shell, Size, Vector, Widget,
alignment, mouse, overlay, renderer, svg, touch, Border, Clipboard, Element, Length, Padding,
Pixels, Point, Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
};
use iced_widget::scrollable::Scrollable;
@ -98,7 +98,7 @@ where
self,
position: Point,
target_height: f32,
) -> overlay::Element<'a, Message, crate::Renderer> {
) -> overlay::Element<'a, Message, crate::Theme, crate::Renderer> {
overlay::Element::new(position, Box::new(Overlay::new(self, target_height)))
}
}
@ -127,7 +127,7 @@ impl Default for State {
struct Overlay<'a, Message> {
state: &'a mut Tree,
container: Container<'a, Message, crate::Renderer>,
container: Container<'a, Message, crate::Theme, crate::Renderer>,
width: f32,
target_height: f32,
style: (),
@ -177,7 +177,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
.padding(padding)
.style(crate::style::Container::Dropdown);
state.tree.diff(&mut container as &mut dyn Widget<_, _>);
state.tree.diff(&mut container as &mut dyn Widget<_, _, _>);
Self {
state: &mut state.tree,
@ -189,7 +189,9 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
}
}
impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, Message> {
impl<'a, Message> iced_core::Overlay<Message, crate::Theme, crate::Renderer>
for Overlay<'a, Message>
{
fn layout(
&mut self,
renderer: &crate::Renderer,
@ -215,7 +217,7 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
let mut node = self.container.layout(self.state, renderer, &limits);
node.move_to(if space_below > space_above {
node = node.clone().move_to(if space_below > space_above {
position + Vector::new(0.0, self.target_height)
} else {
position - Vector::new(0.0, node.size().height)
@ -265,9 +267,12 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: appearance.border_color,
border_width: appearance.border_width,
border_radius: appearance.border_radius,
border: Border {
width: appearance.border_width,
color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow::default(),
},
appearance.background,
);
@ -289,17 +294,14 @@ struct InnerList<'a, S, Item, Message> {
selected_icon: Option<svg::Handle>,
}
impl<'a, S, Item, Message> Widget<Message, crate::Renderer> for InnerList<'a, S, Item, Message>
impl<'a, S, Item, Message> Widget<Message, crate::Theme, crate::Renderer>
for InnerList<'a, S, Item, Message>
where
S: AsRef<str>,
Item: Clone + PartialEq,
{
fn width(&self) -> Length {
Length::Fill
}
fn height(&self) -> Length {
Length::Shrink
fn size(&self) -> Size<Length> {
Size::new(Length::Fill, Length::Shrink)
}
fn layout(
@ -338,7 +340,7 @@ where
separators + descriptions + options
});
limits.resolve(intrinsic)
limits.resolve(Length::Fill, Length::Shrink, intrinsic)
};
layout::Node::new(size)
@ -539,9 +541,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: Color::TRANSPARENT,
border_width: 0.0,
border_radius: appearance.border_radius,
border: Border {
radius: appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
appearance.selected_background,
);
@ -574,9 +578,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_color: Color::TRANSPARENT,
border_width: 0.0,
border_radius: appearance.border_radius,
border: Border {
radius: appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
appearance.hovered_background,
);
@ -614,18 +620,17 @@ where
OptionElement::Separator => {
let divider = crate::widget::divider::horizontal::light().height(1.0);
let mut layout_node = layout::Node::new(Size {
let layout_node = layout::Node::new(Size {
width: bounds.width,
height: 1.0,
});
layout_node.move_to(Point {
})
.move_to(Point {
x: bounds.x,
y: bounds.y + (self.padding.vertical() / 2.0) - 4.0,
});
Widget::<Message, crate::Renderer>::draw(
&crate::Element::<Message>::from(divider),
Widget::<Message, crate::Theme, crate::Renderer>::draw(
crate::Element::<Message>::from(divider).as_widget(),
&Tree::empty(),
renderer,
theme,
@ -665,7 +670,7 @@ where
}
impl<'a, S, Item, Message: 'a> From<InnerList<'a, S, Item, Message>>
for Element<'a, Message, crate::Renderer>
for Element<'a, Message, crate::Theme, crate::Renderer>
where
S: AsRef<str>,
Item: Clone + PartialEq,

View file

@ -8,7 +8,7 @@ use derive_setters::Setters;
use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text};
use iced_core::widget::tree::{self, Tree};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch, Shadow};
use iced_core::{Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Widget};
use std::ffi::OsStr;
@ -60,7 +60,7 @@ impl<'a, S: AsRef<str>, Message, Item: Clone + PartialEq + 'static> Dropdown<'a,
}
impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
Widget<Message, crate::Renderer> for Dropdown<'a, S, Message, Item>
Widget<Message, crate::Theme, crate::Renderer> for Dropdown<'a, S, Message, Item>
{
fn tag(&self) -> tree::Tag {
tree::Tag::of::<State<Item>>()
@ -70,12 +70,8 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
tree::State::new(State::<Item>::new())
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
fn size(&self) -> Size<Length> {
Size::new(self.width, Length::Shrink)
}
fn layout(
@ -188,7 +184,7 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
) -> Option<overlay::Element<'b, Message, crate::Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let state = tree.state.downcast_mut::<State<Item>>();
overlay(
@ -269,7 +265,7 @@ pub fn layout(
) -> layout::Node {
use std::f32;
let limits = limits.width(width).height(Length::Shrink).pad(padding);
let limits = limits.width(width).height(Length::Shrink).shrink(padding);
let max_width = match width {
Length::Shrink => {
@ -298,7 +294,9 @@ pub fn layout(
f32::from(text_line_height.to_absolute(Pixels(text_size))),
);
limits.resolve(intrinsic).pad(padding)
limits
.resolve(width, Length::Shrink, intrinsic)
.expand(padding)
};
layout::Node::new(size)
@ -391,7 +389,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static
text_line_height: text::LineHeight,
selections: &'a super::Model<S, Item>,
on_selected: &'a dyn Fn(Item) -> Message,
) -> Option<overlay::Element<'a, Message, crate::Renderer>> {
) -> Option<overlay::Element<'a, Message, crate::Theme, crate::Renderer>> {
if state.is_open {
let description_line_height = text::LineHeight::Absolute(Pixels(
text_line_height.to_absolute(Pixels(text_size)).0 + 4.0,
@ -510,9 +508,8 @@ pub fn draw<'a, S, Item: Clone + PartialEq + 'static>(
renderer,
renderer::Quad {
bounds,
border_color: style.border_color,
border_width: style.border_width,
border_radius: style.border_radius,
border: style.border,
shadow: Shadow::default(),
},
style.background,
);

View file

@ -8,7 +8,7 @@ use derive_setters::Setters;
use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text};
use iced_core::widget::tree::{self, Tree};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch};
use iced_core::{alignment, keyboard, layout, mouse, overlay, renderer, svg, touch, Shadow};
use iced_core::{Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Widget};
use std::ffi::OsStr;
@ -85,7 +85,9 @@ impl<'a, S: AsRef<str>, Message> Dropdown<'a, S, Message> {
}
}
impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Renderer> for Dropdown<'a, S, Message> {
impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Theme, crate::Renderer>
for Dropdown<'a, S, Message>
{
fn tag(&self) -> tree::Tag {
tree::Tag::of::<State>()
}
@ -118,12 +120,8 @@ impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Renderer> for Dropdo
}
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
fn size(&self) -> Size<Length> {
Size::new(self.width, Length::Shrink)
}
fn layout(
@ -218,7 +216,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Widget<Message, crate::Renderer> for Dropdo
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
) -> Option<overlay::Element<'b, Message, crate::Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let state = tree.state.downcast_mut::<State>();
overlay(
@ -298,7 +296,7 @@ pub fn layout(
) -> layout::Node {
use std::f32;
let limits = limits.width(width).height(Length::Shrink).pad(padding);
let limits = limits.width(width).height(Length::Shrink).shrink(padding);
let max_width = match width {
Length::Shrink => {
@ -327,7 +325,9 @@ pub fn layout(
f32::from(text_line_height.to_absolute(Pixels(text_size))),
);
limits.resolve(intrinsic).pad(padding)
limits
.resolve(width, Length::Shrink, intrinsic)
.expand(padding)
};
layout::Node::new(size)
@ -424,7 +424,7 @@ pub fn overlay<'a, S: AsRef<str>, Message: 'a>(
selections: &'a [S],
selected_option: Option<usize>,
on_selected: &'a dyn Fn(usize) -> Message,
) -> Option<overlay::Element<'a, Message, crate::Renderer>> {
) -> Option<overlay::Element<'a, Message, crate::Theme, crate::Renderer>> {
if state.is_open {
let bounds = layout.bounds();
@ -497,9 +497,8 @@ pub fn draw<'a, S>(
renderer,
renderer::Quad {
bounds,
border_color: style.border_color,
border_width: style.border_width,
border_radius: style.border_radius,
border: style.border,
shadow: Shadow::default(),
},
style.background,
);

View file

@ -15,7 +15,7 @@ pub fn resolve<Message>(
row_spacing: f32,
tree: &mut [Tree],
) -> Node {
let limits = limits.pad(padding);
let limits = limits.shrink(padding);
let mut nodes = Vec::with_capacity(items.len());
@ -51,7 +51,7 @@ pub fn resolve<Message>(
let pos_y = flex_height;
for mut child_node in row_buffer.drain(..) {
child_node.move_to(Point::new(pos_x, pos_y));
child_node = child_node.move_to(Point::new(pos_x, pos_y));
pos_x += row_spacing + child_node.size().width;
nodes.push(child_node);
}
@ -77,7 +77,7 @@ pub fn resolve<Message>(
let pos_y = flex_height;
for mut child_node in row_buffer.drain(..) {
child_node.move_to(Point::new(pos_x, pos_y));
child_node = child_node.move_to(Point::new(pos_x, pos_y));
pos_x += row_spacing + child_node.size().width;
nodes.push(child_node);
}
@ -86,6 +86,6 @@ pub fn resolve<Message>(
flex_width = flex_width.max(current_row_width);
}
let flex_size = limits.resolve(Size::new(flex_width, flex_height));
Node::with_children(flex_size.pad(padding), nodes)
let flex_size = limits.resolve(flex_width, flex_height, Size::new(flex_width, flex_height));
Node::with_children(flex_size.expand(padding), nodes)
}

View file

@ -41,7 +41,9 @@ impl<'a, Message> FlexRow<'a, Message> {
}
}
impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Message> {
impl<'a, Message: 'static + Clone> Widget<Message, crate::Theme, Renderer>
for FlexRow<'a, Message>
{
fn children(&self) -> Vec<Tree> {
self.children.iter().map(Tree::new).collect()
}
@ -50,12 +52,8 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Mes
tree.diff_children(self.children.as_mut_slice());
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
fn size(&self) -> iced_core::Size<Length> {
iced_core::Size::new(self.width, Length::Shrink)
}
fn layout(
@ -64,10 +62,11 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Mes
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
let size = self.size();
let limits = limits
.max_width(self.max_width)
.width(self.width())
.height(self.height());
.width(size.width)
.height(size.height);
super::layout::resolve(
renderer,
@ -178,7 +177,7 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Mes
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
overlay::from_children(&mut self.children, tree, layout, renderer)
}

View file

@ -268,7 +268,7 @@ impl<'a> AnimatedImage<'a> {
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for AnimatedImage<'a>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer> for AnimatedImage<'a>
where
Renderer: ImageRenderer<Handle = Handle>,
{
@ -355,7 +355,7 @@ where
&self,
tree: &Tree,
renderer: &mut Renderer,
_theme: &Renderer::Theme,
_theme: &crate::Theme,
_style: &renderer::Style,
layout: Layout<'_>,
_cursor_position: Cursor,
@ -397,11 +397,11 @@ where
}
}
impl<'a, Message, Renderer> From<AnimatedImage<'a>> for Element<'a, Message, Renderer>
impl<'a, Message, Renderer> From<AnimatedImage<'a>> for Element<'a, Message, crate::Theme, Renderer>
where
Renderer: ImageRenderer<Handle = Handle> + 'a,
{
fn from(gif: AnimatedImage<'a>) -> Element<'a, Message, Renderer> {
fn from(gif: AnimatedImage<'a>) -> Element<'a, Message, crate::Theme, Renderer> {
Element::new(gif)
}
}

View file

@ -43,7 +43,8 @@ pub fn resolve<Message>(
nodes.push(child_node);
let (width, justify_self) = match child_widget.width() {
let c_size = child_widget.size();
let (width, justify_self) = match c_size.width {
Length::Fill | Length::FillPortion(_) => (Dimension::Auto, Some(AlignItems::Stretch)),
_ => (length(size.width), None),
};
@ -62,7 +63,7 @@ pub fn resolve<Message>(
},
size: taffy::geometry::Size {
width,
height: match child_widget.height() {
height: match c_size.height {
Length::Fill | Length::FillPortion(_) => Dimension::Auto,
_ => length(size.height),
},
@ -165,7 +166,8 @@ pub fn resolve<Message>(
{
if let Ok(leaf_layout) = taffy.layout(leaf) {
let child_widget = child.as_widget();
match child_widget.width() {
let c_size = child_widget.size();
match c_size.width {
Length::Fill | Length::FillPortion(_) => {
*node =
child_widget.layout(tree, renderer, &limits.width(leaf_layout.size.width));
@ -173,10 +175,10 @@ pub fn resolve<Message>(
_ => (),
}
node.move_to(Point {
*node = node.clone().move_to(Point {
x: leaf_layout.location.x,
y: leaf_layout.location.y,
});
})
}
}
@ -185,5 +187,5 @@ pub fn resolve<Message>(
height: grid_layout.size.height,
};
Node::with_children(grid_size.pad(padding), nodes)
Node::with_children(grid_size.expand(padding), nodes)
}

View file

@ -103,7 +103,7 @@ impl<'a, Message> Grid<'a, Message> {
}
}
impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Message> {
impl<'a, Message: 'static + Clone> Widget<Message, crate::Theme, Renderer> for Grid<'a, Message> {
fn children(&self) -> Vec<Tree> {
self.children.iter().map(Tree::new).collect()
}
@ -112,12 +112,8 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Messag
tree.diff_children(self.children.as_mut_slice());
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
self.height
fn size(&self) -> iced_core::Size<Length> {
iced_core::Size::new(self.width, self.height)
}
fn layout(
@ -126,10 +122,11 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Messag
renderer: &Renderer,
limits: &layout::Limits,
) -> layout::Node {
let size = self.size();
let limits = limits
.max_width(self.max_width)
.width(self.width())
.height(self.height());
.width(size.width)
.height(size.height);
super::layout::resolve(
renderer,
@ -245,7 +242,7 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Messag
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
overlay::from_children(&mut self.children, tree, layout, renderer)
}

View file

@ -5,8 +5,10 @@ use crate::{ext::CollectionWidget, widget, Element};
use apply::Apply;
use derive_setters::Setters;
use iced::{window, Length};
use iced_core::{renderer::Quad, widget::tree, Background, Color, Renderer, Widget};
use std::{borrow::Cow, process::Child};
use iced_core::{
renderer::Quad, widget::tree, Background, Renderer, Widget,
};
use std::{borrow::Cow};
#[must_use]
pub fn header_bar<'a, Message>() -> HeaderBar<'a, Message> {
@ -106,19 +108,15 @@ pub struct HeaderBarWidget<'a, Message> {
window_id: Option<iced::window::Id>,
}
impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
impl<'a, Message: Clone + 'static> Widget<Message, crate::Theme, crate::Renderer>
for HeaderBarWidget<'a, Message>
{
fn children(&self) -> Vec<tree::Tree> {
vec![tree::Tree::new(&self.header_bar_inner)]
}
fn width(&self) -> Length {
self.header_bar_inner.width()
}
fn height(&self) -> Length {
self.header_bar_inner.height()
fn size(&self) -> iced_core::Size<Length> {
self.header_bar_inner.as_widget().size()
}
fn tag(&self) -> tree::Tag {
@ -156,7 +154,7 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
&self,
tree: &tree::Tree,
renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme,
theme: &crate::Theme,
style: &iced_core::renderer::Style,
layout: iced_core::Layout<'_>,
cursor: iced_core::mouse::Cursor,
@ -189,9 +187,8 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
renderer.fill_quad(
Quad {
bounds: layout.bounds(),
border_radius: header_bar_appearance.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: header_bar_appearance.border,
shadow: header_bar_appearance.shadow,
},
Background::Color(neutral_0.into()),
);
@ -271,7 +268,7 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
state: &'b mut tree::Tree,
layout: iced_core::Layout<'_>,
renderer: &crate::Renderer,
) -> Option<iced_core::overlay::Element<'b, Message, crate::Renderer>> {
) -> Option<iced_core::overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let child_tree = &mut state.children[0];
let child_layout = layout.children().next().unwrap();
self.header_bar_inner

View file

@ -12,7 +12,7 @@ pub use named::{IconFallback, Named};
mod handle;
pub use handle::{from_path, from_raster_bytes, from_raster_pixels, from_svg_bytes, Data, Handle};
use crate::{Element, Renderer};
use crate::Element;
use derive_setters::Setters;
use iced::widget::{Image, Svg};
use iced::{ContentFit, Length};
@ -85,7 +85,7 @@ impl Icon {
};
let from_svg = |handle| {
Svg::<Renderer>::new(handle)
Svg::<crate::Theme>::new(handle)
.style(self.style.clone())
.width(
self.width

View file

@ -9,11 +9,12 @@ pub use self::column::{list_column, ListColumn};
use crate::widget::Container;
use crate::Element;
use iced::{Background, Color};
use iced::{Background};
use iced_core::Shadow;
pub fn container<'a, Message>(
content: impl Into<Element<'a, Message>>,
) -> Container<'a, Message, crate::Renderer> {
) -> Container<'a, Message, crate::Theme, crate::Renderer> {
super::container(content)
.padding([16, 6])
.style(crate::theme::Container::custom(style))
@ -28,8 +29,10 @@ pub fn style(theme: &crate::Theme) -> crate::widget::container::Appearance {
icon_color: Some(container.on.into()),
text_color: Some(container.on.into()),
background: Some(Background::Color(container.base.into())),
border_radius: theme.cosmic().corner_radii.radius_s.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: iced::Border {
radius: theme.cosmic().corner_radii.radius_s.into(),
..Default::default()
},
shadow: Shadow::default(),
}
}

View file

@ -58,15 +58,15 @@ pub fn resolve<'a, E, Message, Renderer>(
tree: &mut [&mut Tree],
) -> Node
where
E: std::borrow::Borrow<Element<'a, Message, Renderer>>,
E: std::borrow::Borrow<Element<'a, Message, crate::Theme, Renderer>>,
Renderer: renderer::Renderer,
{
let limits = limits.pad(padding);
let limits = limits.shrink(padding);
let total_spacing = spacing * items.len().saturating_sub(1) as f32;
let max_cross = axis.cross(limits.max());
let mut fill_sum = 0;
let mut cross = axis.cross(limits.min()).max(axis.cross(limits.fill()));
let mut cross = axis.cross(limits.min()).max(axis.cross(Size::INFINITY));
let mut available = axis.main(limits.max()) - total_spacing;
let mut nodes: Vec<Node> = Vec::with_capacity(items.len());
@ -77,9 +77,10 @@ where
for (child, tree) in items.iter().zip(tree.iter_mut()) {
let child = child.borrow();
let c_size = child.as_widget().size();
let cross_fill_factor = match axis {
Axis::Horizontal => child.as_widget().height(),
Axis::Vertical => child.as_widget().width(),
Axis::Horizontal => c_size.height,
Axis::Vertical => c_size.width,
}
.fill_factor();
@ -100,9 +101,10 @@ where
for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() {
let child = child.borrow();
let c_size = child.as_widget().size();
let fill_factor = match axis {
Axis::Horizontal => child.as_widget().width(),
Axis::Vertical => child.as_widget().height(),
Axis::Horizontal => c_size.width,
Axis::Vertical => c_size.height,
}
.fill_factor();
@ -143,9 +145,10 @@ where
for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() {
let child = child.borrow();
let c_size = child.as_widget().size();
let fill_factor = match axis {
Axis::Horizontal => child.as_widget().width(),
Axis::Vertical => child.as_widget().height(),
Axis::Horizontal => c_size.width,
Axis::Vertical => c_size.height,
}
.fill_factor();
@ -194,24 +197,22 @@ where
let (x, y) = axis.pack(main, pad.1);
node.move_to(Point::new(x, y));
let node_ = node.clone().move_to(Point::new(x, y));
match axis {
Axis::Horizontal => {
node.align(Alignment::Start, align_items, Size::new(0.0, cross));
}
Axis::Vertical => {
node.align(align_items, Alignment::Start, Size::new(cross, 0.0));
}
}
let node_ = match axis {
Axis::Horizontal => node_.align(Alignment::Start, align_items, Size::new(0.0, cross)),
Axis::Vertical => node_.align(align_items, Alignment::Start, Size::new(cross, 0.0)),
};
let size = node.size();
let size = node_.bounds().size();
*node = node_;
main += axis.main(size);
}
let (width, height) = axis.pack(main - pad.0, cross);
let size = limits.resolve(Size::new(width, height));
let size = limits.resolve(width, height, Size::new(width, height));
Node::with_children(size.pad(padding), nodes)
Node::with_children(size.expand(padding), nodes)
}

View file

@ -9,13 +9,14 @@ use super::{
};
use crate::style::menu_bar::StyleSheet;
use iced_core::Border;
use iced_widget::core::{
event,
layout::{Limits, Node},
mouse::{self, Cursor},
overlay, renderer, touch,
widget::{tree, Tree},
Alignment, Clipboard, Color, Element, Layout, Length, Padding, Rectangle, Shell, Widget,
Alignment, Clipboard, Element, Layout, Length, Padding, Rectangle, Shell, Widget,
};
pub(super) struct MenuBarState {
@ -61,7 +62,6 @@ impl Default for MenuBarState {
pub struct MenuBar<'a, Message, Renderer = crate::Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
width: Length,
height: Length,
@ -75,13 +75,12 @@ where
item_height: ItemHeight,
path_highlight: Option<PathHighlight>,
menu_roots: Vec<MenuTree<'a, Message, Renderer>>,
style: <Renderer::Theme as StyleSheet>::Style,
style: <crate::Theme as StyleSheet>::Style,
}
impl<'a, Message, Renderer> MenuBar<'a, Message, Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
/// Creates a new [`MenuBar`] with the given menu roots
#[must_use]
@ -106,7 +105,7 @@ where
item_height: ItemHeight::Uniform(30),
path_highlight: Some(PathHighlight::MenuActive),
menu_roots,
style: <Renderer::Theme as StyleSheet>::Style::default(),
style: <crate::Theme as StyleSheet>::Style::default(),
}
}
@ -186,7 +185,7 @@ where
/// Sets the style of the menu bar and its menus
#[must_use]
pub fn style(mut self, style: impl Into<<Renderer::Theme as StyleSheet>::Style>) -> Self {
pub fn style(mut self, style: impl Into<<crate::Theme as StyleSheet>::Style>) -> Self {
self.style = style.into();
self
}
@ -198,17 +197,13 @@ where
self
}
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for MenuBar<'a, Message, Renderer>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer>
for MenuBar<'a, Message, Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
self.height
fn size(&self) -> iced_core::Size<Length> {
iced_core::Size::new(self.width, self.height)
}
#[allow(invalid_reference_casting)]
@ -226,8 +221,10 @@ where
.iter()
.map(|mt| {
let widget = mt.item.as_widget();
let widget_ptr = widget as *const dyn Widget<Message, Renderer>;
let widget_ptr_mut = widget_ptr as *mut dyn Widget<Message, Renderer>;
let widget_ptr =
widget as *const dyn Widget<Message, crate::Theme, Renderer>;
let widget_ptr_mut =
widget_ptr as *mut dyn Widget<Message, crate::Theme, Renderer>;
//TODO: find a way to diff_children without unsafe code
unsafe { &mut *widget_ptr_mut }
})
@ -356,7 +353,7 @@ where
&self,
tree: &Tree,
renderer: &mut Renderer,
theme: &<Renderer as renderer::Renderer>::Theme,
theme: &crate::Theme,
style: &renderer::Style,
layout: Layout<'_>,
view_cursor: Cursor,
@ -381,9 +378,11 @@ where
.bounds();
let path_quad = renderer::Quad {
bounds: active_bounds,
border_radius: styling.bar_border_radius.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: styling.bar_border_radius.into(),
..Default::default()
},
shadow: Default::default(),
};
let path_color = styling.path;
renderer.fill_quad(path_quad, path_color);
@ -412,7 +411,7 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
_renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
let state = tree.state.downcast_ref::<MenuBarState>();
if !state.open {
return None;
@ -437,11 +436,11 @@ where
)
}
}
impl<'a, Message, Renderer> From<MenuBar<'a, Message, Renderer>> for Element<'a, Message, Renderer>
impl<'a, Message, Renderer> From<MenuBar<'a, Message, Renderer>>
for Element<'a, Message, crate::Theme, Renderer>
where
Message: 'a,
Renderer: 'a + renderer::Renderer,
Renderer::Theme: StyleSheet,
{
fn from(value: MenuBar<'a, Message, Renderer>) -> Self {
Self::new(value)

View file

@ -4,13 +4,14 @@
use super::{menu_bar::MenuBarState, menu_tree::MenuTree};
use crate::style::menu_bar::StyleSheet;
use iced_core::{Border, Shadow};
use iced_widget::core::{
event,
layout::{Limits, Node},
mouse::{self, Cursor},
overlay, renderer, touch,
widget::Tree,
Clipboard, Color, Layout, Length, Padding, Point, Rectangle, Shell, Size, Vector,
Clipboard, Layout, Length, Padding, Point, Rectangle, Shell, Size, Vector,
};
/// The condition of when to close a menu
@ -338,18 +339,14 @@ impl MenuState {
let limits = Limits::new(Size::ZERO, size);
let mut node = mt
.item
mt.item
.as_widget()
.layout(&mut tree[mt.index], renderer, &limits);
node.move_to(Point::new(0.0, position + self.scroll_offset));
node
.layout(&mut tree[mt.index], renderer, &limits)
.move_to(Point::new(0.0, position + self.scroll_offset))
})
.collect::<Vec<_>>();
let mut node = Node::with_children(children_bounds.size(), child_nodes);
node.move_to(children_bounds.position());
node
Node::with_children(children_bounds.size(), child_nodes).move_to(children_bounds.position())
}
fn layout_single<Message, Renderer>(
@ -369,12 +366,11 @@ impl MenuState {
let position = self.menu_bounds.child_positions[index];
let limits = Limits::new(Size::ZERO, self.menu_bounds.child_sizes[index]);
let parent_offset = children_bounds.position() - Point::ORIGIN;
let mut node = menu_tree.item.as_widget().layout(tree, renderer, &limits);
node.move_to(Point::new(
let node = menu_tree.item.as_widget().layout(tree, renderer, &limits);
node.clone().move_to(Point::new(
parent_offset.x,
parent_offset.y + position + self.scroll_offset,
));
node
))
}
fn slice(
@ -434,7 +430,6 @@ impl MenuState {
pub(super) struct Menu<'a, 'b, Message, Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
pub(super) tree: &'b mut Tree,
pub(super) menu_roots: &'b mut Vec<MenuTree<'a, Message, Renderer>>,
@ -447,22 +442,20 @@ where
pub(super) cross_offset: i32,
pub(super) root_bounds_list: Vec<Rectangle>,
pub(super) path_highlight: Option<PathHighlight>,
pub(super) style: &'b <Renderer::Theme as StyleSheet>::Style,
pub(super) style: &'b <crate::Theme as StyleSheet>::Style,
}
impl<'a, 'b, Message, Renderer> Menu<'a, 'b, Message, Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
pub(super) fn overlay(self) -> overlay::Element<'b, Message, Renderer> {
pub(super) fn overlay(self) -> overlay::Element<'b, Message, crate::Theme, Renderer> {
overlay::Element::new(Point::ORIGIN, Box::new(self))
}
}
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, crate::Theme, Renderer>
for Menu<'a, 'b, Message, Renderer>
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
fn layout(
&mut self,
@ -633,7 +626,7 @@ where
fn draw(
&self,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &crate::Theme,
style: &renderer::Style,
layout: Layout<'_>,
view_cursor: Cursor,
@ -689,9 +682,12 @@ where
// println!("color: {:?}\n", styling.background);
let menu_quad = renderer::Quad {
bounds: pad_rectangle(children_bounds, styling.background_expand.into()),
border_radius: styling.menu_border_radius.into(),
border_width: styling.border_width,
border_color: styling.border_color,
border: Border {
radius: styling.menu_border_radius.into(),
width: styling.border_width,
color: styling.border_color,
},
shadow: Shadow::default(),
};
let menu_color = styling.background;
r.fill_quad(menu_quad, menu_color);
@ -705,9 +701,11 @@ where
.bounds();
let path_quad = renderer::Quad {
bounds: active_bounds,
border_radius: styling.menu_border_radius.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: styling.menu_border_radius.into(),
..Default::default()
},
shadow: Shadow::default(),
};
let path_color = styling.path;
r.fill_quad(path_quad, path_color);
@ -759,7 +757,6 @@ fn init_root_menu<Message, Renderer>(
main_offset: f32,
) where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
let state = menu.tree.state.downcast_mut::<MenuBarState>();
if !(state.menu_states.is_empty() && bar_bounds.contains(overlay_cursor)) {
@ -896,7 +893,6 @@ fn process_overlay_events<Message, Renderer>(
) -> event::Status
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
use event::Status::{Captured, Ignored};
/*
@ -1086,7 +1082,6 @@ fn process_scroll_events<Message, Renderer>(
) -> event::Status
where
Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{
use event::Status::{Captured, Ignored};
use mouse::ScrollDelta;
@ -1186,7 +1181,7 @@ where
.iter()
.map(|mt| {
let w = mt.item.as_widget();
match w.height() {
match w.size().height {
Length::Fixed(f) => Size::new(width, f),
Length::Shrink => {
let l_height = w

View file

@ -18,7 +18,7 @@ pub struct MenuTree<'a, Message, Renderer = crate::Renderer> {
pub(super) index: usize,
/// The item of the menu tree
pub(super) item: Element<'a, Message, Renderer>,
pub(super) item: Element<'a, Message, crate::Theme, Renderer>,
/// The children of the menu tree
pub(super) children: Vec<MenuTree<'a, Message, Renderer>>,
/// The width of the menu tree
@ -31,7 +31,7 @@ where
Renderer: renderer::Renderer,
{
/// Create a new menu tree from a widget
pub fn new(item: impl Into<Element<'a, Message, Renderer>>) -> Self {
pub fn new(item: impl Into<Element<'a, Message, crate::Theme, Renderer>>) -> Self {
Self {
index: 0,
item: item.into(),
@ -43,7 +43,7 @@ where
/// Create a menu tree from a widget and a vector of sub trees
pub fn with_children(
item: impl Into<Element<'a, Message, Renderer>>,
item: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
children: Vec<impl Into<MenuTree<'a, Message, Renderer>>>,
) -> Self {
Self {
@ -120,11 +120,12 @@ where
}
}
impl<'a, Message, Renderer> From<Element<'a, Message, Renderer>> for MenuTree<'a, Message, Renderer>
impl<'a, Message, Renderer> From<Element<'a, Message, crate::Theme, Renderer>>
for MenuTree<'a, Message, Renderer>
where
Renderer: renderer::Renderer,
{
fn from(value: Element<'a, Message, Renderer>) -> Self {
fn from(value: Element<'a, Message, crate::Theme, Renderer>) -> Self {
Self::new(value)
}
}

View file

@ -35,7 +35,7 @@ pub use context_drawer::{context_drawer, ContextDrawer};
pub use column::{column, Column};
pub mod column {
pub type Column<'a, Message> = iced::widget::Column<'a, Message, crate::Renderer>;
pub type Column<'a, Message> = iced::widget::Column<'a, Message, crate::Theme, crate::Renderer>;
#[must_use]
pub fn column<'a, Message>() -> Column<'a, Message> {
@ -64,19 +64,19 @@ pub mod divider {
/// Horizontal divider with default thickness
#[must_use]
pub fn default() -> Rule<crate::Renderer> {
pub fn default() -> Rule<crate::Theme> {
horizontal_rule(1).style(crate::theme::Rule::Default)
}
/// Horizontal divider with light thickness
#[must_use]
pub fn light() -> Rule<crate::Renderer> {
pub fn light() -> Rule<crate::Theme> {
horizontal_rule(4).style(crate::theme::Rule::LightDivider)
}
/// Horizontal divider with heavy thickness.
#[must_use]
pub fn heavy() -> Rule<crate::Renderer> {
pub fn heavy() -> Rule<crate::Theme> {
horizontal_rule(10).style(crate::theme::Rule::HeavyDivider)
}
}
@ -87,19 +87,19 @@ pub mod divider {
/// Vertical divider with default thickness
#[must_use]
pub fn default() -> Rule<crate::Renderer> {
pub fn default() -> Rule<crate::Theme> {
vertical_rule(1).style(crate::theme::Rule::Default)
}
/// Vertical divider with light thickness
#[must_use]
pub fn light() -> Rule<crate::Renderer> {
pub fn light() -> Rule<crate::Theme> {
vertical_rule(4).style(crate::theme::Rule::LightDivider)
}
/// Vertical divider with heavy thickness.
#[must_use]
pub fn heavy() -> Rule<crate::Renderer> {
pub fn heavy() -> Rule<crate::Theme> {
vertical_rule(10).style(crate::theme::Rule::HeavyDivider)
}
}
@ -142,7 +142,7 @@ pub use rectangle_tracker::{rectangle_tracker, RectangleTracker};
pub use row::{row, Row};
pub mod row {
pub type Row<'a, Message> = iced::widget::Row<'a, Message, crate::Renderer>;
pub type Row<'a, Message> = iced::widget::Row<'a, Message, crate::Theme, crate::Renderer>;
#[must_use]
pub fn row<'a, Message>() -> Row<'a, Message> {
@ -187,7 +187,8 @@ pub mod tooltip {
pub use iced::widget::tooltip::Position;
pub type Tooltip<'a, Message> = iced::widget::Tooltip<'a, Message, crate::Renderer>;
pub type Tooltip<'a, Message> =
iced::widget::Tooltip<'a, Message, crate::Theme, crate::Renderer>;
pub fn tooltip<'a, Message>(
content: impl Into<Element<'a, Message>>,

View file

@ -10,7 +10,7 @@ use iced::{
widget::{container, scrollable},
Background, Length,
};
use iced_core::Color;
use iced_core::{Border, Color, Shadow};
use crate::{theme, widget::segmented_button, Theme};
@ -23,7 +23,7 @@ pub type Model = segmented_button::SingleSelectModel;
pub fn nav_bar<Message>(
model: &segmented_button::SingleSelectModel,
on_activate: fn(segmented_button::Entity) -> Message,
) -> iced::widget::Container<Message, crate::Renderer>
) -> iced::widget::Container<Message, crate::Theme, crate::Renderer>
where
Message: Clone + 'static,
{
@ -48,8 +48,11 @@ pub fn nav_bar_style(theme: &Theme) -> iced_style::container::Appearance {
icon_color: Some(cosmic.on_bg_color().into()),
text_color: Some(cosmic.on_bg_color().into()),
background: Some(Background::Color(cosmic.primary.base.into())),
border_radius: cosmic.corner_radii.radius_s.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
width: 0.0,
color: Color::TRANSPARENT,
radius: cosmic.corner_radii.radius_s.into(),
},
shadow: Shadow::default(),
}
}

View file

@ -17,24 +17,24 @@ use std::cell::RefCell;
pub use iced_style::container::{Appearance, StyleSheet};
pub fn popover<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>,
popup: impl Into<Element<'a, Message, Renderer>>,
content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
) -> Popover<'a, Message, Renderer> {
Popover::new(content, popup)
}
pub struct Popover<'a, Message, Renderer> {
content: Element<'a, Message, Renderer>,
content: Element<'a, Message, crate::Theme, Renderer>,
// XXX Avoid refcell; improve iced overlay API?
popup: RefCell<Element<'a, Message, Renderer>>,
popup: RefCell<Element<'a, Message, crate::Theme, Renderer>>,
position: Option<Point>,
show_popup: bool,
}
impl<'a, Message, Renderer> Popover<'a, Message, Renderer> {
pub fn new(
content: impl Into<Element<'a, Message, Renderer>>,
popup: impl Into<Element<'a, Message, Renderer>>,
content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
) -> Self {
Self {
content: content.into(),
@ -57,10 +57,10 @@ impl<'a, Message, Renderer> Popover<'a, Message, Renderer> {
// TODO More options for positioning similar to GdkPopup, xdg_popup
}
impl<'a, Message, Renderer> Widget<Message, Renderer> for Popover<'a, Message, Renderer>
impl<'a, Message, Renderer> Widget<Message, crate::Theme, Renderer>
for Popover<'a, Message, Renderer>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{
fn children(&self) -> Vec<Tree> {
vec![Tree::new(&self.content), Tree::new(&*self.popup.borrow())]
@ -70,12 +70,8 @@ where
tree.diff_children(&mut [&mut self.content, &mut self.popup.borrow_mut()]);
}
fn width(&self) -> Length {
self.content.as_widget().width()
}
fn height(&self) -> Length {
self.content.as_widget().height()
fn size(&self) -> Size<Length> {
self.content.as_widget().size()
}
fn layout(
@ -144,7 +140,7 @@ where
&self,
tree: &Tree,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &crate::Theme,
renderer_style: &renderer::Style,
layout: Layout<'_>,
cursor_position: mouse::Cursor,
@ -166,7 +162,7 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
_renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
if !self.show_popup {
return None;
}
@ -198,11 +194,11 @@ where
}
}
impl<'a, Message, Renderer> From<Popover<'a, Message, Renderer>> for Element<'a, Message, Renderer>
impl<'a, Message, Renderer> From<Popover<'a, Message, Renderer>>
for Element<'a, Message, crate::Theme, Renderer>
where
Message: 'static,
Renderer: iced_core::Renderer + 'static,
Renderer::Theme: StyleSheet,
{
fn from(popover: Popover<'a, Message, Renderer>) -> Self {
Self::new(popover)
@ -211,11 +207,11 @@ where
pub struct Overlay<'a, 'b, Message, Renderer> {
tree: &'a mut Tree,
content: &'a RefCell<Element<'b, Message, Renderer>>,
content: &'a RefCell<Element<'b, Message, crate::Theme, Renderer>>,
centered: bool,
}
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, Renderer>
impl<'a, 'b, Message, Renderer> overlay::Overlay<Message, crate::Theme, Renderer>
for Overlay<'a, 'b, Message, Renderer>
where
Renderer: iced_core::Renderer,
@ -228,7 +224,7 @@ where
_translation: iced::Vector,
) -> layout::Node {
let limits = layout::Limits::new(Size::UNIT, bounds);
let mut node = self
let node = self
.content
.borrow()
.as_widget()
@ -245,9 +241,7 @@ where
position.y = (position.y - size.height).clamp(0.0, bounds.height - size.height);
}
}
node.move_to(position);
node
node.move_to(position)
}
fn operate(
@ -302,7 +296,7 @@ where
fn draw(
&self,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &crate::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: mouse::Cursor,

View file

@ -23,7 +23,7 @@ pub fn rectangle_tracker<'a, Message, I, T>(
) -> RectangleTrackingContainer<'a, Message, crate::Renderer, I>
where
I: Hash + Copy + Send + Sync + Debug + 'a,
T: Into<Element<'a, Message, crate::Renderer>>,
T: Into<Element<'a, Message, crate::Theme, crate::Renderer>>,
{
RectangleTrackingContainer::new(content, id, tx)
}
@ -53,7 +53,7 @@ where
) -> RectangleTrackingContainer<'a, Message, crate::Renderer, I>
where
I: 'a,
T: Into<Element<'a, Message, crate::Renderer>>,
T: Into<Element<'a, Message, crate::Theme, crate::Renderer>>,
{
RectangleTrackingContainer::new(content, id, self.tx.clone())
}
@ -66,24 +66,22 @@ where
pub struct RectangleTrackingContainer<'a, Message, Renderer, I>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{
tx: UnboundedSender<(I, Rectangle)>,
id: I,
container: Container<'a, Message, Renderer>,
container: Container<'a, Message, crate::Theme, Renderer>,
ignore_bounds: bool,
}
impl<'a, Message, Renderer, I> RectangleTrackingContainer<'a, Message, Renderer, I>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
I: 'a + Hash + Copy + Send + Sync + Debug,
{
/// Creates an empty [`Container`].
pub(crate) fn new<T>(content: T, id: I, tx: UnboundedSender<(I, Rectangle)>) -> Self
where
T: Into<Element<'a, Message, Renderer>>,
T: Into<Element<'a, Message, crate::Theme, Renderer>>,
{
RectangleTrackingContainer {
id,
@ -162,7 +160,7 @@ where
/// Sets the style of the [`Container`].
#[must_use]
pub fn style(mut self, style: impl Into<<Renderer::Theme as StyleSheet>::Style>) -> Self {
pub fn style(mut self, style: impl Into<<crate::Theme as StyleSheet>::Style>) -> Self {
self.container = self.container.style(style);
self
}
@ -176,11 +174,10 @@ where
}
}
impl<'a, Message, Renderer, I> Widget<Message, Renderer>
impl<'a, Message, Renderer, I> Widget<Message, crate::Theme, Renderer>
for RectangleTrackingContainer<'a, Message, Renderer, I>
where
Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
I: 'a + Hash + Copy + Send + Sync + Debug,
{
fn children(&self) -> Vec<Tree> {
@ -195,12 +192,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) -> iced_core::Size<Length> {
self.container.size()
}
fn layout(
@ -271,7 +264,7 @@ where
&self,
tree: &Tree,
renderer: &mut Renderer,
theme: &Renderer::Theme,
theme: &crate::Theme,
renderer_style: &renderer::Style,
layout: Layout<'_>,
cursor_position: mouse::Cursor,
@ -295,22 +288,21 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.container.overlay(tree, layout, renderer)
}
}
impl<'a, Message, Renderer, I> From<RectangleTrackingContainer<'a, Message, Renderer, I>>
for Element<'a, Message, Renderer>
for Element<'a, Message, crate::Theme, Renderer>
where
Message: 'a,
Renderer: 'a + iced_core::Renderer,
Renderer::Theme: StyleSheet,
I: 'a + Hash + Copy + Send + Sync + Debug,
{
fn from(
column: RectangleTrackingContainer<'a, Message, Renderer, I>,
) -> Element<'a, Message, Renderer> {
) -> Element<'a, Message, crate::Theme, Renderer> {
Element::new(column)
}
}

View file

@ -6,7 +6,7 @@ use iced::widget;
pub fn scrollable<'a, Message>(
element: impl Into<Element<'a, Message>>,
) -> widget::Scrollable<'a, Message, Renderer> {
) -> widget::Scrollable<'a, Message, crate::Theme, Renderer> {
widget::scrollable(element)
// .scrollbar_width(8) TODO add these back
// .scroller_width(8)

View file

@ -131,9 +131,11 @@ where
}
// Get the max available width for placing buttons into.
let max_size = limits
.height(Length::Fixed(total_height))
.resolve(Size::new(f32::MAX, total_height));
let max_size = limits.height(Length::Fixed(total_height)).resolve(
Length::Fill,
total_height,
Size::new(f32::MAX, total_height),
);
let mut visible_width = f32::from(self.button_height) * 2.0;
state.buttons_visible = 0;
@ -162,25 +164,33 @@ where
size = limits
.width(Length::Fixed(visible_width))
.height(Length::Fixed(total_height))
.resolve(Size::new(visible_width, total_height));
.resolve(
visible_width,
total_height,
Size::new(visible_width, total_height),
);
} else {
// Buttons will be rendered with equal widths.
state.buttons_visible = self.model.items.len();
let (width, height) = self.max_button_dimensions(state, renderer, limits.max());
let total_width = (state.buttons_visible as f32) * (width + spacing);
size = limits
.height(Length::Fixed(height))
.resolve(Size::new(total_width, height));
size = limits.height(Length::Fixed(height)).resolve(
total_width,
height,
Size::new(total_width, height),
);
let actual_width = size.width as usize;
let minimum_width = state.buttons_visible * self.minimum_button_width as usize;
state.collapsed = actual_width < minimum_width;
if state.collapsed {
size = limits
.height(Length::Fixed(height))
.resolve(Size::new(f32::MAX, height));
size = limits.height(Length::Fixed(height)).resolve(
Length::Fill,
height,
Size::new(f32::MAX, height),
);
state.buttons_visible =
(actual_width / self.minimum_button_width as usize).min(state.buttons_visible);

View file

@ -1,13 +1,13 @@
// Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0
use iced_core::{Background, BorderRadius, Color};
use iced_core::{border::Radius, Background, Color};
/// Appearance of the segmented button.
#[derive(Default, Clone, Copy)]
pub struct Appearance {
pub background: Option<Background>,
pub border_radius: BorderRadius,
pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>,
pub border_start: Option<(f32, Color)>,
@ -21,7 +21,7 @@ pub struct Appearance {
/// Appearance of an item in the segmented button.
#[derive(Default, Clone, Copy)]
pub struct ItemAppearance {
pub border_radius: BorderRadius,
pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>,
pub border_start: Option<(f32, Color)>,

View file

@ -88,9 +88,10 @@ where
height = (num as f32 * height) + (num as f32 * spacing) - spacing;
}
let size = limits
.height(Length::Fixed(height))
.resolve(Size::new(width, height));
let size =
limits
.height(Length::Fixed(height))
.resolve(width, height, Size::new(width, height));
layout::Node::new(size)
}

View file

@ -14,7 +14,7 @@ use iced_core::mouse::ScrollDelta;
use iced_core::text::{LineHeight, Paragraph, Renderer as TextRenderer, Shaping};
use iced_core::widget::{self, operation, tree};
use iced_core::{layout, renderer, widget::Tree, Clipboard, Layout, Shell, Widget};
use iced_core::{Point, Renderer as IcedRenderer, Text};
use iced_core::{Border, Point, Renderer as IcedRenderer, Shadow, Text};
use slotmap::{Key, SecondaryMap};
use std::marker::PhantomData;
use std::time::{Duration, Instant};
@ -374,7 +374,7 @@ where
}
}
impl<'a, Variant, SelectionMode, Message> Widget<Message, Renderer>
impl<'a, Variant, SelectionMode, Message> Widget<Message, crate::Theme, Renderer>
for SegmentedButton<'a, Variant, SelectionMode, Message>
where
Self: SegmentedVariant,
@ -423,12 +423,8 @@ where
}
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
self.height
fn size(&self) -> Size<Length> {
Size::new(self.width, self.height)
}
fn layout(
@ -601,7 +597,7 @@ where
if state.focused {
if let Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab,
key: keyboard::Key::Named(keyboard::key::Named::Tab),
modifiers,
..
}) = event
@ -615,7 +611,7 @@ where
if let Some(on_activate) = self.on_activate.as_ref() {
if let Event::Keyboard(keyboard::Event::KeyReleased {
key_code: keyboard::KeyCode::Enter,
key: keyboard::Key::Named(keyboard::key::Named::Enter),
..
}) = event
{
@ -719,7 +715,6 @@ where
cursor: mouse::Cursor,
viewport: &iced::Rectangle,
) {
let cosmic_theme = theme.cosmic();
let state = tree.state.downcast_ref::<LocalState>();
let appearance = Self::variant_appearance(theme, &self.style);
let bounds = layout.bounds();
@ -730,9 +725,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
background,
);
@ -758,9 +755,11 @@ where
width: f32::from(self.button_height),
height: bounds.height,
},
border_radius: cosmic_theme.radius_s().into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: appearance.focus.first.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
background_appearance
.background
@ -808,9 +807,11 @@ where
width: f32::from(self.button_height),
height: bounds.height,
},
border_radius: cosmic_theme.radius_s().into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: appearance.focus.last.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
background_appearance
.background
@ -871,9 +872,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: button_appearance.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: button_appearance.border_radius,
..Default::default()
},
shadow: Shadow::default(),
},
status_appearance
.background
@ -891,9 +894,11 @@ where
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: rad_0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
radius: rad_0.into(),
..Default::default()
},
shadow: Shadow::default(),
},
background,
);
@ -1012,7 +1017,7 @@ where
_tree: &'b mut Tree,
_layout: iced_core::Layout<'_>,
_renderer: &Renderer,
) -> Option<iced_core::overlay::Element<'b, Message, Renderer>> {
) -> Option<iced_core::overlay::Element<'b, Message, crate::Theme, Renderer>> {
None
}
}
@ -1134,18 +1139,17 @@ fn draw_icon<Message: 'static>(
bounds: Rectangle,
icon: Icon,
) {
let mut layout_node = layout::Node::new(Size {
let layout_node = layout::Node::new(Size {
width: bounds.width,
height: bounds.width,
});
layout_node.move_to(Point {
})
.move_to(Point {
x: bounds.x,
y: bounds.y,
});
Widget::<Message, Renderer>::draw(
Element::<Message>::from(icon).as_widget(),
Widget::<Message, crate::Theme, Renderer>::draw(
Element::<Message>::from(icon.clone()).as_widget(),
&Tree::empty(),
renderer,
theme,

View file

@ -13,6 +13,7 @@ use iced::{
alignment::{Horizontal, Vertical},
Alignment, Length,
};
use iced_core::{Border, Shadow};
pub struct SpinButton<'a, Message> {
label: Cow<'a, str>,
@ -106,8 +107,11 @@ fn container_style(theme: &crate::Theme) -> iced_style::container::Appearance {
icon_color: Some(basic.palette.neutral_10.into()),
text_color: Some(basic.palette.neutral_10.into()),
background: None,
border_radius: corners.radius_s.into(),
border_width: 0.0,
border_color: accent.base.into(),
border: Border {
radius: corners.radius_s.into(),
width: 0.0,
color: accent.base.into(),
},
shadow: Shadow::default(),
}
}

View file

@ -6,7 +6,7 @@ use std::borrow::Cow;
/// Creates a new [`Text`] widget with the provided content.
///
/// [`Text`]: widget::Text
pub fn text<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn text<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
}
@ -25,7 +25,7 @@ pub enum Typography {
}
/// [`Text`] widget with the Title 1 typography preset.
pub fn title1<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn title1<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(32.0)
.line_height(LineHeight::Absolute(44.0.into()))
@ -33,28 +33,28 @@ pub fn title1<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
}
/// [`Text`] widget with the Title 2 typography preset.
pub fn title2<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn title2<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(28.0)
.line_height(LineHeight::Absolute(36.0.into()))
}
/// [`Text`] widget with the Title 3 typography preset.
pub fn title3<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn title3<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(24.0)
.line_height(LineHeight::Absolute(32.0.into()))
}
/// [`Text`] widget with the Title 4 typography preset.
pub fn title4<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn title4<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(20.0)
.line_height(LineHeight::Absolute(28.0.into()))
}
/// [`Text`] widget with the Heading typography preset.
pub fn heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(14.0)
.line_height(LineHeight::Absolute(iced::Pixels(20.0)))
@ -62,7 +62,7 @@ pub fn heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
}
/// [`Text`] widget with the Caption Heading typography preset.
pub fn caption_heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn caption_heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(10.0)
.line_height(LineHeight::Absolute(iced::Pixels(14.0)))
@ -70,21 +70,21 @@ pub fn caption_heading<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Rende
}
/// [`Text`] widget with the Body typography preset.
pub fn body<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn body<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(14.0)
.line_height(LineHeight::Absolute(20.0.into()))
}
/// [`Text`] widget with the Caption typography preset.
pub fn caption<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn caption<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(10.0)
.line_height(LineHeight::Absolute(14.0.into()))
}
/// [`Text`] widget with the Monotext typography preset.
pub fn monotext<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, Renderer> {
pub fn monotext<'a>(text: impl Into<Cow<'a, str>> + 'a) -> Text<'a, crate::Theme, Renderer> {
Text::new(text)
.size(14.0)
.line_height(LineHeight::Absolute(20.0.into()))

View file

@ -18,7 +18,6 @@ pub use super::value::Value;
use apply::Apply;
use iced::Limits;
use iced_core::event::{self, Event};
use iced_core::keyboard;
use iced_core::mouse::{self, click};
use iced_core::overlay::Group;
use iced_core::renderer::{self, Renderer as CoreRenderer};
@ -30,6 +29,7 @@ use iced_core::widget::tree::{self, Tree};
use iced_core::widget::Id;
use iced_core::window;
use iced_core::{alignment, Background};
use iced_core::{keyboard, Border, Shadow};
use iced_core::{layout, overlay};
use iced_core::{
Clipboard, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shell, Size,
@ -193,9 +193,9 @@ pub struct TextInput<'a, Message> {
on_input: Option<Box<dyn Fn(String) -> Message + 'a>>,
on_paste: Option<Box<dyn Fn(String) -> Message + 'a>>,
on_submit: Option<Message>,
leading_icon: Option<Element<'a, Message, crate::Renderer>>,
trailing_icon: Option<Element<'a, Message, crate::Renderer>>,
style: <<crate::Renderer as iced_core::Renderer>::Theme as StyleSheet>::Style,
leading_icon: Option<Element<'a, Message, crate::Theme, crate::Renderer>>,
trailing_icon: Option<Element<'a, Message, crate::Theme, crate::Renderer>>,
style: <crate::Theme as StyleSheet>::Style,
on_create_dnd_source: Option<Box<dyn Fn(State) -> Message + 'a>>,
on_dnd_command_produced: Option<Box<dyn Fn(DnDCommand) -> Message + 'a>>,
surface_ids: Option<(window::Id, window::Id)>,
@ -322,13 +322,19 @@ where
}
/// Sets the start [`Icon`] of the [`TextInput`].
pub fn leading_icon(mut self, icon: Element<'a, Message, crate::Renderer>) -> Self {
pub fn leading_icon(
mut self,
icon: Element<'a, Message, crate::Theme, crate::Renderer>,
) -> Self {
self.leading_icon = Some(icon);
self
}
/// Sets the end [`Icon`] of the [`TextInput`].
pub fn trailing_icon(mut self, icon: Element<'a, Message, crate::Renderer>) -> Self {
pub fn trailing_icon(
mut self,
icon: Element<'a, Message, crate::Theme, crate::Renderer>,
) -> Self {
self.trailing_icon = Some(icon);
self
}
@ -352,10 +358,7 @@ where
}
/// Sets the style of the [`TextInput`].
pub fn style(
mut self,
style: impl Into<<<crate::Renderer as iced_core::Renderer>::Theme as StyleSheet>::Style>,
) -> Self {
pub fn style(mut self, style: impl Into<<crate::Theme as StyleSheet>::Style>) -> Self {
self.style = style.into();
self
}
@ -369,7 +372,7 @@ where
&self,
tree: &Tree,
renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme,
theme: &crate::Theme,
layout: Layout<'_>,
cursor_position: mouse::Cursor,
value: Option<&Value>,
@ -467,7 +470,7 @@ where
}
}
impl<'a, Message> Widget<Message, crate::Renderer> for TextInput<'a, Message>
impl<'a, Message> Widget<Message, crate::Theme, crate::Renderer> for TextInput<'a, Message>
where
Message: Clone + 'static,
{
@ -512,12 +515,11 @@ where
.collect()
}
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
fn size(&self) -> Size<Length> {
Size {
width: self.width,
height: Length::Shrink,
}
}
fn layout(
@ -552,9 +554,10 @@ where
shaping: text::Shaping::Advanced,
});
let Size { width, height } = limits.resolve(value_paragraph.min_bounds());
let Size { width, height } =
limits.resolve(Length::Shrink, Length::Shrink, value_paragraph.min_bounds());
let size = limits.resolve(Size::new(width, height));
let size = limits.resolve(width, height, Size::new(width, height));
layout::Node::with_children(size, vec![layout::Node::new(size)])
} else {
let res = layout(
@ -616,7 +619,7 @@ where
tree: &'b mut Tree,
layout: Layout<'_>,
renderer: &crate::Renderer,
) -> Option<overlay::Element<'b, Message, crate::Renderer>> {
) -> Option<overlay::Element<'b, Message, crate::Theme, crate::Renderer>> {
let mut layout_ = Vec::with_capacity(2);
if self.leading_icon.is_some() {
let mut children = self.text_layout(layout).children();
@ -750,7 +753,7 @@ where
&self,
tree: &Tree,
renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme,
theme: &crate::Theme,
style: &renderer::Style,
layout: Layout<'_>,
cursor_position: mouse::Cursor,
@ -801,7 +804,7 @@ where
let leading_icon_layout = children.next().unwrap();
if cursor_position.is_over(leading_icon_layout.bounds()) {
return leading_icon.mouse_interaction(
return leading_icon.as_widget().mouse_interaction(
tree,
layout,
cursor_position,
@ -824,7 +827,7 @@ where
let trailing_icon_layout = children.next().unwrap();
if cursor_position.is_over(trailing_icon_layout.bounds()) {
return trailing_icon.mouse_interaction(
return trailing_icon.as_widget().mouse_interaction(
tree,
layout,
cursor_position,
@ -839,11 +842,14 @@ where
}
}
impl<'a, Message> From<TextInput<'a, Message>> for Element<'a, Message, crate::Renderer>
impl<'a, Message> From<TextInput<'a, Message>>
for Element<'a, Message, crate::Theme, crate::Renderer>
where
Message: 'static + Clone,
{
fn from(text_input: TextInput<'a, Message>) -> Element<'a, Message, crate::Renderer> {
fn from(
text_input: TextInput<'a, Message>,
) -> Element<'a, Message, crate::Theme, crate::Renderer> {
Element::new(text_input)
}
}
@ -886,8 +892,8 @@ pub fn layout<Message>(
width: Length,
padding: Padding,
size: Option<f32>,
leading_icon: Option<&Element<'_, Message, crate::Renderer>>,
trailing_icon: Option<&Element<'_, Message, crate::Renderer>>,
leading_icon: Option<&Element<'_, Message, crate::Theme, crate::Renderer>>,
trailing_icon: Option<&Element<'_, Message, crate::Theme, crate::Renderer>>,
line_height: text::LineHeight,
label: Option<&str>,
helper_text: Option<&str>,
@ -901,7 +907,7 @@ pub fn layout<Message>(
let mut nodes = Vec::with_capacity(3);
let text_pos = if let Some(label) = label {
let text_bounds = limits.resolve(Size::ZERO);
let text_bounds = limits.resolve(Length::Shrink, Length::Shrink, Size::ZERO);
let state = tree.state.downcast_mut::<State>();
let label_paragraph = &mut state.label;
label_paragraph.update(Text {
@ -931,17 +937,16 @@ pub fn layout<Message>(
// TODO configurable icon spacing, maybe via appearance
let limits_copy = limits;
let limits = limits.pad(padding);
let limits = limits.shrink(padding);
let icon_spacing = 8.0;
let mut c_i = 0;
let (leading_icon_width, mut leading_icon) =
if let Some((icon, tree)) = leading_icon.zip(children.get_mut(c_i)) {
let size = icon.as_widget().size();
let icon_node = icon.as_widget().layout(
tree,
renderer,
&Limits::NONE
.width(icon.as_widget().width())
.height(icon.as_widget().height()),
&Limits::NONE.width(size.width).height(size.height),
);
text_input_height = text_input_height.max(icon_node.bounds().height);
c_i += 1;
@ -952,12 +957,11 @@ pub fn layout<Message>(
let (trailing_icon_width, mut trailing_icon) =
if let Some((icon, tree)) = trailing_icon.zip(children.get_mut(c_i)) {
let icon_node = icon.layout(
let size = icon.as_widget().size();
let icon_node = icon.as_widget().layout(
tree,
renderer,
&Limits::NONE
.width(icon.as_widget().width())
.height(icon.as_widget().height()),
&Limits::NONE.width(size.width).height(size.height),
);
text_input_height = text_input_height.max(icon_node.bounds().height);
(icon_node.bounds().width + icon_spacing, Some(icon_node))
@ -966,13 +970,12 @@ pub fn layout<Message>(
};
let text_limits = limits.width(width).height(text_size * 1.2);
let text_bounds = text_limits.resolve(Size::ZERO);
let text_bounds = text_limits.resolve(Length::Shrink, Length::Shrink, Size::ZERO);
let mut text_node = layout::Node::new(
let text_node = layout::Node::new(
text_bounds - Size::new(leading_icon_width + trailing_icon_width, 0.0),
);
text_node.move_to(Point::new(
)
.move_to(Point::new(
padding.left + leading_icon_width,
padding.top + (text_size.mul_add(-1.2, text_input_height) / 2.0).max(0.0),
));
@ -981,32 +984,38 @@ pub fn layout<Message>(
let text_node_bounds = text_node.bounds();
node_list.push(text_node);
if let Some(mut leading_icon) = leading_icon.take() {
leading_icon.move_to(Point::new(
if let Some(leading_icon) = leading_icon.take() {
node_list.push(leading_icon.clone().move_to(Point::new(
padding.left,
padding.top + ((text_input_height - leading_icon.bounds().height) / 2.0).max(0.0),
));
node_list.push(leading_icon);
)));
}
if let Some(mut trailing_icon) = trailing_icon.take() {
trailing_icon.move_to(Point::new(
if let Some(trailing_icon) = trailing_icon.take() {
node_list.push(trailing_icon.clone().move_to(Point::new(
text_node_bounds.x + text_node_bounds.width + f32::from(spacing),
padding.top + ((text_input_height - trailing_icon.bounds().height) / 2.0).max(0.0),
));
node_list.push(trailing_icon);
)));
}
let text_input_size = Size::new(
text_node_bounds.x + text_node_bounds.width + trailing_icon_width,
text_input_height,
)
.pad(padding);
.expand(Size {
height: -padding.top - padding.bottom,
width: -padding.left - padding.right,
})
.expand(padding);
let input_limits = limits_copy
.width(width)
.height(text_input_height.max(text_input_size.height))
.min_width(text_input_size.width);
let input_bounds = input_limits.resolve(text_input_size);
let input_bounds = input_limits.resolve(
width,
text_input_height.max(text_input_size.height),
text_input_size,
);
let input_node = layout::Node::with_children(input_bounds, node_list).translate(text_pos);
let y_pos = input_node.bounds().y + input_node.bounds().height + f32::from(spacing);
nodes.push(input_node);
@ -1016,14 +1025,13 @@ pub fn layout<Message>(
let limits = limits
.width(width)
.height(text_input_height + padding.vertical())
.pad(padding);
let text_bounds = limits.resolve(Size::ZERO);
.shrink(padding);
let text_bounds = limits.resolve(Length::Shrink, Length::Shrink, Size::ZERO);
let mut text = layout::Node::new(text_bounds);
text.move_to(Point::new(padding.left, padding.top));
let text = layout::Node::new(text_bounds).move_to(Point::new(padding.left, padding.top));
let node =
layout::Node::with_children(text_bounds.pad(padding), vec![text]).translate(text_pos);
let node = layout::Node::with_children(text_bounds.expand(padding), vec![text])
.translate(text_pos);
let y_pos = node.bounds().y + node.bounds().height + f32::from(spacing);
nodes.push(node);
@ -1033,9 +1041,9 @@ pub fn layout<Message>(
if let Some(helper_text) = helper_text {
let limits = limits
.width(width)
.pad(padding)
.shrink(padding)
.height(helper_text_size * 1.2);
let text_bounds = limits.resolve(Size::ZERO);
let text_bounds = limits.resolve(Length::Shrink, Length::Shrink, Size::ZERO);
let state = tree.state.downcast_mut::<State>();
let helper_text_paragraph = &mut state.label;
@ -1067,7 +1075,7 @@ pub fn layout<Message>(
.height(size.height)
.min_width(size.width);
layout::Node::with_children(limits.resolve(size), nodes)
layout::Node::with_children(limits.resolve(width, size.height, size), nodes)
}
/// Processes an [`Event`] and updates the [`State`] of a [`TextInput`]
@ -1302,7 +1310,11 @@ where
return event::Status::Captured;
}
}
Event::Keyboard(keyboard::Event::CharacterReceived(c)) => {
Event::Keyboard(keyboard::Event::KeyReleased {
key: keyboard::Key::Character(c),
modifiers,
..
}) => {
let state = state();
if let Some(focus) = &mut state.is_focused {
@ -1312,11 +1324,11 @@ where
if state.is_pasting.is_none()
&& !state.keyboard_modifiers.command()
&& !c.is_control()
&& !modifiers.control()
{
let mut editor = Editor::new(unsecured_value, &mut state.cursor);
editor.insert(c);
editor.insert(c.chars().next().unwrap_or_default());
let contents = editor.contents();
let unsecured_value = Value::new(&contents);
let message = (on_input)(contents);
@ -1335,7 +1347,7 @@ where
}
}
}
Event::Keyboard(keyboard::Event::KeyPressed { key_code, .. }) => {
Event::Keyboard(keyboard::Event::KeyPressed { key, .. }) => {
let state = state();
if let Some(focus) = &mut state.is_focused {
@ -1346,13 +1358,13 @@ where
let modifiers = state.keyboard_modifiers;
focus.updated_at = Instant::now();
match key_code {
keyboard::KeyCode::Enter | keyboard::KeyCode::NumpadEnter => {
match key {
keyboard::Key::Named(keyboard::key::Named::Enter) => {
if let Some(on_submit) = on_submit.clone() {
shell.publish(on_submit);
}
}
keyboard::KeyCode::Backspace => {
keyboard::Key::Named(keyboard::key::Named::Backspace) => {
if platform::is_jump_modifier_pressed(modifiers)
&& state.cursor.selection(value).is_none()
{
@ -1379,7 +1391,7 @@ where
};
update_cache(state, &value);
}
keyboard::KeyCode::Delete => {
keyboard::Key::Named(keyboard::key::Named::Delete) => {
if platform::is_jump_modifier_pressed(modifiers)
&& state.cursor.selection(value).is_none()
{
@ -1405,7 +1417,7 @@ where
update_cache(state, &value);
}
keyboard::KeyCode::Left => {
keyboard::Key::Named(keyboard::key::Named::ArrowLeft) => {
if platform::is_jump_modifier_pressed(modifiers) && !is_secure {
if modifiers.shift() {
state.cursor.select_left_by_words(value);
@ -1418,7 +1430,7 @@ where
state.cursor.move_left(value);
}
}
keyboard::KeyCode::Right => {
keyboard::Key::Named(keyboard::key::Named::ArrowRight) => {
if platform::is_jump_modifier_pressed(modifiers) && !is_secure {
if modifiers.shift() {
state.cursor.select_right_by_words(value);
@ -1431,14 +1443,14 @@ where
state.cursor.move_right(value);
}
}
keyboard::KeyCode::Home => {
keyboard::Key::Named(keyboard::key::Named::Home) => {
if modifiers.shift() {
state.cursor.select_range(state.cursor.start(value), 0);
} else {
state.cursor.move_to(0);
}
}
keyboard::KeyCode::End => {
keyboard::Key::Named(keyboard::key::Named::End) => {
if modifiers.shift() {
state
.cursor
@ -1447,7 +1459,9 @@ where
state.cursor.move_to(value.len());
}
}
keyboard::KeyCode::C if state.keyboard_modifiers.command() => {
keyboard::Key::Character(ref c)
if "c" == c && state.keyboard_modifiers.command() =>
{
if !is_secure {
if let Some((start, end)) = state.cursor.selection(value) {
clipboard.write(value.select(start, end).to_string());
@ -1456,7 +1470,9 @@ where
}
// XXX if we want to allow cutting of secure text, we need to
// update the cache and decide which value to cut
keyboard::KeyCode::X if state.keyboard_modifiers.command() => {
keyboard::Key::Character(c)
if "x" == c && state.keyboard_modifiers.command() =>
{
if !is_secure {
if let Some((start, end)) = state.cursor.selection(value) {
clipboard.write(value.select(start, end).to_string());
@ -1470,7 +1486,7 @@ where
shell.publish(message);
}
}
keyboard::KeyCode::V => {
keyboard::Key::Character(c) if "v" == c => {
if state.keyboard_modifiers.command() {
let content = if let Some(content) = state.is_pasting.take() {
content
@ -1511,17 +1527,21 @@ where
state.is_pasting = None;
}
}
keyboard::KeyCode::A if state.keyboard_modifiers.command() => {
keyboard::Key::Character(c)
if "a" == c && state.keyboard_modifiers.command() =>
{
state.cursor.select_all(value);
}
keyboard::KeyCode::Escape => {
keyboard::Key::Named(keyboard::key::Named::Escape) => {
state.is_focused = None;
state.dragging_state = None;
state.is_pasting = None;
state.keyboard_modifiers = keyboard::Modifiers::default();
}
keyboard::KeyCode::Tab | keyboard::KeyCode::Up | keyboard::KeyCode::Down => {
keyboard::Key::Named(keyboard::key::Named::Tab)
| keyboard::Key::Named(keyboard::key::Named::ArrowUp)
| keyboard::Key::Named(keyboard::key::Named::ArrowDown) => {
return event::Status::Ignored;
}
_ => {}
@ -1530,15 +1550,17 @@ where
return event::Status::Captured;
}
}
Event::Keyboard(keyboard::Event::KeyReleased { key_code, .. }) => {
Event::Keyboard(keyboard::Event::KeyReleased { key, .. }) => {
let state = state();
if state.is_focused.is_some() {
match key_code {
keyboard::KeyCode::V => {
match key {
keyboard::Key::Character(c) if "v" == c => {
state.is_pasting = None;
}
keyboard::KeyCode::Tab | keyboard::KeyCode::Up | keyboard::KeyCode::Down => {
keyboard::Key::Named(keyboard::key::Named::Tab)
| keyboard::Key::Named(keyboard::key::Named::ArrowUp)
| keyboard::Key::Named(keyboard::key::Named::ArrowDown) => {
return event::Status::Ignored;
}
_ => {}
@ -1832,8 +1854,8 @@ pub fn draw<'a, Message>(
font: Option<<crate::Renderer as iced_core::text::Renderer>::Font>,
is_disabled: bool,
is_secure: bool,
icon: Option<&Element<'a, Message, crate::Renderer>>,
trailing_icon: Option<&Element<'a, Message, crate::Renderer>>,
icon: Option<&Element<'a, Message, crate::Theme, crate::Renderer>>,
trailing_icon: Option<&Element<'a, Message, crate::Theme, crate::Renderer>>,
style: &<crate::Theme as StyleSheet>::Style,
dnd_icon: bool,
line_height: text::LineHeight,
@ -1902,18 +1924,32 @@ pub fn draw<'a, Message>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
width: appearance.border_width,
color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow {
offset: Vector::new(0.0, 1.0),
color: Color::TRANSPARENT,
blur_radius: 0.0,
},
},
appearance.background,
);
renderer.fill_quad(
renderer::Quad {
bounds: offset_bounds,
border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
border: Border {
width: appearance.border_width,
color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow {
offset: Vector::new(0.0, 1.0),
color: Color::TRANSPARENT,
blur_radius: 0.0,
},
},
Background::Color(Color::TRANSPARENT),
);
@ -1921,9 +1957,16 @@ pub fn draw<'a, Message>(
renderer.fill_quad(
renderer::Quad {
bounds,
border_radius: appearance.border_radius,
border_width: appearance.border_width,
border_color: appearance.border_color,
border: Border {
width: appearance.border_width,
color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow {
offset: Vector::new(0.0, 1.0),
color: Color::TRANSPARENT,
blur_radius: 0.0,
},
},
appearance.background,
);
@ -1999,9 +2042,16 @@ pub fn draw<'a, Message>(
width: 1.0,
height: text_bounds.height,
},
border_radius: radius_0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
width: 0.0,
color: Color::TRANSPARENT,
radius: radius_0,
},
shadow: Shadow {
offset: Vector::ZERO,
color: Color::TRANSPARENT,
blur_radius: 0.0,
},
},
appearance.text_color,
)),
@ -2037,9 +2087,16 @@ pub fn draw<'a, Message>(
width,
height: text_bounds.height,
},
border_radius: radius_0,
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
width: 0.0,
color: Color::TRANSPARENT,
radius: radius_0,
},
shadow: Shadow {
offset: Vector::ZERO,
color: Color::TRANSPARENT,
blur_radius: 0.0,
},
},
appearance.selected_fill,
)),

View file

@ -4,7 +4,7 @@
//! Change the appearance of a text input.
use iced_core::{Background, BorderRadius, Color};
use iced_core::{border::Radius, Background, Color};
/// The appearance of a text input.
#[derive(Debug, Clone, Copy)]
@ -12,7 +12,7 @@ pub struct Appearance {
/// The [`Background`] of the text input.
pub background: Background,
/// The border radius of the text input.
pub border_radius: BorderRadius,
pub border_radius: Radius,
/// The border offset
pub border_offset: Option<f32>,
/// The border width of the text input.

View file

@ -8,7 +8,7 @@ pub fn toggler<'a, Message>(
label: impl Into<Option<String>>,
is_checked: bool,
f: impl Fn(bool) -> Message + 'a,
) -> widget::Toggler<'a, Message, Renderer> {
) -> widget::Toggler<'a, Message, crate::Theme, Renderer> {
widget::Toggler::new(label, is_checked, f)
.size(24)
.spacing(12)

View file

@ -5,6 +5,7 @@ use super::icon;
use crate::{theme, widget, Element, Renderer, Theme};
use apply::Apply;
use iced::{alignment, Alignment, Background, Color, Length};
use iced_core::{Border, Shadow};
use std::borrow::Cow;
#[must_use]
@ -29,7 +30,7 @@ impl<'a, Message: 'static + Clone> Warning<'a, Message> {
}
/// A custom button that has the desired default spacing and padding.
pub fn into_widget(self) -> widget::Container<'a, Message, 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 close_button = icon::from_name("window-close-symbolic")
@ -62,8 +63,15 @@ pub fn warning_container(theme: &Theme) -> widget::container::Appearance {
icon_color: Some(theme.cosmic().warning.on.into()),
text_color: Some(theme.cosmic().warning.on.into()),
background: Some(Background::Color(theme.cosmic().warning_color().into())),
border_radius: cosmic.corner_radii.radius_0.into(),
border_width: 0.0,
border_color: Color::TRANSPARENT,
border: Border {
color: Color::TRANSPARENT,
width: 1.0,
radius: cosmic.corner_radii.radius_0.into(),
},
shadow: Shadow {
color: Color::TRANSPARENT,
offset: iced::Vector::new(0.0, 0.0),
blur_radius: 0.0,
},
}
}