Skip to content

Commit

Permalink
Merge pull request #1562 from casperstorm/feat/custom-accessory-content
Browse files Browse the repository at this point in the history
Added ability to customize the handle of a `pick_list`
  • Loading branch information
hecrj authored Jan 2, 2023

Verified

This commit was signed with the committer’s verified signature.
kbdharun K.B.Dharun Krishna
2 parents d956b8a + 39f4918 commit da1b375
Showing 4 changed files with 88 additions and 19 deletions.
97 changes: 83 additions & 14 deletions native/src/widget/pick_list.rs
Original file line number Diff line number Diff line change
@@ -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>
@@ -36,6 +90,7 @@ where
padding: Padding,
text_size: Option<u16>,
font: Renderer::Font,
handle: Handle<Renderer>,
style: <Renderer::Theme as StyleSheet>::Style,
}

@@ -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(),
}
}
@@ -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,
@@ -214,6 +276,7 @@ where
&self.font,
self.placeholder.as_deref(),
self.selected.as_ref(),
&self.handle,
&self.style,
)
}
@@ -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,
@@ -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);

2 changes: 1 addition & 1 deletion src/widget.rs
Original file line number Diff line number Diff line change
@@ -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> =
4 changes: 2 additions & 2 deletions style/src/pick_list.rs
Original file line number Diff line number Diff line change
@@ -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.
@@ -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.
4 changes: 2 additions & 2 deletions style/src/theme.rs
Original file line number Diff line number Diff line change
@@ -535,10 +535,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),
@@ -554,10 +554,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.hovered(self),

0 comments on commit da1b375

Please sign in to comment.