diff options
author | 2022-06-07 04:51:44 +0200 | |
---|---|---|
committer | 2022-06-07 04:51:44 +0200 | |
commit | 396735b682433928f52ba777891e14f2fbc703c7 (patch) | |
tree | bd275980a2fe6bc2efa7288f08db007dcaa7b6a4 /native | |
parent | 97555e67af8b4bcc77df69c5e72156e14948150e (diff) | |
download | iced-396735b682433928f52ba777891e14f2fbc703c7.tar.gz iced-396735b682433928f52ba777891e14f2fbc703c7.tar.bz2 iced-396735b682433928f52ba777891e14f2fbc703c7.zip |
Implement theme styling for `PickList` and `Menu`
Diffstat (limited to 'native')
-rw-r--r-- | native/src/overlay/menu.rs | 63 | ||||
-rw-r--r-- | native/src/widget/pick_list.rs | 51 |
2 files changed, 72 insertions, 42 deletions
diff --git a/native/src/overlay/menu.rs b/native/src/overlay/menu.rs index fdb68247..979a13c3 100644 --- a/native/src/overlay/menu.rs +++ b/native/src/overlay/menu.rs @@ -14,11 +14,15 @@ use crate::{ Shell, Size, Vector, Widget, }; -pub use iced_style::menu::Style; +pub use iced_style::menu::{Appearance, StyleSheet}; /// A list of selectable options. #[allow(missing_debug_implementations)] -pub struct Menu<'a, T, Renderer: text::Renderer> { +pub struct Menu<'a, T, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ state: &'a mut State, options: &'a [T], hovered_option: &'a mut Option<usize>, @@ -27,14 +31,15 @@ pub struct Menu<'a, T, Renderer: text::Renderer> { padding: Padding, text_size: Option<u16>, font: Renderer::Font, - style: Style, + style: <Renderer::Theme as StyleSheet>::Style, } impl<'a, T, Renderer> Menu<'a, T, Renderer> where T: ToString + Clone, Renderer: text::Renderer + 'a, - Renderer::Theme: container::StyleSheet + scrollable::StyleSheet, + Renderer::Theme: + StyleSheet + container::StyleSheet + scrollable::StyleSheet, { /// Creates a new [`Menu`] with the given [`State`], a list of options, and /// the message to produced when an option is selected. @@ -82,7 +87,10 @@ where } /// Sets the style of the [`Menu`]. - pub fn style(mut self, style: impl Into<Style>) -> Self { + pub fn style( + mut self, + style: impl Into<<Renderer::Theme as StyleSheet>::Style>, + ) -> Self { self.style = style.into(); self } @@ -121,12 +129,12 @@ impl State { struct Overlay<'a, Message, Renderer> where Renderer: crate::Renderer, - Renderer::Theme: container::StyleSheet, + Renderer::Theme: StyleSheet + container::StyleSheet, { container: Container<'a, Message, Renderer>, width: u16, target_height: f32, - style: Style, + style: <Renderer::Theme as StyleSheet>::Style, } impl<'a, Message, Renderer> Overlay<'a, Message, Renderer> @@ -134,7 +142,8 @@ where Message: 'a, Renderer: 'a, Renderer: text::Renderer, - Renderer::Theme: container::StyleSheet + scrollable::StyleSheet, + Renderer::Theme: + StyleSheet + container::StyleSheet + scrollable::StyleSheet, { pub fn new<T>(menu: Menu<'a, T, Renderer>, target_height: f32) -> Self where @@ -160,9 +169,8 @@ where font, text_size, padding, - style: style.clone(), - })) - .padding(1); + style, + })); Self { container, @@ -177,7 +185,7 @@ impl<'a, Message, Renderer> crate::Overlay<Message, Renderer> for Overlay<'a, Message, Renderer> where Renderer: text::Renderer, - Renderer::Theme: container::StyleSheet, + Renderer::Theme: StyleSheet + container::StyleSheet, { fn layout( &self, @@ -254,16 +262,20 @@ where layout: Layout<'_>, cursor_position: Point, ) { + let appearance = theme.appearance(self.style); let bounds = layout.bounds(); renderer.fill_quad( renderer::Quad { - bounds, - border_color: self.style.border_color, - border_width: self.style.border_width, + bounds: Rectangle { + width: bounds.width - 1.0, + ..bounds + }, + border_color: appearance.border_color, + border_width: appearance.border_width, border_radius: 0.0, }, - self.style.background, + appearance.background, ); self.container.draw( @@ -277,14 +289,18 @@ where } } -struct List<'a, T, Renderer: text::Renderer> { +struct List<'a, T, Renderer> +where + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, +{ options: &'a [T], hovered_option: &'a mut Option<usize>, last_selection: &'a mut Option<T>, padding: Padding, text_size: Option<u16>, font: Renderer::Font, - style: Style, + style: <Renderer::Theme as StyleSheet>::Style, } impl<'a, T, Message, Renderer> Widget<Message, Renderer> @@ -292,6 +308,7 @@ impl<'a, T, Message, Renderer> Widget<Message, Renderer> where T: Clone + ToString, Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { Length::Fill @@ -404,12 +421,13 @@ where fn draw( &self, renderer: &mut Renderer, - _theme: &Renderer::Theme, + theme: &Renderer::Theme, _style: &renderer::Style, layout: Layout<'_>, _cursor_position: Point, viewport: &Rectangle, ) { + let appearance = theme.appearance(self.style); let bounds = layout.bounds(); let text_size = self.text_size.unwrap_or(renderer.default_size()); @@ -441,7 +459,7 @@ where border_width: 0.0, border_radius: 0.0, }, - self.style.selected_background, + appearance.selected_background, ); } @@ -456,9 +474,9 @@ where size: f32::from(text_size), font: self.font.clone(), color: if is_selected { - self.style.selected_text_color + appearance.selected_text_color } else { - self.style.text_color + appearance.text_color }, horizontal_alignment: alignment::Horizontal::Left, vertical_alignment: alignment::Vertical::Center, @@ -473,6 +491,7 @@ where T: ToString + Clone, Message: 'a, Renderer: 'a + text::Renderer, + Renderer::Theme: StyleSheet, { fn into(self) -> Element<'a, Message, Renderer> { Element::new(self) diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index eea5862a..c6cfcc01 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -17,13 +17,15 @@ use crate::{ }; use std::borrow::Cow; -pub use iced_style::pick_list::{Style, StyleSheet}; +pub use iced_style::pick_list::{Appearance, StyleSheet}; /// A widget for selecting a single value from a list of options. #[allow(missing_debug_implementations)] -pub struct PickList<'a, T, Message, Renderer: text::Renderer> +pub struct PickList<'a, T, Message, Renderer> where [T]: ToOwned<Owned = Vec<T>>, + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { state: &'a mut State<T>, on_selected: Box<dyn Fn(T) -> Message>, @@ -34,7 +36,7 @@ where padding: Padding, text_size: Option<u16>, font: Renderer::Font, - style_sheet: Box<dyn StyleSheet + 'a>, + style: <Renderer::Theme as StyleSheet>::Style, } /// The local state of a [`PickList`]. @@ -66,11 +68,12 @@ impl<T> Default for State<T> { } } -impl<'a, T: 'a, Message, Renderer: text::Renderer> - PickList<'a, T, Message, Renderer> +impl<'a, T: 'a, Message, Renderer> PickList<'a, T, Message, Renderer> where T: ToString + Eq, [T]: ToOwned<Owned = Vec<T>>, + Renderer: text::Renderer, + Renderer::Theme: StyleSheet, { /// The default padding of a [`PickList`]. pub const DEFAULT_PADDING: Padding = Padding::new(5); @@ -94,7 +97,7 @@ where text_size: None, padding: Self::DEFAULT_PADDING, font: Default::default(), - style_sheet: Default::default(), + style: Default::default(), } } @@ -131,9 +134,9 @@ where /// Sets the style of the [`PickList`]. pub fn style( mut self, - style_sheet: impl Into<Box<dyn StyleSheet + 'a>>, + style: impl Into<<Renderer::Theme as StyleSheet>::Style>, ) -> Self { - self.style_sheet = style_sheet.into(); + self.style = style.into(); self } } @@ -319,13 +322,13 @@ pub fn overlay<'a, T, Message, Renderer>( text_size: Option<u16>, font: Renderer::Font, options: &'a [T], - style_sheet: &dyn StyleSheet, + style: <Renderer::Theme as StyleSheet>::Style, ) -> Option<overlay::Element<'a, Message, Renderer>> where + T: Clone + ToString, Message: 'a, Renderer: text::Renderer + 'a, - Renderer::Theme: container::StyleSheet + scrollable::StyleSheet, - T: Clone + ToString, + Renderer::Theme: StyleSheet, { if state.is_open { let bounds = layout.bounds(); @@ -339,7 +342,7 @@ where .width(bounds.width.round() as u16) .padding(padding) .font(font) - .style(style_sheet.menu()); + .style(style); if let Some(text_size) = text_size { menu = menu.text_size(text_size); @@ -354,6 +357,7 @@ where /// Draws a [`PickList`]. pub fn draw<T, Renderer>( renderer: &mut Renderer, + theme: &Renderer::Theme, layout: Layout<'_>, cursor_position: Point, padding: Padding, @@ -361,9 +365,10 @@ pub fn draw<T, Renderer>( font: &Renderer::Font, placeholder: Option<&str>, selected: Option<&T>, - style_sheet: &dyn StyleSheet, + style: <Renderer::Theme as StyleSheet>::Style, ) where Renderer: text::Renderer, + Renderer::Theme: StyleSheet, T: ToString, { let bounds = layout.bounds(); @@ -371,9 +376,9 @@ pub fn draw<T, Renderer>( let is_selected = selected.is_some(); let style = if is_mouse_over { - style_sheet.hovered() + theme.hovered(style) } else { - style_sheet.active() + theme.active(style) }; renderer.fill_quad( @@ -433,7 +438,7 @@ where [T]: ToOwned<Owned = Vec<T>>, Message: 'static, Renderer: text::Renderer + 'a, - Renderer::Theme: container::StyleSheet + scrollable::StyleSheet, + Renderer::Theme: StyleSheet, { fn width(&self) -> Length { self.width @@ -494,7 +499,7 @@ where fn draw( &self, renderer: &mut Renderer, - _theme: &Renderer::Theme, + theme: &Renderer::Theme, _style: &renderer::Style, layout: Layout<'_>, cursor_position: Point, @@ -502,6 +507,7 @@ where ) { draw( renderer, + theme, layout, cursor_position, self.padding, @@ -509,7 +515,7 @@ where &self.font, self.placeholder.as_ref().map(String::as_str), self.selected.as_ref(), - self.style_sheet.as_ref(), + self.style, ) } @@ -525,7 +531,7 @@ where self.text_size, self.font.clone(), &self.options, - self.style_sheet.as_ref(), + self.style, ) } } @@ -537,7 +543,12 @@ where [T]: ToOwned<Owned = Vec<T>>, Message: 'static, Renderer: text::Renderer + 'a, - Renderer::Theme: container::StyleSheet + scrollable::StyleSheet, + Renderer::Theme: StyleSheet + + container::StyleSheet + + scrollable::StyleSheet + + menu::StyleSheet, + <Renderer::Theme as StyleSheet>::Style: + Into<<Renderer::Theme as menu::StyleSheet>::Style>, { fn into(self) -> Element<'a, Message, Renderer> { Element::new(self) |