Add styling support for ComboBox and Menu

This commit is contained in:
Héctor Ramón Jiménez 2020-06-11 20:41:11 +02:00
parent 0ff5a02550
commit 61f22b1db2
11 changed files with 206 additions and 41 deletions

View file

@ -10,6 +10,7 @@ pub struct Menu<'a, Message, Renderer: self::Renderer> {
is_open: &'a mut bool,
width: u16,
target_height: f32,
style: <Renderer as self::Renderer>::Style,
}
#[derive(Default)]
@ -43,6 +44,7 @@ where
target_height: f32,
text_size: u16,
padding: u16,
style: <Renderer as self::Renderer>::Style,
) -> Self
where
T: Clone + ToString,
@ -55,6 +57,7 @@ where
on_selected,
text_size,
padding,
style.clone(),
)),
)
.padding(1);
@ -64,6 +67,7 @@ where
is_open: &mut state.is_open,
width,
target_height,
style,
}
}
}
@ -156,11 +160,16 @@ where
self.container
.draw(renderer, defaults, layout, cursor_position);
renderer.decorate(layout.bounds(), cursor_position, primitives)
renderer.decorate(
layout.bounds(),
cursor_position,
&self.style,
primitives,
)
}
}
struct List<'a, T, Message>
struct List<'a, T, Message, Renderer: self::Renderer>
where
[T]: ToOwned,
{
@ -169,9 +178,10 @@ where
on_selected: Box<dyn Fn(T) -> Message>,
text_size: u16,
padding: u16,
style: <Renderer as self::Renderer>::Style,
}
impl<'a, T, Message> List<'a, T, Message>
impl<'a, T, Message, Renderer: self::Renderer> List<'a, T, Message, Renderer>
where
[T]: ToOwned,
{
@ -181,6 +191,7 @@ where
on_selected: Box<dyn Fn(T) -> Message>,
text_size: u16,
padding: u16,
style: <Renderer as self::Renderer>::Style,
) -> Self {
List {
hovered_option,
@ -188,12 +199,13 @@ where
on_selected,
text_size,
padding,
style,
}
}
}
impl<'a, T, Message, Renderer> Widget<'a, Message, Renderer>
for List<'a, T, Message>
impl<'a, T, Message, Renderer: self::Renderer> Widget<'a, Message, Renderer>
for List<'a, T, Message, Renderer>
where
T: ToString + Clone,
[T]: ToOwned,
@ -286,15 +298,19 @@ where
*self.hovered_option,
self.text_size,
self.padding,
&self.style,
)
}
}
pub trait Renderer: scrollable::Renderer + container::Renderer {
type Style: Default + Clone;
fn decorate(
&mut self,
bounds: Rectangle,
cursor_position: Point,
style: &<Self as Renderer>::Style,
primitive: Self::Output,
) -> Self::Output;
@ -306,16 +322,17 @@ pub trait Renderer: scrollable::Renderer + container::Renderer {
hovered_option: Option<usize>,
text_size: u16,
padding: u16,
style: &<Self as Renderer>::Style,
) -> Self::Output;
}
impl<'a, T, Message, Renderer> Into<Element<'a, Message, Renderer>>
for List<'a, T, Message>
for List<'a, T, Message, Renderer>
where
T: ToString + Clone,
[T]: ToOwned,
Message: 'static,
Renderer: self::Renderer,
Renderer: 'a + self::Renderer,
{
fn into(self) -> Element<'a, Message, Renderer> {
Element::new(self)

View file

@ -6,7 +6,7 @@ use crate::{
};
use std::borrow::Cow;
pub struct ComboBox<'a, T, Message>
pub struct ComboBox<'a, T, Message, Renderer: self::Renderer>
where
[T]: ToOwned<Owned = Vec<T>>,
{
@ -16,6 +16,7 @@ where
width: Length,
padding: u16,
text_size: Option<u16>,
style: <Renderer as self::Renderer>::Style,
}
#[derive(Default)]
@ -28,7 +29,8 @@ pub struct Internal<'a, T, Message> {
on_selected: Box<dyn Fn(T) -> Message>,
}
impl<'a, T: 'a, Message> ComboBox<'a, T, Message>
impl<'a, T: 'a, Message, Renderer: self::Renderer>
ComboBox<'a, T, Message, Renderer>
where
T: ToString,
[T]: ToOwned<Owned = Vec<T>>,
@ -48,7 +50,8 @@ where
selected,
width: Length::Shrink,
text_size: None,
padding: 5,
padding: Renderer::DEFAULT_PADDING,
style: <Renderer as self::Renderer>::Style::default(),
}
}
@ -72,10 +75,21 @@ where
self.text_size = Some(size);
self
}
/// Sets the style of the [`ComboBox`].
///
/// [`ComboBox`]: struct.ComboBox.html
pub fn style(
mut self,
style: impl Into<<Renderer as self::Renderer>::Style>,
) -> Self {
self.style = style.into();
self
}
}
impl<'a, T: 'a, Message, Renderer> Widget<'a, Message, Renderer>
for ComboBox<'a, T, Message>
for ComboBox<'a, T, Message, Renderer>
where
T: Clone + ToString + Eq,
[T]: ToOwned<Owned = Vec<T>>,
@ -196,6 +210,7 @@ where
self.selected.as_ref().map(ToString::to_string),
self.text_size.unwrap_or(renderer.default_size()),
self.padding,
&self.style,
)
}
@ -223,6 +238,7 @@ where
bounds.height,
self.text_size.unwrap_or(20),
self.padding,
Renderer::menu_style(&self.style),
)),
))
} else {
@ -235,8 +251,14 @@ where
}
pub trait Renderer: text::Renderer + menu::Renderer {
type Style: Default;
const DEFAULT_PADDING: u16;
fn menu_style(
style: &<Self as Renderer>::Style,
) -> <Self as menu::Renderer>::Style;
fn draw(
&mut self,
bounds: Rectangle,
@ -244,11 +266,12 @@ pub trait Renderer: text::Renderer + menu::Renderer {
selected: Option<String>,
text_size: u16,
padding: u16,
style: &<Self as Renderer>::Style,
) -> Self::Output;
}
impl<'a, T: 'a, Message, Renderer> Into<Element<'a, Message, Renderer>>
for ComboBox<'a, T, Message>
for ComboBox<'a, T, Message, Renderer>
where
T: Clone + ToString + Eq,
[T]: ToOwned<Owned = Vec<T>>,