diff options
Diffstat (limited to 'native/src/widget')
-rw-r--r-- | native/src/widget/checkbox.rs | 4 | ||||
-rw-r--r-- | native/src/widget/helpers.rs | 4 | ||||
-rw-r--r-- | native/src/widget/operation/focusable.rs | 4 | ||||
-rw-r--r-- | native/src/widget/pick_list.rs | 97 | ||||
-rw-r--r-- | native/src/widget/text_input.rs | 12 | ||||
-rw-r--r-- | native/src/widget/toggler.rs | 18 |
6 files changed, 108 insertions, 31 deletions
diff --git a/native/src/widget/checkbox.rs b/native/src/widget/checkbox.rs index bec5c448..b46433c2 100644 --- a/native/src/widget/checkbox.rs +++ b/native/src/widget/checkbox.rs @@ -27,7 +27,7 @@ pub use iced_style::checkbox::{Appearance, StyleSheet}; /// /// let is_checked = true; /// -/// Checkbox::new(is_checked, "Toggle me!", Message::CheckboxToggled); +/// Checkbox::new("Toggle me!", is_checked, Message::CheckboxToggled); /// ``` /// ///  @@ -67,7 +67,7 @@ where /// * a function that will be called when the [`Checkbox`] is toggled. It /// will receive the new state of the [`Checkbox`] and must produce a /// `Message`. - pub fn new<F>(is_checked: bool, label: impl Into<String>, f: F) -> Self + pub fn new<F>(label: impl Into<String>, is_checked: bool, f: F) -> Self where F: 'a + Fn(bool) -> Message, { diff --git a/native/src/widget/helpers.rs b/native/src/widget/helpers.rs index 8cc1ae82..dfd949f6 100644 --- a/native/src/widget/helpers.rs +++ b/native/src/widget/helpers.rs @@ -129,7 +129,7 @@ where Renderer: crate::text::Renderer, Renderer::Theme: widget::checkbox::StyleSheet + widget::text::StyleSheet, { - widget::Checkbox::new(is_checked, label, f) + widget::Checkbox::new(label, is_checked, f) } /// Creates a new [`Radio`]. @@ -162,7 +162,7 @@ where Renderer: crate::text::Renderer, Renderer::Theme: widget::toggler::StyleSheet, { - widget::Toggler::new(is_checked, label, f) + widget::Toggler::new(label, is_checked, f) } /// Creates a new [`TextInput`]. diff --git a/native/src/widget/operation/focusable.rs b/native/src/widget/operation/focusable.rs index 0067006b..312e4894 100644 --- a/native/src/widget/operation/focusable.rs +++ b/native/src/widget/operation/focusable.rs @@ -18,10 +18,10 @@ pub trait Focusable { #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)] pub struct Count { /// The index of the current focused widget, if any. - focused: Option<usize>, + pub focused: Option<usize>, /// The total amount of focusable widgets. - total: usize, + pub total: usize, } /// Produces an [`Operation`] that focuses the widget with the given [`Id`]. diff --git a/native/src/widget/pick_list.rs b/native/src/widget/pick_list.rs index 52cb1ad1..c2853314 100644 --- a/native/src/widget/pick_list.rs +++ b/native/src/widget/pick_list.rs @@ -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); diff --git a/native/src/widget/text_input.rs b/native/src/widget/text_input.rs index 05b47ff9..8b4514e3 100644 --- a/native/src/widget/text_input.rs +++ b/native/src/widget/text_input.rs @@ -454,9 +454,17 @@ where ) } else { None - }; + } + .unwrap_or(0); - state.cursor.move_to(position.unwrap_or(0)); + if state.keyboard_modifiers.shift() { + state.cursor.select_range( + state.cursor.start(value), + position, + ); + } else { + state.cursor.move_to(position); + } state.is_dragging = true; } click::Kind::Double => { diff --git a/native/src/widget/toggler.rs b/native/src/widget/toggler.rs index 1ae65ba6..f0a944a3 100644 --- a/native/src/widget/toggler.rs +++ b/native/src/widget/toggler.rs @@ -24,9 +24,9 @@ pub use iced_style::toggler::{Appearance, StyleSheet}; /// TogglerToggled(bool), /// } /// -/// let is_active = true; +/// let is_toggled = true; /// -/// Toggler::new(is_active, String::from("Toggle me!"), |b| Message::TogglerToggled(b)); +/// Toggler::new(String::from("Toggle me!"), is_toggled, |b| Message::TogglerToggled(b)); /// ``` #[allow(missing_debug_implementations)] pub struct Toggler<'a, Message, Renderer> @@ -34,7 +34,7 @@ where Renderer: text::Renderer, Renderer::Theme: StyleSheet, { - is_active: bool, + is_toggled: bool, on_toggle: Box<dyn Fn(bool) -> Message + 'a>, label: Option<String>, width: Length, @@ -63,15 +63,15 @@ where /// will receive the new state of the [`Toggler`] and must produce a /// `Message`. pub fn new<F>( - is_active: bool, label: impl Into<Option<String>>, + is_toggled: bool, f: F, ) -> Self where F: 'a + Fn(bool) -> Message, { Toggler { - is_active, + is_toggled, on_toggle: Box::new(f), label: label.into(), width: Length::Fill, @@ -193,7 +193,7 @@ where let mouse_over = layout.bounds().contains(cursor_position); if mouse_over { - shell.publish((self.on_toggle)(!self.is_active)); + shell.publish((self.on_toggle)(!self.is_toggled)); event::Status::Captured } else { @@ -260,9 +260,9 @@ where let is_mouse_over = bounds.contains(cursor_position); let style = if is_mouse_over { - theme.hovered(&self.style, self.is_active) + theme.hovered(&self.style, self.is_toggled) } else { - theme.active(&self.style, self.is_active) + theme.active(&self.style, self.is_toggled) }; let border_radius = bounds.height / BORDER_RADIUS_RATIO; @@ -289,7 +289,7 @@ where let toggler_foreground_bounds = Rectangle { x: bounds.x - + if self.is_active { + + if self.is_toggled { bounds.width - 2.0 * space - (bounds.height - (4.0 * space)) } else { 2.0 * space |