Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added ability to customize the handle of a pick_list #1562

Merged
merged 4 commits into from
Jan 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 83 additions & 14 deletions native/src/widget/pick_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,60 @@ use std::borrow::Cow;

pub use iced_style::pick_list::{Appearance, StyleSheet};

/// The handle to the right side of the [`PickList`].
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum Handle<Renderer>
where
Renderer: text::Renderer,
{
/// Displays an arrow icon (▼).
///
/// This is the default.
Arrow {
/// Font size of the content.
size: Option<u16>,
},
/// A custom handle.
Custom {
/// Font that will be used to display the `text`,
font: Renderer::Font,
/// Text that will be shown.
text: String,
/// Font size of the content.
size: Option<u16>,
},
/// No handle will be shown.
None,
}

impl<Renderer> Default for Handle<Renderer>
where
Renderer: text::Renderer,
{
fn default() -> Self {
Self::Arrow { size: None }
}
}

impl<Renderer> Handle<Renderer>
where
Renderer: text::Renderer,
{
fn content(&self) -> Option<(Renderer::Font, String, Option<u16>)> {
match self {
Self::Arrow { size } => Some((
Renderer::ICON_FONT,
Renderer::ARROW_DOWN_ICON.to_string(),
*size,
)),
Self::Custom { font, text, size } => {
Some((font.clone(), text.clone(), *size))
}
Self::None => None,
}
}
}

/// A widget for selecting a single value from a list of options.
#[allow(missing_debug_implementations)]
pub struct PickList<'a, T, Message, Renderer>
Expand All @@ -36,6 +90,7 @@ where
padding: Padding,
text_size: Option<u16>,
font: Renderer::Font,
handle: Handle<Renderer>,
style: <Renderer::Theme as StyleSheet>::Style,
}

Expand Down Expand Up @@ -67,9 +122,10 @@ where
placeholder: None,
selected,
width: Length::Shrink,
text_size: None,
padding: Self::DEFAULT_PADDING,
text_size: None,
font: Default::default(),
handle: Default::default(),
style: Default::default(),
}
}
Expand Down Expand Up @@ -104,6 +160,12 @@ where
self
}

/// Sets the [`Handle`] of the [`PickList`].
pub fn handle(mut self, handle: Handle<Renderer>) -> Self {
self.handle = handle;
self
}

/// Sets the style of the [`PickList`].
pub fn style(
mut self,
Expand Down Expand Up @@ -214,6 +276,7 @@ where
&self.font,
self.placeholder.as_deref(),
self.selected.as_ref(),
&self.handle,
&self.style,
)
}
Expand Down Expand Up @@ -515,6 +578,7 @@ pub fn draw<T, Renderer>(
font: &Renderer::Font,
placeholder: Option<&str>,
selected: Option<&T>,
handle: &Handle<Renderer>,
style: &<Renderer::Theme as StyleSheet>::Style,
) where
Renderer: text::Renderer,
Expand All @@ -541,19 +605,24 @@ pub fn draw<T, Renderer>(
style.background,
);

renderer.fill_text(Text {
content: &Renderer::ARROW_DOWN_ICON.to_string(),
font: Renderer::ICON_FONT,
size: bounds.height * style.icon_size,
bounds: Rectangle {
x: bounds.x + bounds.width - f32::from(padding.horizontal()),
y: bounds.center_y(),
..bounds
},
color: style.text_color,
horizontal_alignment: alignment::Horizontal::Right,
vertical_alignment: alignment::Vertical::Center,
});
if let Some((font, text, size)) = handle.content() {
let size = f32::from(size.unwrap_or_else(|| renderer.default_size()));

renderer.fill_text(Text {
content: &text,
size,
font,
color: style.handle_color,
bounds: Rectangle {
x: bounds.x + bounds.width - f32::from(padding.horizontal()),
y: bounds.center_y() - size / 2.0,
height: size,
..bounds
},
horizontal_alignment: alignment::Horizontal::Right,
vertical_alignment: alignment::Vertical::Top,
});
}

let label = selected.map(ToString::to_string);

Expand Down
2 changes: 1 addition & 1 deletion src/widget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub mod pane_grid {

pub mod pick_list {
//! Display a dropdown list of selectable values.
pub use iced_native::widget::pick_list::{Appearance, StyleSheet};
pub use iced_native::widget::pick_list::{Appearance, Handle, StyleSheet};

/// A widget allowing the selection of a single value from a list of options.
pub type PickList<'a, T, Message, Renderer = crate::Renderer> =
Expand Down
4 changes: 2 additions & 2 deletions style/src/pick_list.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub struct Appearance {
pub text_color: Color,
/// The placeholder [`Color`] of the pick list.
pub placeholder_color: Color,
/// The handle [`Color`] of the pick list.
pub handle_color: Color,
/// The [`Background`] of the pick list.
pub background: Background,
/// The border radius of the pick list.
Expand All @@ -16,8 +18,6 @@ pub struct Appearance {
pub border_width: f32,
/// The border color of the pick list.
pub border_color: Color,
/// The size of the arrow icon of the pick list.
pub icon_size: f32,
}

/// A set of rules that dictate the style of a container.
Expand Down
4 changes: 2 additions & 2 deletions style/src/theme.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,10 +534,10 @@ impl pick_list::StyleSheet for Theme {
text_color: palette.background.weak.text,
background: palette.background.weak.color.into(),
placeholder_color: palette.background.strong.color,
handle_color: palette.background.weak.text,
border_radius: 2.0,
border_width: 1.0,
border_color: palette.background.strong.color,
icon_size: 0.7,
}
}
PickList::Custom(custom, _) => custom.active(self),
Expand All @@ -553,10 +553,10 @@ impl pick_list::StyleSheet for Theme {
text_color: palette.background.weak.text,
background: palette.background.weak.color.into(),
placeholder_color: palette.background.strong.color,
handle_color: palette.background.weak.text,
border_radius: 2.0,
border_width: 1.0,
border_color: palette.primary.strong.color,
icon_size: 0.7,
}
}
PickList::Custom(custom, _) => custom.active(self),
Expand Down