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] [dependencies]
apply = "0.3.0" apply = "0.3.0"
fraction = "0.14.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" once_cell = "1.18"
slotmap = "1.0.6" slotmap = "1.0.6"
env_logger = "0.10" 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 # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [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")))] #[cfg(not(any(feature = "multi-window", feature = "wayland")))]
use iced::Application as IcedApplication; use iced::Application as IcedApplication;
use iced_futures::event::listen_raw; use iced_futures::event::listen_raw;
use iced_futures::futures::executor::block_on;
#[cfg(not(feature = "wayland"))] #[cfg(not(feature = "wayland"))]
use iced_runtime::command::Action; use iced_runtime::command::Action;
#[cfg(not(feature = "wayland"))] #[cfg(not(feature = "wayland"))]
@ -86,6 +85,7 @@ where
fn new((mut core, flags): Self::Flags) -> (Self, iced::Command<Self::Message>) { fn new((mut core, flags): Self::Flags) -> (Self, iced::Command<Self::Message>) {
#[cfg(feature = "dbus-config")] #[cfg(feature = "dbus-config")]
{ {
use iced_futures::futures::executor::block_on;
core.settings_daemon = block_on(cosmic_config::dbus::settings_daemon_proxy()).ok(); 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; pub use cosmic_panel_config;
use cosmic_panel_config::{CosmicPanelBackground, PanelAnchor, PanelSize}; use cosmic_panel_config::{CosmicPanelBackground, PanelAnchor, PanelSize};
use iced_core::Padding; use iced_core::{Padding, Shadow};
use iced_style::container::Appearance; use iced_style::container::Appearance;
use iced_widget::runtime::command::platform_specific::wayland::popup::{ use iced_widget::runtime::command::platform_specific::wayland::popup::{
SctkPopupSettings, SctkPositioner, SctkPopupSettings, SctkPositioner,
@ -142,7 +142,7 @@ impl Context {
pub fn popup_container<'a, Message: 'static>( pub fn popup_container<'a, Message: 'static>(
&self, &self,
content: impl Into<Element<'a, Message>>, content: impl Into<Element<'a, Message>>,
) -> Container<'a, Message, Renderer> { ) -> Container<'a, Message, crate::Theme, Renderer> {
let (vertical_align, horizontal_align) = match self.anchor { let (vertical_align, horizontal_align) = match self.anchor {
PanelAnchor::Left => (Vertical::Center, Horizontal::Left), PanelAnchor::Left => (Vertical::Center, Horizontal::Left),
PanelAnchor::Right => (Vertical::Center, Horizontal::Right), PanelAnchor::Right => (Vertical::Center, Horizontal::Right),
@ -150,20 +150,25 @@ impl Context {
PanelAnchor::Bottom => (Vertical::Bottom, Horizontal::Center), PanelAnchor::Bottom => (Vertical::Bottom, Horizontal::Center),
}; };
Container::<Message, Renderer>::new(Container::<Message, Renderer>::new(content).style( Container::<Message, _, Renderer>::new(
theme::Container::custom(|theme| { Container::<Message, _, Renderer>::new(content).style(theme::Container::custom(
let cosmic = theme.cosmic(); |theme| {
let corners = cosmic.corner_radii.clone(); let cosmic = theme.cosmic();
Appearance { let corners = cosmic.corner_radii.clone();
text_color: Some(cosmic.background.on.into()), Appearance {
background: Some(Color::from(cosmic.background.base).into()), text_color: Some(cosmic.background.on.into()),
border_radius: corners.radius_m.into(), background: Some(Color::from(cosmic.background.base).into()),
border_width: 1.0, border: iced::Border {
border_color: cosmic.background.divider.into(), radius: corners.radius_m.into(),
icon_color: Some(cosmic.background.on.into()), width: 1.0,
} color: cosmic.background.divider.into(),
}), },
)) shadow: Shadow::default(),
icon_color: Some(cosmic.background.on.into()),
}
},
)),
)
.width(Length::Shrink) .width(Length::Shrink)
.height(Length::Shrink) .height(Length::Shrink)
.align_x(horizontal_align) .align_x(horizontal_align)
@ -306,7 +311,7 @@ pub fn menu_button<'a, Message>(
pub fn padded_control<'a, Message>( pub fn padded_control<'a, Message>(
content: impl Into<Element<'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) crate::widget::container(content)
.padding(menu_control_padding()) .padding(menu_control_padding())
.width(Length::Fill) .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. /// 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 where
Self: Sized, Self: Sized,
{ {

View file

@ -3,12 +3,9 @@
//! Subscribe to common application keyboard shortcuts. //! Subscribe to common application keyboard shortcuts.
use iced::{ use iced::{event, keyboard, mouse, Command, Event, Subscription};
event,
keyboard::{self, KeyCode},
mouse, Command, Event, Subscription,
};
use iced_core::{ use iced_core::{
keyboard::key::Named,
widget::{operation, Id, Operation}, widget::{operation, Id, Operation},
Rectangle, Rectangle,
}; };
@ -32,10 +29,11 @@ pub fn subscription() -> Subscription<Message> {
match event { match event {
Event::Keyboard(keyboard::Event::KeyPressed { Event::Keyboard(keyboard::Event::KeyPressed {
key_code, key: keyboard::Key::Named(key),
modifiers, modifiers,
}) => match key_code { ..
KeyCode::Tab => { }) => match key {
Named::Tab => {
return Some(if modifiers.shift() { return Some(if modifiers.shift() {
Message::FocusPrevious Message::FocusPrevious
} else { } else {
@ -43,24 +41,23 @@ pub fn subscription() -> Subscription<Message> {
}); });
} }
KeyCode::Escape => { Named::Escape => {
return Some(Message::Escape); return Some(Message::Escape);
} }
KeyCode::F11 => { Named::F11 => {
return Some(Message::Fullscreen); 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 { .. }) => { Event::Mouse(mouse::Event::ButtonPressed { .. }) => {
return Some(Message::Unfocus); return Some(Message::Unfocus);

View file

@ -69,5 +69,5 @@ pub use theme::{style, Theme};
pub mod widget; pub mod widget;
type Paragraph = <Renderer as iced_core::text::Renderer>::Paragraph; type Paragraph = <Renderer as iced_core::text::Renderer>::Paragraph;
pub type Renderer = iced::Renderer<Theme>; pub type Renderer = iced::Renderer;
pub type Element<'a, Message> = iced::Element<'a, Message, 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 crate::theme::{CosmicComponent, Theme, TRANSPARENT_COMPONENT};
use cosmic_theme::composite::over; use cosmic_theme::composite::over;
use iced_core::gradient::Linear; use iced_core::Border;
use iced_core::BorderRadius;
use iced_core::Radians;
use iced_core::{Background, Color}; use iced_core::{Background, Color};
use iced_style::application; use iced_style::application;
use iced_style::button as iced_button; use iced_style::button as iced_button;
@ -25,7 +23,7 @@ use iced_style::slider::Rail;
use iced_style::svg; use iced_style::svg;
use iced_style::text_input; use iced_style::text_input;
use iced_style::toggler; use iced_style::toggler;
use std::f32::consts::PI;
use std::rc::Rc; use std::rc::Rc;
#[derive(Default)] #[derive(Default)]
@ -203,14 +201,17 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.accent.on.into(), icon_color: cosmic.accent.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.accent.base color: if is_checked {
} else { cosmic.accent.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Secondary => checkbox::Appearance { Checkbox::Secondary => checkbox::Appearance {
@ -220,9 +221,11 @@ impl checkbox::StyleSheet for Theme {
cosmic.background.base.into() cosmic.background.base.into()
}), }),
icon_color: cosmic.background.on.into(), icon_color: cosmic.background.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: cosmic.button.border.into(), width: if is_checked { 0.0 } else { 1.0 },
color: cosmic.button.border.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Success => checkbox::Appearance { Checkbox::Success => checkbox::Appearance {
@ -232,14 +235,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.success.on.into(), icon_color: cosmic.success.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.success.base color: if is_checked {
} else { cosmic.success.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Danger => checkbox::Appearance { Checkbox::Danger => checkbox::Appearance {
@ -249,14 +254,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.destructive.on.into(), icon_color: cosmic.destructive.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.destructive.base color: if is_checked {
} else { cosmic.destructive.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
} }
@ -274,14 +281,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.accent.on.into(), icon_color: cosmic.accent.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.accent.base color: if is_checked {
} else { cosmic.accent.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Secondary => checkbox::Appearance { Checkbox::Secondary => checkbox::Appearance {
@ -291,14 +300,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
self.current_container().base color: if is_checked {
} else { self.current_container().base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Success => checkbox::Appearance { Checkbox::Success => checkbox::Appearance {
@ -308,14 +319,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.success.on.into(), icon_color: cosmic.success.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.success.base color: if is_checked {
} else { cosmic.success.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
Checkbox::Danger => checkbox::Appearance { Checkbox::Danger => checkbox::Appearance {
@ -325,14 +338,16 @@ impl checkbox::StyleSheet for Theme {
cosmic.button.base.into() cosmic.button.base.into()
}), }),
icon_color: cosmic.destructive.on.into(), icon_color: cosmic.destructive.on.into(),
border_radius: corners.radius_xs.into(), border: Border {
border_width: if is_checked { 0.0 } else { 1.0 }, radius: corners.radius_xs.into(),
border_color: if is_checked { width: if is_checked { 0.0 } else { 1.0 },
cosmic.destructive.base color: if is_checked {
} else { cosmic.destructive.base
cosmic.button.border } else {
} cosmic.button.border
.into(), }
.into(),
},
text_color: None, text_color: None,
}, },
} }
@ -371,61 +386,50 @@ impl container::StyleSheet for Theme {
match style { match style {
Container::Transparent => container::Appearance::default(), Container::Transparent => container::Appearance::default(),
Container::Custom(f) => f(self), Container::Custom(f) => f(self),
Container::Background => { Container::Background => container::Appearance {
let palette = self.cosmic(); icon_color: Some(Color::from(cosmic.background.on)),
text_color: Some(Color::from(cosmic.background.on)),
container::Appearance { background: Some(iced::Background::Color(cosmic.background.base.into())),
icon_color: Some(Color::from(palette.background.on)), border: Border {
text_color: Some(Color::from(palette.background.on)), radius: cosmic.corner_radii.radius_xs.into(),
background: Some(iced::Background::Color(palette.background.base.into())), ..Default::default()
border_radius: cosmic.corner_radii.radius_xs.into(), },
border_width: 0.0, shadow: Default::default(),
border_color: Color::TRANSPARENT, },
}
}
Container::HeaderBar => { Container::HeaderBar => {
let palette = self.cosmic(); let header_top = cosmic.background.base;
let header_top = palette.background.base;
container::Appearance { container::Appearance {
icon_color: Some(Color::from(palette.accent.base)), icon_color: Some(Color::from(cosmic.accent.base)),
text_color: Some(Color::from(palette.background.on)), text_color: Some(Color::from(cosmic.background.on)),
background: Some(iced::Background::Color(header_top.into())), background: Some(iced::Background::Color(header_top.into())),
border_radius: BorderRadius::from([ border: Border {
palette.corner_radii.radius_xs[0], radius: cosmic.corner_radii.radius_xs.into(),
palette.corner_radii.radius_xs[3], ..Default::default()
0.0, },
0.0, shadow: Default::default(),
]),
border_width: 0.0,
border_color: Color::TRANSPARENT,
} }
} }
Container::Primary => { Container::Primary => container::Appearance {
let palette = self.cosmic(); icon_color: Some(Color::from(cosmic.primary.on)),
text_color: Some(Color::from(cosmic.primary.on)),
container::Appearance { background: Some(iced::Background::Color(cosmic.primary.base.into())),
icon_color: Some(Color::from(palette.primary.on)), border: Border {
text_color: Some(Color::from(palette.primary.on)), radius: cosmic.corner_radii.radius_xs.into(),
background: Some(iced::Background::Color(palette.primary.base.into())), ..Default::default()
border_radius: cosmic.corner_radii.radius_xs.into(), },
border_width: 0.0, shadow: Default::default(),
border_color: Color::TRANSPARENT, },
} Container::Secondary => container::Appearance {
} icon_color: Some(Color::from(cosmic.secondary.on)),
Container::Secondary => { text_color: Some(Color::from(cosmic.secondary.on)),
let palette = self.cosmic(); background: Some(iced::Background::Color(cosmic.secondary.base.into())),
border: Border {
container::Appearance { radius: cosmic.corner_radii.radius_xs.into(),
icon_color: Some(Color::from(palette.secondary.on)), ..Default::default()
text_color: Some(Color::from(palette.secondary.on)), },
background: Some(iced::Background::Color(palette.secondary.base.into())), shadow: Default::default(),
border_radius: cosmic.corner_radii.radius_xs.into(), },
border_width: 0.0,
border_color: Color::TRANSPARENT,
}
}
Container::Dropdown => { Container::Dropdown => {
let theme = self.cosmic(); let theme = self.cosmic();
@ -433,58 +437,63 @@ impl container::StyleSheet for Theme {
icon_color: None, icon_color: None,
text_color: None, text_color: None,
background: Some(iced::Background::Color(theme.primary.base.into())), background: Some(iced::Background::Color(theme.primary.base.into())),
border_radius: theme.corner_radii.radius_xs.into(), border: Border {
border_width: 1.0, radius: cosmic.corner_radii.radius_xs.into(),
border_color: theme.bg_divider().into(), ..Default::default()
} },
} shadow: Default::default(),
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,
} }
} }
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 => { Container::Card => {
let palette = self.cosmic(); let cosmic = self.cosmic();
match self.layer { match self.layer {
cosmic_theme::Layer::Background => container::Appearance { cosmic_theme::Layer::Background => container::Appearance {
icon_color: Some(Color::from(palette.background.component.on)), icon_color: Some(Color::from(cosmic.background.component.on)),
text_color: Some(Color::from(palette.background.component.on)), text_color: Some(Color::from(cosmic.background.component.on)),
background: Some(iced::Background::Color( background: Some(iced::Background::Color(
palette.background.component.base.into(), cosmic.background.component.base.into(),
)), )),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}, },
cosmic_theme::Layer::Primary => container::Appearance { cosmic_theme::Layer::Primary => container::Appearance {
icon_color: Some(Color::from(palette.primary.component.on)), icon_color: Some(Color::from(cosmic.primary.component.on)),
text_color: Some(Color::from(palette.primary.component.on)), text_color: Some(Color::from(cosmic.primary.component.on)),
background: Some(iced::Background::Color( background: Some(iced::Background::Color(
palette.primary.component.base.into(), cosmic.primary.component.base.into(),
)), )),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}, },
cosmic_theme::Layer::Secondary => container::Appearance { cosmic_theme::Layer::Secondary => container::Appearance {
icon_color: Some(Color::from(palette.secondary.component.on)), icon_color: Some(Color::from(cosmic.secondary.component.on)),
text_color: Some(Color::from(palette.secondary.component.on)), text_color: Some(Color::from(cosmic.secondary.component.on)),
background: Some(iced::Background::Color( background: Some(iced::Background::Color(
palette.secondary.component.base.into(), cosmic.secondary.component.base.into(),
)), )),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}, },
} }
} }
@ -581,9 +590,10 @@ impl menu::StyleSheet for Theme {
menu::Appearance { menu::Appearance {
text_color: cosmic.on_bg_color().into(), text_color: cosmic.on_bg_color().into(),
background: Background::Color(cosmic.background.base.into()), background: Background::Color(cosmic.background.base.into()),
border_width: 0.0, border: Border {
border_radius: cosmic.corner_radii.radius_m.into(), radius: cosmic.corner_radii.radius_m.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
selected_text_color: cosmic.accent.base.into(), selected_text_color: cosmic.accent.base.into(),
selected_background: Background::Color(cosmic.background.component.hover.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(), text_color: cosmic.on_bg_color().into(),
background: Color::TRANSPARENT.into(), background: Color::TRANSPARENT.into(),
placeholder_color: cosmic.on_bg_color().into(), placeholder_color: cosmic.on_bg_color().into(),
border_radius: cosmic.corner_radii.radius_m.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_m.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
// icon_size: 0.7, // TODO: how to replace // icon_size: 0.7, // TODO: how to replace
handle_color: cosmic.on_bg_color().into(), handle_color: cosmic.on_bg_color().into(),
} }
@ -740,9 +751,11 @@ impl pane_grid::StyleSheet for Theme {
let theme = self.cosmic(); let theme = self.cosmic();
pane_grid::Appearance { pane_grid::Appearance {
background: Background::Color(theme.bg_color().into()), background: Background::Color(theme.bg_color().into()),
border_width: 2.0, border: Border {
border_color: theme.bg_divider().into(), radius: theme.corner_radii.radius_0.into(),
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; neutral_5.alpha = 0.7;
let mut a = scrollable::Scrollbar { let mut a = scrollable::Scrollbar {
background: None, background: None,
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
scroller: scrollable::Scroller { scroller: scrollable::Scroller {
color: neutral_5.into(), color: neutral_5.into(),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
}, },
}; };
@ -889,14 +904,16 @@ impl scrollable::StyleSheet for Theme {
} }
let mut a = scrollable::Scrollbar { let mut a = scrollable::Scrollbar {
background: None, background: None,
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
scroller: scrollable::Scroller { scroller: scrollable::Scroller {
color: neutral_5.into(), color: neutral_5.into(),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, radius: cosmic.corner_radii.radius_s.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
}, },
}; };
if matches!(style, Scrollable::Permanent) { if matches!(style, Scrollable::Permanent) {
@ -934,6 +951,10 @@ impl svg::StyleSheet for Theme {
Svg::Custom(appearance) => appearance(self), 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 { match style {
TextInput::Default => text_input::Appearance { TextInput::Default => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_s.into(), border: Border {
border_width: 1.0, radius: palette.corner_radii.radius_s.into(),
border_color: self.current_container().component.divider.into(), width: 1.0,
color: self.current_container().component.divider.into(),
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
TextInput::Search => text_input::Appearance { TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_m.into(), border: Border {
border_width: 0.0, radius: palette.corner_radii.radius_m.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
} }
@ -1013,16 +1037,19 @@ impl text_input::StyleSheet for Theme {
match style { match style {
TextInput::Default => text_input::Appearance { TextInput::Default => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_s.into(), border: Border {
border_width: 1.0, radius: palette.corner_radii.radius_s.into(),
border_color: palette.accent.base.into(), width: 1.0,
color: self.current_container().on.into(),
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
TextInput::Search => text_input::Appearance { TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_m.into(), border: Border {
border_width: 0.0, radius: palette.corner_radii.radius_m.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
} }
@ -1036,16 +1063,19 @@ impl text_input::StyleSheet for Theme {
match style { match style {
TextInput::Default => text_input::Appearance { TextInput::Default => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_s.into(), border: Border {
border_width: 1.0, radius: palette.corner_radii.radius_s.into(),
border_color: palette.accent.base.into(), width: 1.0,
color: palette.accent.base.into(),
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
TextInput::Search => text_input::Appearance { TextInput::Search => text_input::Appearance {
background: Color::from(bg).into(), background: Color::from(bg).into(),
border_radius: palette.corner_radii.radius_m.into(), border: Border {
border_width: 0.0, radius: palette.corner_radii.radius_m.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
icon_color: self.current_container().on.into(), icon_color: self.current_container().on.into(),
}, },
} }
@ -1121,9 +1151,11 @@ impl iced_style::text_editor::StyleSheet for Theme {
let cosmic = self.cosmic(); let cosmic = self.cosmic();
iced_style::text_editor::Appearance { iced_style::text_editor::Appearance {
background: iced::Color::from(cosmic.bg_color()).into(), background: iced::Color::from(cosmic.bg_color()).into(),
border_radius: cosmic.corner_radii.radius_0.into(), border: Border {
border_width: f32::from(cosmic.space_xxxs()), radius: cosmic.corner_radii.radius_0.into(),
border_color: iced::Color::from(cosmic.bg_divider()), 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(); let cosmic = self.cosmic();
iced_style::text_editor::Appearance { iced_style::text_editor::Appearance {
background: iced::Color::from(cosmic.bg_color()).into(), background: iced::Color::from(cosmic.bg_color()).into(),
border_radius: cosmic.corner_radii.radius_0.into(), border: Border {
border_width: f32::from(cosmic.space_xxxs()), radius: cosmic.corner_radii.radius_0.into(),
border_color: iced::Color::from(cosmic.accent.base), 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::widget::segmented_button::{Appearance, ItemAppearance, StyleSheet};
use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance}; use crate::{theme::Theme, widget::segmented_button::ItemStatusAppearance};
use iced_core::{Background, BorderRadius}; use iced_core::{border::Radius, Background};
#[derive(Default)] #[derive(Default)]
pub enum SegmentedButton { pub enum SegmentedButton {
@ -66,9 +66,7 @@ impl StyleSheet for Theme {
inactive: ItemStatusAppearance { inactive: ItemStatusAppearance {
background: Some(Background::Color(neutral_5.into())), background: Some(Background::Color(neutral_5.into())),
first: ItemAppearance { first: ItemAppearance {
border_radius: BorderRadius::from([ border_radius: Radius::from([rad_m[0], rad_0[1], rad_0[2], rad_m[3]]),
rad_m[0], rad_0[1], rad_0[2], rad_m[3],
]),
..Default::default() ..Default::default()
}, },
middle: ItemAppearance { middle: ItemAppearance {
@ -76,9 +74,7 @@ impl StyleSheet for Theme {
..Default::default() ..Default::default()
}, },
last: ItemAppearance { last: ItemAppearance {
border_radius: BorderRadius::from([ border_radius: Radius::from([rad_0[0], rad_m[1], rad_m[2], rad_0[3]]),
rad_0[0], rad_m[1], rad_m[2], rad_0[3],
]),
..Default::default() ..Default::default()
}, },
text_color: cosmic.on_bg_color().into(), text_color: cosmic.on_bg_color().into(),
@ -123,9 +119,7 @@ impl StyleSheet for Theme {
inactive: ItemStatusAppearance { inactive: ItemStatusAppearance {
background: Some(Background::Color(neutral_5.into())), background: Some(Background::Color(neutral_5.into())),
first: ItemAppearance { first: ItemAppearance {
border_radius: BorderRadius::from([ border_radius: Radius::from([rad_m[0], rad_m[1], rad_0[0], rad_0[0]]),
rad_m[0], rad_m[1], rad_0[0], rad_0[0],
]),
..Default::default() ..Default::default()
}, },
middle: ItemAppearance { middle: ItemAppearance {
@ -133,9 +127,7 @@ impl StyleSheet for Theme {
..Default::default() ..Default::default()
}, },
last: ItemAppearance { last: ItemAppearance {
border_radius: BorderRadius::from([ border_radius: Radius::from([rad_0[0], rad_0[1], rad_m[2], rad_m[3]]),
rad_0[0], rad_0[1], rad_m[2], rad_m[3],
]),
..Default::default() ..Default::default()
}, },
text_color: cosmic.on_bg_color().into(), text_color: cosmic.on_bg_color().into(),
@ -153,7 +145,7 @@ impl StyleSheet for Theme {
mod horizontal { mod horizontal {
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance}; 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 { pub fn selection_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance {
let mut neutral_5 = cosmic.palette.neutral_5; let mut neutral_5 = cosmic.palette.neutral_5;
@ -163,7 +155,7 @@ mod horizontal {
ItemStatusAppearance { ItemStatusAppearance {
background: Some(Background::Color(neutral_5.into())), background: Some(Background::Color(neutral_5.into())),
first: ItemAppearance { 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() ..Default::default()
}, },
middle: ItemAppearance { middle: ItemAppearance {
@ -171,7 +163,7 @@ mod horizontal {
..Default::default() ..Default::default()
}, },
last: ItemAppearance { 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() ..Default::default()
}, },
text_color: cosmic.accent.base.into(), text_color: cosmic.accent.base.into(),
@ -186,17 +178,17 @@ mod horizontal {
ItemStatusAppearance { ItemStatusAppearance {
background: Some(Background::Color(neutral_5.into())), background: Some(Background::Color(neutral_5.into())),
first: ItemAppearance { 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())), border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default() ..Default::default()
}, },
middle: ItemAppearance { 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())), border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default() ..Default::default()
}, },
last: ItemAppearance { 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())), border_bottom: Some((4.0, cosmic.accent.base.into())),
..Default::default() ..Default::default()
}, },
@ -229,7 +221,7 @@ pub fn hover(cosmic: &cosmic_theme::Theme, default: &ItemStatusAppearance) -> It
mod vertical { mod vertical {
use crate::widget::segmented_button::{ItemAppearance, ItemStatusAppearance}; 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 { pub fn selection_active(cosmic: &cosmic_theme::Theme) -> ItemStatusAppearance {
let mut neutral_5 = cosmic.palette.neutral_5; let mut neutral_5 = cosmic.palette.neutral_5;
@ -239,7 +231,7 @@ mod vertical {
ItemStatusAppearance { ItemStatusAppearance {
background: Some(Background::Color(neutral_5.into())), background: Some(Background::Color(neutral_5.into())),
first: ItemAppearance { 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() ..Default::default()
}, },
middle: ItemAppearance { middle: ItemAppearance {
@ -247,7 +239,7 @@ mod vertical {
..Default::default() ..Default::default()
}, },
last: ItemAppearance { 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() ..Default::default()
}, },
text_color: cosmic.accent.base.into(), text_color: cosmic.accent.base.into(),

View file

@ -16,7 +16,7 @@ pub fn aspect_ratio_container<'a, Message: 'static, T>(
ratio: f32, ratio: f32,
) -> AspectRatio<'a, Message, crate::Renderer> ) -> AspectRatio<'a, Message, crate::Renderer>
where where
T: Into<Element<'a, Message, crate::Renderer>>, T: Into<Element<'a, Message, crate::Theme, crate::Renderer>>,
{ {
AspectRatio::new(content, ratio) AspectRatio::new(content, ratio)
} }
@ -28,16 +28,14 @@ where
pub struct AspectRatio<'a, Message, Renderer> pub struct AspectRatio<'a, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
ratio: f32, ratio: f32,
container: Container<'a, Message, Renderer>, container: Container<'a, Message, crate::Theme, Renderer>,
} }
impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer> impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn constrain_limits(&self, size: Size) -> Size { fn constrain_limits(&self, size: Size) -> Size {
let Size { let Size {
@ -56,12 +54,11 @@ where
impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer> impl<'a, Message, Renderer> AspectRatio<'a, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
/// Creates an empty [`Container`]. /// Creates an empty [`Container`].
pub(crate) fn new<T>(content: T, ratio: f32) -> Self pub(crate) fn new<T>(content: T, ratio: f32) -> Self
where where
T: Into<Element<'a, Message, Renderer>>, T: Into<Element<'a, Message, crate::Theme, Renderer>>,
{ {
AspectRatio { AspectRatio {
ratio, ratio,
@ -134,16 +131,16 @@ where
/// Sets the style of the [`Container`]. /// Sets the style of the [`Container`].
#[must_use] #[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.container = self.container.style(style);
self 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 where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn children(&self) -> Vec<Tree> { fn children(&self) -> Vec<Tree> {
self.container.children() self.container.children()
@ -153,12 +150,8 @@ where
self.container.diff(tree); self.container.diff(tree);
} }
fn width(&self) -> Length { fn size(&self) -> Size<Length> {
Widget::width(&self.container) self.container.size()
}
fn height(&self) -> Length {
Widget::height(&self.container)
} }
fn layout( fn layout(
@ -226,7 +219,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut Renderer, renderer: &mut Renderer,
theme: &Renderer::Theme, theme: &crate::Theme,
renderer_style: &renderer::Style, renderer_style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: mouse::Cursor, cursor_position: mouse::Cursor,
@ -248,19 +241,20 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.container.overlay(tree, layout, renderer) self.container.overlay(tree, layout, renderer)
} }
} }
impl<'a, Message, Renderer> From<AspectRatio<'a, Message, Renderer>> impl<'a, Message, Renderer> From<AspectRatio<'a, Message, Renderer>>
for Element<'a, Message, Renderer> for Element<'a, Message, crate::Theme, Renderer>
where where
Message: 'a, Message: 'a,
Renderer: 'a + iced_core::Renderer, 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) Element::new(column)
} }
} }

View file

@ -2,7 +2,7 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
//! Change the apperance of a button. //! 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; use crate::theme::THEME;
@ -17,7 +17,7 @@ pub struct Appearance {
pub background: Option<Background>, pub background: Option<Background>,
/// The border radius of the button. /// The border radius of the button.
pub border_radius: BorderRadius, pub border_radius: Radius,
/// The border width of the button. /// The border width of the button.
pub border_width: f32, pub border_width: f32,
@ -39,13 +39,13 @@ pub struct Appearance {
} }
impl Appearance { impl Appearance {
// TODO: `BorderRadius` is not `const fn` compatible. // TODO: `Radius` is not `const fn` compatible.
pub fn new() -> Self { pub fn new() -> Self {
let rad_0 = THEME.with(|t| t.borrow().cosmic().corner_radii.radius_0); let rad_0 = THEME.with(|t| t.borrow().cosmic().corner_radii.radius_0);
Self { Self {
shadow_offset: Vector::new(0.0, 0.0), shadow_offset: Vector::new(0.0, 0.0),
background: None, background: None,
border_radius: BorderRadius::from(rad_0), border_radius: Radius::from(rad_0),
border_width: 0.0, border_width: 0.0,
border_color: Color::TRANSPARENT, border_color: Color::TRANSPARENT,
outline_width: 0.0, outline_width: 0.0,

View file

@ -10,13 +10,13 @@ use iced_runtime::core::widget::Id;
use iced_runtime::{keyboard, Command}; use iced_runtime::{keyboard, Command};
use iced_core::event::{self, Event}; use iced_core::event::{self, Event};
use iced_core::mouse;
use iced_core::overlay;
use iced_core::renderer::{self, Quad}; use iced_core::renderer::{self, Quad};
use iced_core::touch; use iced_core::touch;
use iced_core::widget::tree::{self, Tree}; use iced_core::widget::tree::{self, Tree};
use iced_core::widget::Operation; use iced_core::widget::Operation;
use iced_core::{layout, svg}; use iced_core::{layout, svg};
use iced_core::{mouse, Border};
use iced_core::{overlay, Shadow};
use iced_core::{ use iced_core::{
Background, Clipboard, Color, Element, Layout, Length, Padding, Point, Rectangle, Shell, Background, Clipboard, Color, Element, Layout, Length, Padding, Point, Rectangle, Shell,
Vector, Widget, Vector, Widget,
@ -43,7 +43,6 @@ enum Variant<Message> {
pub struct Button<'a, Message, Renderer> pub struct Button<'a, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
id: Id, id: Id,
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
@ -52,23 +51,22 @@ where
description: Option<iced_accessibility::Description<'a>>, description: Option<iced_accessibility::Description<'a>>,
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
label: Option<Vec<iced_accessibility::accesskit::NodeId>>, label: Option<Vec<iced_accessibility::accesskit::NodeId>>,
content: Element<'a, Message, Renderer>, content: Element<'a, Message, crate::Theme, Renderer>,
on_press: Option<Message>, on_press: Option<Message>,
width: Length, width: Length,
height: Length, height: Length,
padding: Padding, padding: Padding,
selected: bool, selected: bool,
style: <Renderer::Theme as StyleSheet>::Style, style: <crate::Theme as StyleSheet>::Style,
variant: Variant<Message>, variant: Variant<Message>,
} }
impl<'a, Message, Renderer> Button<'a, Message, Renderer> impl<'a, Message, Renderer> Button<'a, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
/// Creates a new [`Button`] with the given content. /// 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 { Self {
id: Id::unique(), id: Id::unique(),
#[cfg(feature = "a11y")] #[cfg(feature = "a11y")]
@ -83,13 +81,13 @@ where
height: Length::Shrink, height: Length::Shrink,
padding: Padding::new(5.0), padding: Padding::new(5.0),
selected: false, selected: false,
style: <Renderer::Theme as StyleSheet>::Style::default(), style: <crate::Theme as StyleSheet>::Style::default(),
variant: Variant::Normal, variant: Variant::Normal,
} }
} }
pub fn new_image( pub fn new_image(
content: impl Into<Element<'a, Message, Renderer>>, content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
on_remove: Option<Message>, on_remove: Option<Message>,
) -> Self { ) -> Self {
Self { Self {
@ -106,7 +104,7 @@ where
height: Length::Shrink, height: Length::Shrink,
padding: Padding::new(5.0), padding: Padding::new(5.0),
selected: false, selected: false,
style: <Renderer::Theme as StyleSheet>::Style::default(), style: <crate::Theme as StyleSheet>::Style::default(),
variant: Variant::Image { variant: Variant::Image {
on_remove, on_remove,
close_icon: crate::widget::icon::from_name("window-close-symbolic") close_icon: crate::widget::icon::from_name("window-close-symbolic")
@ -180,7 +178,7 @@ where
} }
/// Sets the style variant of this [`Button`]. /// 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.style = style;
self 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 where
Message: 'a + Clone, Message: 'a + Clone,
Renderer: 'a + iced_core::Renderer + svg::Renderer, Renderer: 'a + iced_core::Renderer + svg::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn tag(&self) -> tree::Tag { fn tag(&self) -> tree::Tag {
tree::Tag::of::<State>() tree::Tag::of::<State>()
@ -238,12 +236,8 @@ where
tree.diff_children(std::slice::from_mut(&mut self.content)); tree.diff_children(std::slice::from_mut(&mut self.content));
} }
fn width(&self) -> Length { fn size(&self) -> iced_core::Size<Length> {
self.width iced_core::Size::new(self.width, self.height)
}
fn height(&self) -> Length {
self.height
} }
fn layout( fn layout(
@ -346,7 +340,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut Renderer, renderer: &mut Renderer,
theme: &Renderer::Theme, theme: &crate::Theme,
renderer_style: &renderer::Style, renderer_style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
@ -400,15 +394,17 @@ where
x: bounds.x + styling.border_width, x: bounds.x + styling.border_width,
y: bounds.y + (bounds.height - 20.0 - styling.border_width), y: bounds.y + (bounds.height - 20.0 - styling.border_width),
}, },
border_radius: [ border: Border {
c_rad.radius_0[0], radius: [
c_rad.radius_s[1], c_rad.radius_0[0],
c_rad.radius_0[2], c_rad.radius_s[1],
c_rad.radius_s[3], c_rad.radius_0[2],
] c_rad.radius_s[3],
.into(), ]
border_width: 0.0, .into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}, },
selection_background, selection_background,
); );
@ -433,9 +429,11 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: c_rad.radius_m.into(), shadow: Default::default(),
border_width: 0.0, border: Border {
border_color: Color::TRANSPARENT, radius: c_rad.radius_m.into(),
..Default::default()
},
}, },
selection_background, selection_background,
); );
@ -473,7 +471,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
self.content.as_widget_mut().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), 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 where
Message: Clone + 'a, Message: Clone + 'a,
Renderer: iced_core::Renderer + svg::Renderer + 'a, Renderer: iced_core::Renderer + svg::Renderer + 'a,
Renderer::Theme: StyleSheet,
{ {
fn from(button: Button<'a, Message, Renderer>) -> Self { fn from(button: Button<'a, Message, Renderer>) -> Self {
Self::new(button) Self::new(button)
@ -660,10 +658,10 @@ pub fn update<'a, Message: Clone>(
} }
return event::Status::Captured; 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() { if let Some(on_press) = on_press.clone() {
let state = state(); 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; state.is_pressed = true;
shell.publish(on_press); shell.publish(on_press);
return event::Status::Captured; return event::Status::Captured;
@ -688,13 +686,12 @@ pub fn draw<'a, Renderer: iced_core::Renderer>(
cursor: mouse::Cursor, cursor: mouse::Cursor,
is_enabled: bool, is_enabled: bool,
is_selected: bool, is_selected: bool,
style_sheet: &dyn StyleSheet<Style = <Renderer::Theme as StyleSheet>::Style>, style_sheet: &dyn StyleSheet<Style = <crate::Theme as StyleSheet>::Style>,
style: &<Renderer::Theme as StyleSheet>::Style, style: &<crate::Theme as StyleSheet>::Style,
state: impl FnOnce() -> &'a State, state: impl FnOnce() -> &'a State,
draw_contents: impl FnOnce(&mut Renderer, Appearance), draw_contents: impl FnOnce(&mut Renderer, Appearance),
) -> Appearance ) -> Appearance
where where
Renderer::Theme: StyleSheet,
{ {
let is_mouse_over = cursor.position().is_some_and(|p| bounds.contains(p)); 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, width: bounds.width + doubled_border_width + doubled_outline_width,
height: bounds.height + doubled_border_width + doubled_outline_width, height: bounds.height + doubled_border_width + doubled_outline_width,
}, },
border_radius: styling.border_radius, border: Border {
border_width: styling.outline_width, width: styling.outline_width,
border_color: styling.outline_color, color: styling.outline_color,
radius: styling.border_radius,
},
shadow: Default::default(),
}, },
Color::TRANSPARENT, Color::TRANSPARENT,
); );
@ -743,9 +743,11 @@ where
width: bounds.width, width: bounds.width,
height: bounds.height, height: bounds.height,
}, },
border_radius: styling.border_radius, border: Border {
border_width: 0.0, radius: styling.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
Background::Color([0.0, 0.0, 0.0, 0.5].into()), Background::Color([0.0, 0.0, 0.0, 0.5].into()),
); );
@ -756,9 +758,11 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: styling.border_radius, border: Border {
border_width: 0.0, radius: styling.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}, },
background, background,
); );
@ -771,9 +775,12 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: styling.border_radius, border: Border {
border_width: styling.border_width, width: styling.border_width,
border_color: styling.border_color, color: styling.border_color,
radius: styling.border_radius,
},
shadow: Default::default(),
}, },
Color::TRANSPARENT, Color::TRANSPARENT,
); );
@ -795,11 +802,14 @@ pub fn layout<Renderer>(
) -> layout::Node { ) -> layout::Node {
let limits = limits.width(width).height(height); 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 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]) 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::renderer::Quad;
use iced_core::widget::{tree, Tree}; use iced_core::widget::{tree, Tree};
use iced_core::{ use iced_core::{
layout, mouse, renderer, Background, Clipboard, Color, Layout, Length, Radians, Rectangle, layout, mouse, renderer, Background, Border, Clipboard, Color, Layout, Length, Radians,
Renderer, Shell, Vector, Widget, Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
}; };
use iced_style::slider::{HandleShape, RailBackground}; use iced_style::slider::{HandleShape, RailBackground};
@ -414,7 +414,7 @@ where
) )
.into() .into()
}) })
.collect(), .collect::<Vec<_>>(),
) )
.spacing(spacing.space_xxs), .spacing(spacing.space_xxs),
) )
@ -487,7 +487,7 @@ pub struct ColorPicker<'a, Message> {
must_clear_cache: Rc<AtomicBool>, 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 where
Message: Clone + 'static, Message: Clone + 'static,
{ {
@ -507,14 +507,6 @@ where
vec![Tree::new(&self.inner)] vec![Tree::new(&self.inner)]
} }
fn width(&self) -> Length {
self.width
}
fn height(&self) -> Length {
Length::Shrink
}
fn layout( fn layout(
&self, &self,
tree: &mut Tree, tree: &mut Tree,
@ -531,7 +523,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut crate::Renderer, renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme, theme: &crate::Theme,
style: &renderer::Style, style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor: mouse::Cursor, cursor: mouse::Cursor,
@ -611,9 +603,12 @@ where
width: handle_radius.mul_add(2.0, 1.0), width: handle_radius.mul_add(2.0, 1.0),
height: 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: Border {
border_width: 1.0, width: 1.0,
border_color: t.palette.neutral_5.into(), color: t.palette.neutral_5.into(),
radius: (1.0 + handle_radius).into(),
},
shadow: Shadow::default(),
}, },
Color::TRANSPARENT, Color::TRANSPARENT,
); );
@ -625,9 +620,12 @@ where
width: handle_radius * 2.0, width: handle_radius * 2.0,
height: handle_radius * 2.0, height: handle_radius * 2.0,
}, },
border_radius: handle_radius.into(), border: Border {
border_width: 1.0, width: 1.0,
border_color: t.palette.neutral_10.into(), color: t.palette.neutral_10.into(),
radius: handle_radius.into(),
},
shadow: Shadow::default(),
}, },
Color::TRANSPARENT, Color::TRANSPARENT,
); );
@ -638,7 +636,7 @@ where
state: &'b mut Tree, state: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &crate::Renderer, 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 self.inner
.as_widget_mut() .as_widget_mut()
.overlay(&mut state.children[0], layout, renderer) .overlay(&mut state.children[0], layout, renderer)
@ -723,6 +721,10 @@ where
_ => event::Status::Ignored, _ => event::Status::Ignored,
} }
} }
fn size(&self) -> Size<Length> {
Size::new(self.width, Length::Shrink)
}
} }
#[derive(Debug, Default)] #[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 where
Message: 'static + Clone, 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) Element::new(picker)
} }
} }

View file

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

View file

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

View file

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

View file

@ -3,7 +3,7 @@
// SPDX-License-Identifier: MPL-2.0 AND MIT // SPDX-License-Identifier: MPL-2.0 AND MIT
//! Change the appearance of menus. //! Change the appearance of menus.
use iced_core::{Background, BorderRadius, Color}; use iced_core::{border::Radius, Background, Color};
/// The appearance of a menu. /// The appearance of a menu.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -15,7 +15,7 @@ pub struct Appearance {
/// Menu border width /// Menu border width
pub border_width: f32, pub border_width: f32,
/// Menu border radius /// Menu border radius
pub border_radius: BorderRadius, pub border_radius: Radius,
/// Menu border color /// Menu border color
pub border_color: Color, pub border_color: Color,
/// Text color when hovered /// 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::text::{self, Text};
use iced_core::widget::Tree; use iced_core::widget::Tree;
use iced_core::{ use iced_core::{
alignment, mouse, overlay, renderer, svg, touch, Clipboard, Color, Element, Length, Padding, alignment, mouse, overlay, renderer, svg, touch, Border, Clipboard, Element, Length, Padding,
Pixels, Point, Rectangle, Renderer, Shell, Size, Vector, Widget, Pixels, Point, Rectangle, Renderer, Shadow, Shell, Size, Vector, Widget,
}; };
use iced_widget::scrollable::Scrollable; use iced_widget::scrollable::Scrollable;
@ -98,7 +98,7 @@ impl<'a, S: AsRef<str>, Message: 'a> Menu<'a, S, Message> {
self, self,
position: Point, position: Point,
target_height: f32, 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))) overlay::Element::new(position, Box::new(Overlay::new(self, target_height)))
} }
} }
@ -127,7 +127,7 @@ impl Default for State {
struct Overlay<'a, Message> { struct Overlay<'a, Message> {
state: &'a mut Tree, state: &'a mut Tree,
container: Container<'a, Message, crate::Renderer>, container: Container<'a, Message, crate::Theme, crate::Renderer>,
width: f32, width: f32,
target_height: f32, target_height: f32,
style: (), style: (),
@ -174,7 +174,7 @@ impl<'a, Message: 'a> Overlay<'a, Message> {
.padding(padding) .padding(padding)
.style(crate::style::Container::Dropdown); .style(crate::style::Container::Dropdown);
state.tree.diff(&mut container as &mut dyn Widget<_, _>); state.tree.diff(&mut container as &mut dyn Widget<_, _, _>);
Self { Self {
state: &mut state.tree, 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( fn layout(
&mut self, &mut self,
renderer: &crate::Renderer, renderer: &crate::Renderer,
@ -210,15 +212,13 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
) )
.width(self.width); .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) position + Vector::new(0.0, self.target_height)
} else { } else {
position - Vector::new(0.0, node.size().height) position - Vector::new(0.0, node.size().height)
}); })
node
} }
fn on_event( fn on_event(
@ -262,9 +262,12 @@ impl<'a, Message> iced_core::Overlay<Message, crate::Renderer> for Overlay<'a, M
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_color: appearance.border_color, border: Border {
border_width: appearance.border_width, width: appearance.border_width,
border_radius: appearance.border_radius, color: appearance.border_color,
radius: appearance.border_radius,
},
shadow: Shadow::default(),
}, },
appearance.background, appearance.background,
); );
@ -286,13 +289,11 @@ struct List<'a, S: AsRef<str>, Message> {
selected_icon: Option<svg::Handle>, selected_icon: Option<svg::Handle>,
} }
impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S, Message> { impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Theme, crate::Renderer>
fn width(&self) -> Length { for List<'a, S, Message>
Length::Fill {
} fn size(&self) -> Size<Length> {
Size::new(Length::Fill, Length::Shrink)
fn height(&self) -> Length {
Length::Shrink
} }
fn layout( 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, (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) 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, width: item_width,
..bounds ..bounds
}, },
border_color: Color::TRANSPARENT, border: Border {
border_width: 0.0, radius: appearance.border_radius,
border_radius: appearance.border_radius, ..Default::default()
},
shadow: Shadow::default(),
}, },
appearance.selected_background, appearance.selected_background,
); );
@ -483,9 +486,11 @@ impl<'a, S: AsRef<str>, Message> Widget<Message, crate::Renderer> for List<'a, S
width: item_width, width: item_width,
..bounds ..bounds
}, },
border_color: Color::TRANSPARENT, border: Border {
border_width: 0.0, radius: appearance.border_radius,
border_radius: appearance.border_radius, ..Default::default()
},
shadow: Shadow::default(),
}, },
appearance.hovered_background, 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>> 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 { fn from(list: List<'a, S, Message>) -> Self {
Element::new(list) Element::new(list)

View file

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

View file

@ -8,7 +8,7 @@ use derive_setters::Setters;
use iced_core::event::{self, Event}; use iced_core::event::{self, Event};
use iced_core::text::{self, Paragraph, Text}; use iced_core::text::{self, Paragraph, Text};
use iced_core::widget::tree::{self, Tree}; 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 iced_core::{Clipboard, Layout, Length, Padding, Pixels, Rectangle, Shell, Size, Widget};
use std::ffi::OsStr; 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> 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 { fn tag(&self) -> tree::Tag {
tree::Tag::of::<State<Item>>() 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()) tree::State::new(State::<Item>::new())
} }
fn width(&self) -> Length { fn size(&self) -> Size<Length> {
self.width Size::new(self.width, Length::Shrink)
}
fn height(&self) -> Length {
Length::Shrink
} }
fn layout( fn layout(
@ -188,7 +184,7 @@ impl<'a, S: AsRef<str>, Message: 'a, Item: Clone + PartialEq + 'static>
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &crate::Renderer, 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>>(); let state = tree.state.downcast_mut::<State<Item>>();
overlay( overlay(
@ -269,7 +265,7 @@ pub fn layout(
) -> layout::Node { ) -> layout::Node {
use std::f32; 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 { let max_width = match width {
Length::Shrink => { Length::Shrink => {
@ -298,7 +294,9 @@ pub fn layout(
f32::from(text_line_height.to_absolute(Pixels(text_size))), 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) 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, text_line_height: text::LineHeight,
selections: &'a super::Model<S, Item>, selections: &'a super::Model<S, Item>,
on_selected: &'a dyn Fn(Item) -> Message, 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 { if state.is_open {
let description_line_height = text::LineHeight::Absolute(Pixels( let description_line_height = text::LineHeight::Absolute(Pixels(
text_line_height.to_absolute(Pixels(text_size)).0 + 4.0, 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,
renderer::Quad { renderer::Quad {
bounds, bounds,
border_color: style.border_color, border: style.border,
border_width: style.border_width, shadow: Shadow::default(),
border_radius: style.border_radius,
}, },
style.background, style.background,
); );

View file

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

View file

@ -15,7 +15,7 @@ pub fn resolve<Message>(
row_spacing: f32, row_spacing: f32,
tree: &mut [Tree], tree: &mut [Tree],
) -> Node { ) -> Node {
let limits = limits.pad(padding); let limits = limits.shrink(padding);
let mut nodes = Vec::with_capacity(items.len()); let mut nodes = Vec::with_capacity(items.len());
@ -51,7 +51,7 @@ pub fn resolve<Message>(
let pos_y = flex_height; let pos_y = flex_height;
for mut child_node in row_buffer.drain(..) { 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; pos_x += row_spacing + child_node.size().width;
nodes.push(child_node); nodes.push(child_node);
} }
@ -77,7 +77,7 @@ pub fn resolve<Message>(
let pos_y = flex_height; let pos_y = flex_height;
for mut child_node in row_buffer.drain(..) { 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; pos_x += row_spacing + child_node.size().width;
nodes.push(child_node); nodes.push(child_node);
} }
@ -86,6 +86,6 @@ pub fn resolve<Message>(
flex_width = flex_width.max(current_row_width); flex_width = flex_width.max(current_row_width);
} }
let flex_size = limits.resolve(Size::new(flex_width, flex_height)); let flex_size = limits.resolve(flex_width, flex_height, Size::new(flex_width, flex_height));
Node::with_children(flex_size.pad(padding), nodes) 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> { fn children(&self) -> Vec<Tree> {
self.children.iter().map(Tree::new).collect() 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()); tree.diff_children(self.children.as_mut_slice());
} }
fn width(&self) -> Length { fn size(&self) -> iced_core::Size<Length> {
self.width iced_core::Size::new(self.width, Length::Shrink)
}
fn height(&self) -> Length {
Length::Shrink
} }
fn layout( fn layout(
@ -64,10 +62,11 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Mes
renderer: &Renderer, renderer: &Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
let size = self.size();
let limits = limits let limits = limits
.max_width(self.max_width) .max_width(self.max_width)
.width(self.width()) .width(size.width)
.height(self.height()); .height(size.height);
super::layout::resolve( super::layout::resolve(
renderer, renderer,
@ -178,7 +177,7 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for FlexRow<'a, Mes
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, 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) 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 where
Renderer: ImageRenderer<Handle = Handle>, Renderer: ImageRenderer<Handle = Handle>,
{ {
@ -355,7 +355,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut Renderer, renderer: &mut Renderer,
_theme: &Renderer::Theme, _theme: &crate::Theme,
_style: &renderer::Style, _style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
_cursor_position: Cursor, _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 where
Renderer: ImageRenderer<Handle = Handle> + 'a, 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) Element::new(gif)
} }
} }

View file

@ -43,7 +43,8 @@ pub fn resolve<Message>(
nodes.push(child_node); 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::Fill | Length::FillPortion(_) => (Dimension::Auto, Some(AlignItems::Stretch)),
_ => (length(size.width), None), _ => (length(size.width), None),
}; };
@ -62,7 +63,7 @@ pub fn resolve<Message>(
}, },
size: taffy::geometry::Size { size: taffy::geometry::Size {
width, width,
height: match child_widget.height() { height: match c_size.height {
Length::Fill | Length::FillPortion(_) => Dimension::Auto, Length::Fill | Length::FillPortion(_) => Dimension::Auto,
_ => length(size.height), _ => length(size.height),
}, },
@ -165,7 +166,8 @@ pub fn resolve<Message>(
{ {
if let Ok(leaf_layout) = taffy.layout(leaf) { if let Ok(leaf_layout) = taffy.layout(leaf) {
let child_widget = child.as_widget(); let child_widget = child.as_widget();
match child_widget.width() { let c_size = child_widget.size();
match c_size.width {
Length::Fill | Length::FillPortion(_) => { Length::Fill | Length::FillPortion(_) => {
*node = *node =
child_widget.layout(tree, renderer, &limits.width(leaf_layout.size.width)); 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, x: leaf_layout.location.x,
y: leaf_layout.location.y, y: leaf_layout.location.y,
}); })
} }
} }
@ -185,5 +187,5 @@ pub fn resolve<Message>(
height: grid_layout.size.height, 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> { fn children(&self) -> Vec<Tree> {
self.children.iter().map(Tree::new).collect() 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()); tree.diff_children(self.children.as_mut_slice());
} }
fn width(&self) -> Length { fn size(&self) -> iced_core::Size<Length> {
self.width iced_core::Size::new(self.width, self.height)
}
fn height(&self) -> Length {
self.height
} }
fn layout( fn layout(
@ -126,10 +122,11 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Messag
renderer: &Renderer, renderer: &Renderer,
limits: &layout::Limits, limits: &layout::Limits,
) -> layout::Node { ) -> layout::Node {
let size = self.size();
let limits = limits let limits = limits
.max_width(self.max_width) .max_width(self.max_width)
.width(self.width()) .width(size.width)
.height(self.height()); .height(size.height);
super::layout::resolve( super::layout::resolve(
renderer, renderer,
@ -245,7 +242,7 @@ impl<'a, Message: 'static + Clone> Widget<Message, Renderer> for Grid<'a, Messag
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, 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) 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 apply::Apply;
use derive_setters::Setters; use derive_setters::Setters;
use iced::{window, Length}; use iced::{window, Length};
use iced_core::{renderer::Quad, widget::tree, Background, Color, Renderer, Widget}; use iced_core::{
use std::{borrow::Cow, process::Child}; renderer::Quad, widget::tree, Background, Renderer, Widget,
};
use std::{borrow::Cow};
#[must_use] #[must_use]
pub fn header_bar<'a, Message>() -> HeaderBar<'a, Message> { pub fn header_bar<'a, Message>() -> HeaderBar<'a, Message> {
@ -106,19 +108,15 @@ pub struct HeaderBarWidget<'a, Message> {
window_id: Option<iced::window::Id>, 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> for HeaderBarWidget<'a, Message>
{ {
fn children(&self) -> Vec<tree::Tree> { fn children(&self) -> Vec<tree::Tree> {
vec![tree::Tree::new(&self.header_bar_inner)] vec![tree::Tree::new(&self.header_bar_inner)]
} }
fn width(&self) -> Length { fn size(&self) -> iced_core::Size<Length> {
self.header_bar_inner.width() self.header_bar_inner.as_widget().size()
}
fn height(&self) -> Length {
self.header_bar_inner.height()
} }
fn tag(&self) -> tree::Tag { fn tag(&self) -> tree::Tag {
@ -156,7 +154,7 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
&self, &self,
tree: &tree::Tree, tree: &tree::Tree,
renderer: &mut crate::Renderer, renderer: &mut crate::Renderer,
theme: &<crate::Renderer as iced_core::Renderer>::Theme, theme: &crate::Theme,
style: &iced_core::renderer::Style, style: &iced_core::renderer::Style,
layout: iced_core::Layout<'_>, layout: iced_core::Layout<'_>,
cursor: iced_core::mouse::Cursor, cursor: iced_core::mouse::Cursor,
@ -189,9 +187,8 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
renderer.fill_quad( renderer.fill_quad(
Quad { Quad {
bounds: layout.bounds(), bounds: layout.bounds(),
border_radius: header_bar_appearance.border_radius, border: header_bar_appearance.border,
border_width: 0.0, shadow: header_bar_appearance.shadow,
border_color: Color::TRANSPARENT,
}, },
Background::Color(neutral_0.into()), Background::Color(neutral_0.into()),
); );
@ -271,7 +268,7 @@ impl<'a, Message: Clone + 'static> Widget<Message, crate::Renderer>
state: &'b mut tree::Tree, state: &'b mut tree::Tree,
layout: iced_core::Layout<'_>, layout: iced_core::Layout<'_>,
renderer: &crate::Renderer, 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_tree = &mut state.children[0];
let child_layout = layout.children().next().unwrap(); let child_layout = layout.children().next().unwrap();
self.header_bar_inner self.header_bar_inner

View file

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

View file

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

View file

@ -58,15 +58,15 @@ pub fn resolve<'a, E, Message, Renderer>(
tree: &mut [&mut Tree], tree: &mut [&mut Tree],
) -> Node ) -> Node
where where
E: std::borrow::Borrow<Element<'a, Message, Renderer>>, E: std::borrow::Borrow<Element<'a, Message, crate::Theme, Renderer>>,
Renderer: renderer::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 total_spacing = spacing * items.len().saturating_sub(1) as f32;
let max_cross = axis.cross(limits.max()); let max_cross = axis.cross(limits.max());
let mut fill_sum = 0; 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 available = axis.main(limits.max()) - total_spacing;
let mut nodes: Vec<Node> = Vec::with_capacity(items.len()); 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()) { for (child, tree) in items.iter().zip(tree.iter_mut()) {
let child = child.borrow(); let child = child.borrow();
let c_size = child.as_widget().size();
let cross_fill_factor = match axis { let cross_fill_factor = match axis {
Axis::Horizontal => child.as_widget().height(), Axis::Horizontal => c_size.height,
Axis::Vertical => child.as_widget().width(), Axis::Vertical => c_size.width,
} }
.fill_factor(); .fill_factor();
@ -100,9 +101,10 @@ where
for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() { for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() {
let child = child.borrow(); let child = child.borrow();
let c_size = child.as_widget().size();
let fill_factor = match axis { let fill_factor = match axis {
Axis::Horizontal => child.as_widget().width(), Axis::Horizontal => c_size.width,
Axis::Vertical => child.as_widget().height(), Axis::Vertical => c_size.height,
} }
.fill_factor(); .fill_factor();
@ -143,9 +145,10 @@ where
for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() { for (i, (child, tree)) in items.iter().zip(tree.iter_mut()).enumerate() {
let child = child.borrow(); let child = child.borrow();
let c_size = child.as_widget().size();
let fill_factor = match axis { let fill_factor = match axis {
Axis::Horizontal => child.as_widget().width(), Axis::Horizontal => c_size.width,
Axis::Vertical => child.as_widget().height(), Axis::Vertical => c_size.height,
} }
.fill_factor(); .fill_factor();
@ -194,24 +197,22 @@ where
let (x, y) = axis.pack(main, pad.1); 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 { let node_ = match axis {
Axis::Horizontal => { Axis::Horizontal => node_.align(Alignment::Start, align_items, Size::new(0.0, cross)),
node.align(Alignment::Start, align_items, Size::new(0.0, cross)); Axis::Vertical => node_.align(align_items, Alignment::Start, Size::new(cross, 0.0)),
} };
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); main += axis.main(size);
} }
let (width, height) = axis.pack(main - pad.0, cross); 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 crate::style::menu_bar::StyleSheet;
use iced_core::Border;
use iced_widget::core::{ use iced_widget::core::{
event, event,
layout::{Limits, Node}, layout::{Limits, Node},
mouse::{self, Cursor}, mouse::{self, Cursor},
overlay, renderer, touch, overlay, renderer, touch,
widget::{tree, Tree}, 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 { pub(super) struct MenuBarState {
@ -61,7 +62,6 @@ impl Default for MenuBarState {
pub struct MenuBar<'a, Message, Renderer = crate::Renderer> pub struct MenuBar<'a, Message, Renderer = crate::Renderer>
where where
Renderer: renderer::Renderer, Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{ {
width: Length, width: Length,
height: Length, height: Length,
@ -75,13 +75,12 @@ where
item_height: ItemHeight, item_height: ItemHeight,
path_highlight: Option<PathHighlight>, path_highlight: Option<PathHighlight>,
menu_roots: Vec<MenuTree<'a, Message, Renderer>>, 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> impl<'a, Message, Renderer> MenuBar<'a, Message, Renderer>
where where
Renderer: renderer::Renderer, Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{ {
/// Creates a new [`MenuBar`] with the given menu roots /// Creates a new [`MenuBar`] with the given menu roots
#[must_use] #[must_use]
@ -106,7 +105,7 @@ where
item_height: ItemHeight::Uniform(30), item_height: ItemHeight::Uniform(30),
path_highlight: Some(PathHighlight::MenuActive), path_highlight: Some(PathHighlight::MenuActive),
menu_roots, 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 /// Sets the style of the menu bar and its menus
#[must_use] #[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.style = style.into();
self self
} }
@ -198,17 +197,13 @@ where
self 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 where
Renderer: renderer::Renderer, Renderer: renderer::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn width(&self) -> Length { fn size(&self) -> iced_core::Size<Length> {
self.width iced_core::Size::new(self.width, self.height)
}
fn height(&self) -> Length {
self.height
} }
#[allow(invalid_reference_casting)] #[allow(invalid_reference_casting)]
@ -226,8 +221,10 @@ where
.iter() .iter()
.map(|mt| { .map(|mt| {
let widget = mt.item.as_widget(); let widget = mt.item.as_widget();
let widget_ptr = widget as *const dyn Widget<Message, Renderer>; let widget_ptr =
let widget_ptr_mut = widget_ptr as *mut dyn Widget<Message, Renderer>; 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 //TODO: find a way to diff_children without unsafe code
unsafe { &mut *widget_ptr_mut } unsafe { &mut *widget_ptr_mut }
}) })
@ -356,7 +353,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut Renderer, renderer: &mut Renderer,
theme: &<Renderer as renderer::Renderer>::Theme, theme: &crate::Theme,
style: &renderer::Style, style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
view_cursor: Cursor, view_cursor: Cursor,
@ -381,9 +378,11 @@ where
.bounds(); .bounds();
let path_quad = renderer::Quad { let path_quad = renderer::Quad {
bounds: active_bounds, bounds: active_bounds,
border_radius: styling.bar_border_radius.into(), border: Border {
border_width: 0.0, radius: styling.bar_border_radius.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Default::default(),
}; };
let path_color = styling.path; let path_color = styling.path;
renderer.fill_quad(path_quad, path_color); renderer.fill_quad(path_quad, path_color);
@ -412,7 +411,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
let state = tree.state.downcast_ref::<MenuBarState>(); let state = tree.state.downcast_ref::<MenuBarState>();
if !state.open { if !state.open {
return None; 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 where
Message: 'a, Message: 'a,
Renderer: 'a + renderer::Renderer, Renderer: 'a + renderer::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn from(value: MenuBar<'a, Message, Renderer>) -> Self { fn from(value: MenuBar<'a, Message, Renderer>) -> Self {
Self::new(value) Self::new(value)

View file

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

View file

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

View file

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

View file

@ -10,7 +10,7 @@ use iced::{
widget::{container, scrollable}, widget::{container, scrollable},
Background, Length, Background, Length,
}; };
use iced_core::Color; use iced_core::{Border, Color, Shadow};
use crate::{theme, widget::segmented_button, Theme}; use crate::{theme, widget::segmented_button, Theme};
@ -23,7 +23,7 @@ pub type Model = segmented_button::SingleSelectModel;
pub fn nav_bar<Message>( pub fn nav_bar<Message>(
model: &segmented_button::SingleSelectModel, model: &segmented_button::SingleSelectModel,
on_activate: fn(segmented_button::Entity) -> Message, on_activate: fn(segmented_button::Entity) -> Message,
) -> iced::widget::Container<Message, crate::Renderer> ) -> iced::widget::Container<Message, crate::Theme, crate::Renderer>
where where
Message: Clone + 'static, 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()), icon_color: Some(cosmic.on_bg_color().into()),
text_color: Some(cosmic.on_bg_color().into()), text_color: Some(cosmic.on_bg_color().into()),
background: Some(Background::Color(cosmic.primary.base.into())), background: Some(Background::Color(cosmic.primary.base.into())),
border_radius: cosmic.corner_radii.radius_s.into(), border: Border {
border_width: 0.0, width: 0.0,
border_color: Color::TRANSPARENT, 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 use iced_style::container::{Appearance, StyleSheet};
pub fn popover<'a, Message, Renderer>( pub fn popover<'a, Message, Renderer>(
content: impl Into<Element<'a, Message, Renderer>>, content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
popup: impl Into<Element<'a, Message, Renderer>>, popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
) -> Popover<'a, Message, Renderer> { ) -> Popover<'a, Message, Renderer> {
Popover::new(content, popup) Popover::new(content, popup)
} }
pub struct Popover<'a, Message, Renderer> { 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? // XXX Avoid refcell; improve iced overlay API?
popup: RefCell<Element<'a, Message, Renderer>>, popup: RefCell<Element<'a, Message, crate::Theme, Renderer>>,
position: Option<Point>, position: Option<Point>,
show_popup: bool, show_popup: bool,
} }
impl<'a, Message, Renderer> Popover<'a, Message, Renderer> { impl<'a, Message, Renderer> Popover<'a, Message, Renderer> {
pub fn new( pub fn new(
content: impl Into<Element<'a, Message, Renderer>>, content: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
popup: impl Into<Element<'a, Message, Renderer>>, popup: impl Into<Element<'a, Message, crate::Theme, Renderer>>,
) -> Self { ) -> Self {
Self { Self {
content: content.into(), 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 // 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 where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
Renderer::Theme: StyleSheet,
{ {
fn children(&self) -> Vec<Tree> { fn children(&self) -> Vec<Tree> {
vec![Tree::new(&self.content), Tree::new(&*self.popup.borrow())] 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()]); tree.diff_children(&mut [&mut self.content, &mut self.popup.borrow_mut()]);
} }
fn width(&self) -> Length { fn size(&self) -> Size<Length> {
self.content.as_widget().width() self.content.as_widget().size()
}
fn height(&self) -> Length {
self.content.as_widget().height()
} }
fn layout( fn layout(
@ -144,7 +140,7 @@ where
&self, &self,
tree: &Tree, tree: &Tree,
renderer: &mut Renderer, renderer: &mut Renderer,
theme: &Renderer::Theme, theme: &crate::Theme,
renderer_style: &renderer::Style, renderer_style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: mouse::Cursor, cursor_position: mouse::Cursor,
@ -166,7 +162,7 @@ where
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, crate::Theme, Renderer>> {
if !self.show_popup { if !self.show_popup {
return None; 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 where
Message: 'static, Message: 'static,
Renderer: iced_core::Renderer + 'static, Renderer: iced_core::Renderer + 'static,
Renderer::Theme: StyleSheet,
{ {
fn from(popover: Popover<'a, Message, Renderer>) -> Self { fn from(popover: Popover<'a, Message, Renderer>) -> Self {
Self::new(popover) Self::new(popover)
@ -211,11 +207,11 @@ where
pub struct Overlay<'a, 'b, Message, Renderer> { pub struct Overlay<'a, 'b, Message, Renderer> {
tree: &'a mut Tree, tree: &'a mut Tree,
content: &'a RefCell<Element<'b, Message, Renderer>>, content: &'a RefCell<Element<'b, Message, crate::Theme, Renderer>>,
centered: bool, 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> for Overlay<'a, 'b, Message, Renderer>
where where
Renderer: iced_core::Renderer, Renderer: iced_core::Renderer,
@ -228,7 +224,7 @@ where
_translation: iced::Vector, _translation: iced::Vector,
) -> layout::Node { ) -> layout::Node {
let limits = layout::Limits::new(Size::UNIT, bounds); let limits = layout::Limits::new(Size::UNIT, bounds);
let mut node = self let node = self
.content .content
.borrow() .borrow()
.as_widget() .as_widget()
@ -245,9 +241,7 @@ where
position.y = (position.y - size.height).clamp(0.0, bounds.height - size.height); position.y = (position.y - size.height).clamp(0.0, bounds.height - size.height);
} }
} }
node.move_to(position); node.move_to(position)
node
} }
fn operate( fn operate(
@ -302,7 +296,7 @@ where
fn draw( fn draw(
&self, &self,
renderer: &mut Renderer, renderer: &mut Renderer,
theme: &Renderer::Theme, theme: &crate::Theme,
style: &renderer::Style, style: &renderer::Style,
layout: Layout<'_>, layout: Layout<'_>,
cursor_position: mouse::Cursor, cursor_position: mouse::Cursor,

View file

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

View file

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

View file

@ -131,9 +131,11 @@ where
} }
// Get the max available width for placing buttons into. // Get the max available width for placing buttons into.
let max_size = limits let max_size = limits.height(Length::Fixed(total_height)).resolve(
.height(Length::Fixed(total_height)) Length::Fill,
.resolve(Size::new(f32::MAX, total_height)); total_height,
Size::new(f32::MAX, total_height),
);
let mut visible_width = f32::from(self.button_height) * 2.0; let mut visible_width = f32::from(self.button_height) * 2.0;
state.buttons_visible = 0; state.buttons_visible = 0;
@ -162,25 +164,33 @@ where
size = limits size = limits
.width(Length::Fixed(visible_width)) .width(Length::Fixed(visible_width))
.height(Length::Fixed(total_height)) .height(Length::Fixed(total_height))
.resolve(Size::new(visible_width, total_height)); .resolve(
visible_width,
total_height,
Size::new(visible_width, total_height),
);
} else { } else {
// Buttons will be rendered with equal widths. // Buttons will be rendered with equal widths.
state.buttons_visible = self.model.items.len(); state.buttons_visible = self.model.items.len();
let (width, height) = self.max_button_dimensions(state, renderer, limits.max()); let (width, height) = self.max_button_dimensions(state, renderer, limits.max());
let total_width = (state.buttons_visible as f32) * (width + spacing); let total_width = (state.buttons_visible as f32) * (width + spacing);
size = limits size = limits.height(Length::Fixed(height)).resolve(
.height(Length::Fixed(height)) total_width,
.resolve(Size::new(total_width, height)); height,
Size::new(total_width, height),
);
let actual_width = size.width as usize; let actual_width = size.width as usize;
let minimum_width = state.buttons_visible * self.minimum_button_width as usize; let minimum_width = state.buttons_visible * self.minimum_button_width as usize;
state.collapsed = actual_width < minimum_width; state.collapsed = actual_width < minimum_width;
if state.collapsed { if state.collapsed {
size = limits size = limits.height(Length::Fixed(height)).resolve(
.height(Length::Fixed(height)) Length::Fill,
.resolve(Size::new(f32::MAX, height)); height,
Size::new(f32::MAX, height),
);
state.buttons_visible = state.buttons_visible =
(actual_width / self.minimum_button_width as usize).min(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> // Copyright 2022 System76 <info@system76.com>
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use iced_core::{Background, BorderRadius, Color}; use iced_core::{border::Radius, Background, Color};
/// Appearance of the segmented button. /// Appearance of the segmented button.
#[derive(Default, Clone, Copy)] #[derive(Default, Clone, Copy)]
pub struct Appearance { pub struct Appearance {
pub background: Option<Background>, pub background: Option<Background>,
pub border_radius: BorderRadius, pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>, pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>, pub border_end: Option<(f32, Color)>,
pub border_start: Option<(f32, Color)>, pub border_start: Option<(f32, Color)>,
@ -21,7 +21,7 @@ pub struct Appearance {
/// Appearance of an item in the segmented button. /// Appearance of an item in the segmented button.
#[derive(Default, Clone, Copy)] #[derive(Default, Clone, Copy)]
pub struct ItemAppearance { pub struct ItemAppearance {
pub border_radius: BorderRadius, pub border_radius: Radius,
pub border_bottom: Option<(f32, Color)>, pub border_bottom: Option<(f32, Color)>,
pub border_end: Option<(f32, Color)>, pub border_end: Option<(f32, Color)>,
pub border_start: 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; height = (num as f32 * height) + (num as f32 * spacing) - spacing;
} }
let size = limits let size =
.height(Length::Fixed(height)) limits
.resolve(Size::new(width, height)); .height(Length::Fixed(height))
.resolve(width, height, Size::new(width, height));
layout::Node::new(size) 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::text::{LineHeight, Paragraph, Renderer as TextRenderer, Shaping};
use iced_core::widget::{self, operation, tree}; use iced_core::widget::{self, operation, tree};
use iced_core::{layout, renderer, widget::Tree, Clipboard, Layout, Shell, Widget}; 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 slotmap::{Key, SecondaryMap};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::time::{Duration, Instant}; 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> for SegmentedButton<'a, Variant, SelectionMode, Message>
where where
Self: SegmentedVariant, Self: SegmentedVariant,
@ -423,12 +423,8 @@ where
} }
} }
fn width(&self) -> Length { fn size(&self) -> Size<Length> {
self.width Size::new(self.width, self.height)
}
fn height(&self) -> Length {
self.height
} }
fn layout( fn layout(
@ -601,7 +597,7 @@ where
if state.focused { if state.focused {
if let Event::Keyboard(keyboard::Event::KeyPressed { if let Event::Keyboard(keyboard::Event::KeyPressed {
key_code: keyboard::KeyCode::Tab, key: keyboard::Key::Named(keyboard::key::Named::Tab),
modifiers, modifiers,
.. ..
}) = event }) = event
@ -615,7 +611,7 @@ where
if let Some(on_activate) = self.on_activate.as_ref() { if let Some(on_activate) = self.on_activate.as_ref() {
if let Event::Keyboard(keyboard::Event::KeyReleased { if let Event::Keyboard(keyboard::Event::KeyReleased {
key_code: keyboard::KeyCode::Enter, key: keyboard::Key::Named(keyboard::key::Named::Enter),
.. ..
}) = event }) = event
{ {
@ -719,7 +715,6 @@ where
cursor: mouse::Cursor, cursor: mouse::Cursor,
viewport: &iced::Rectangle, viewport: &iced::Rectangle,
) { ) {
let cosmic_theme = theme.cosmic();
let state = tree.state.downcast_ref::<LocalState>(); let state = tree.state.downcast_ref::<LocalState>();
let appearance = Self::variant_appearance(theme, &self.style); let appearance = Self::variant_appearance(theme, &self.style);
let bounds = layout.bounds(); let bounds = layout.bounds();
@ -730,9 +725,11 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: appearance.border_radius, border: Border {
border_width: 0.0, radius: appearance.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
background, background,
); );
@ -758,9 +755,11 @@ where
width: f32::from(self.button_height), width: f32::from(self.button_height),
height: bounds.height, height: bounds.height,
}, },
border_radius: cosmic_theme.radius_s().into(), border: Border {
border_width: 0.0, radius: appearance.focus.first.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
background_appearance background_appearance
.background .background
@ -808,9 +807,11 @@ where
width: f32::from(self.button_height), width: f32::from(self.button_height),
height: bounds.height, height: bounds.height,
}, },
border_radius: cosmic_theme.radius_s().into(), border: Border {
border_width: 0.0, radius: appearance.focus.last.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
background_appearance background_appearance
.background .background
@ -871,9 +872,11 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: button_appearance.border_radius, border: Border {
border_width: 0.0, radius: button_appearance.border_radius,
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
status_appearance status_appearance
.background .background
@ -891,9 +894,11 @@ where
renderer.fill_quad( renderer.fill_quad(
renderer::Quad { renderer::Quad {
bounds, bounds,
border_radius: rad_0.into(), border: Border {
border_width: 0.0, radius: rad_0.into(),
border_color: Color::TRANSPARENT, ..Default::default()
},
shadow: Shadow::default(),
}, },
background, background,
); );
@ -1012,7 +1017,7 @@ where
_tree: &'b mut Tree, _tree: &'b mut Tree,
_layout: iced_core::Layout<'_>, _layout: iced_core::Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,
) -> Option<iced_core::overlay::Element<'b, Message, Renderer>> { ) -> Option<iced_core::overlay::Element<'b, Message, crate::Theme, Renderer>> {
None None
} }
} }
@ -1134,18 +1139,17 @@ fn draw_icon<Message: 'static>(
bounds: Rectangle, bounds: Rectangle,
icon: Icon, icon: Icon,
) { ) {
let mut layout_node = layout::Node::new(Size { let layout_node = layout::Node::new(Size {
width: bounds.width, width: bounds.width,
height: bounds.width, height: bounds.width,
}); })
.move_to(Point {
layout_node.move_to(Point {
x: bounds.x, x: bounds.x,
y: bounds.y, y: bounds.y,
}); });
Widget::<Message, Renderer>::draw( Widget::<Message, crate::Theme, Renderer>::draw(
Element::<Message>::from(icon).as_widget(), Element::<Message>::from(icon.clone()).as_widget(),
&Tree::empty(), &Tree::empty(),
renderer, renderer,
theme, theme,

View file

@ -13,6 +13,7 @@ use iced::{
alignment::{Horizontal, Vertical}, alignment::{Horizontal, Vertical},
Alignment, Length, Alignment, Length,
}; };
use iced_core::{Border, Shadow};
pub struct SpinButton<'a, Message> { pub struct SpinButton<'a, Message> {
label: Cow<'a, str>, 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()), icon_color: Some(basic.palette.neutral_10.into()),
text_color: Some(basic.palette.neutral_10.into()), text_color: Some(basic.palette.neutral_10.into()),
background: None, background: None,
border_radius: corners.radius_s.into(), border: Border {
border_width: 0.0, radius: corners.radius_s.into(),
border_color: accent.base.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. /// Creates a new [`Text`] widget with the provided content.
/// ///
/// [`Text`]: widget::Text /// [`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) Text::new(text)
} }
@ -25,7 +25,7 @@ pub enum Typography {
} }
/// [`Text`] widget with the Title 1 typography preset. /// [`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) Text::new(text)
.size(32.0) .size(32.0)
.line_height(LineHeight::Absolute(44.0.into())) .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. /// [`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) Text::new(text)
.size(28.0) .size(28.0)
.line_height(LineHeight::Absolute(36.0.into())) .line_height(LineHeight::Absolute(36.0.into()))
} }
/// [`Text`] widget with the Title 3 typography preset. /// [`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) Text::new(text)
.size(24.0) .size(24.0)
.line_height(LineHeight::Absolute(32.0.into())) .line_height(LineHeight::Absolute(32.0.into()))
} }
/// [`Text`] widget with the Title 4 typography preset. /// [`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) Text::new(text)
.size(20.0) .size(20.0)
.line_height(LineHeight::Absolute(28.0.into())) .line_height(LineHeight::Absolute(28.0.into()))
} }
/// [`Text`] widget with the Heading typography preset. /// [`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) Text::new(text)
.size(14.0) .size(14.0)
.line_height(LineHeight::Absolute(iced::Pixels(20.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. /// [`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) Text::new(text)
.size(10.0) .size(10.0)
.line_height(LineHeight::Absolute(iced::Pixels(14.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. /// [`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) Text::new(text)
.size(14.0) .size(14.0)
.line_height(LineHeight::Absolute(20.0.into())) .line_height(LineHeight::Absolute(20.0.into()))
} }
/// [`Text`] widget with the Caption typography preset. /// [`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) Text::new(text)
.size(10.0) .size(10.0)
.line_height(LineHeight::Absolute(14.0.into())) .line_height(LineHeight::Absolute(14.0.into()))
} }
/// [`Text`] widget with the Monotext typography preset. /// [`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) Text::new(text)
.size(14.0) .size(14.0)
.line_height(LineHeight::Absolute(20.0.into())) .line_height(LineHeight::Absolute(20.0.into()))

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@ use super::icon;
use crate::{theme, widget, Element, Renderer, Theme}; use crate::{theme, widget, Element, Renderer, Theme};
use apply::Apply; use apply::Apply;
use iced::{alignment, Alignment, Background, Color, Length}; use iced::{alignment, Alignment, Background, Color, Length};
use iced_core::{Border, Shadow};
use std::borrow::Cow; use std::borrow::Cow;
#[must_use] #[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. /// 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 label = widget::container(crate::widget::text(self.message)).width(Length::Fill);
let close_button = icon::from_name("window-close-symbolic") let close_button = icon::from_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()), icon_color: Some(theme.cosmic().warning.on.into()),
text_color: Some(theme.cosmic().warning.on.into()), text_color: Some(theme.cosmic().warning.on.into()),
background: Some(Background::Color(theme.cosmic().warning_color().into())), background: Some(Background::Color(theme.cosmic().warning_color().into())),
border_radius: cosmic.corner_radii.radius_0.into(), border: Border {
border_width: 0.0, color: Color::TRANSPARENT,
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,
},
} }
} }