diff options
Diffstat (limited to 'widget')
-rw-r--r-- | widget/src/button.rs | 2 | ||||
-rw-r--r-- | widget/src/canvas.rs | 2 | ||||
-rw-r--r-- | widget/src/column.rs | 15 | ||||
-rw-r--r-- | widget/src/container.rs | 37 | ||||
-rw-r--r-- | widget/src/helpers.rs | 71 | ||||
-rw-r--r-- | widget/src/keyed/column.rs | 2 | ||||
-rw-r--r-- | widget/src/lazy.rs | 2 | ||||
-rw-r--r-- | widget/src/lazy/cache.rs | 1 | ||||
-rw-r--r-- | widget/src/lazy/component.rs | 61 | ||||
-rw-r--r-- | widget/src/lazy/responsive.rs | 2 | ||||
-rw-r--r-- | widget/src/mouse_area.rs | 2 | ||||
-rw-r--r-- | widget/src/pane_grid.rs | 2 | ||||
-rw-r--r-- | widget/src/pane_grid/content.rs | 2 | ||||
-rw-r--r-- | widget/src/pane_grid/title_bar.rs | 2 | ||||
-rw-r--r-- | widget/src/pick_list.rs | 24 | ||||
-rw-r--r-- | widget/src/row.rs | 15 | ||||
-rw-r--r-- | widget/src/scrollable.rs | 24 | ||||
-rw-r--r-- | widget/src/shader.rs | 4 | ||||
-rw-r--r-- | widget/src/stack.rs | 2 | ||||
-rw-r--r-- | widget/src/text_editor.rs | 32 | ||||
-rw-r--r-- | widget/src/text_input.rs | 137 | ||||
-rw-r--r-- | widget/src/themer.rs | 4 |
22 files changed, 243 insertions, 202 deletions
diff --git a/widget/src/button.rs b/widget/src/button.rs index dc949671..5d446fea 100644 --- a/widget/src/button.rs +++ b/widget/src/button.rs @@ -205,7 +205,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.content.as_widget().operate( diff --git a/widget/src/canvas.rs b/widget/src/canvas.rs index be09f163..73cef087 100644 --- a/widget/src/canvas.rs +++ b/widget/src/canvas.rs @@ -172,7 +172,7 @@ where core::Event::Keyboard(keyboard_event) => { Some(Event::Keyboard(keyboard_event)) } - _ => None, + core::Event::Window(_) => None, }; if let Some(canvas_event) = canvas_event { diff --git a/widget/src/column.rs b/widget/src/column.rs index df7829b3..0b81c545 100644 --- a/widget/src/column.rs +++ b/widget/src/column.rs @@ -161,6 +161,19 @@ where } } +impl<'a, Message, Theme, Renderer: crate::core::Renderer> + FromIterator<Element<'a, Message, Theme, Renderer>> + for Column<'a, Message, Theme, Renderer> +{ + fn from_iter< + T: IntoIterator<Item = Element<'a, Message, Theme, Renderer>>, + >( + iter: T, + ) -> Self { + Self::with_children(iter) + } +} + impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Column<'a, Message, Theme, Renderer> where @@ -208,7 +221,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.children diff --git a/widget/src/container.rs b/widget/src/container.rs index 8b6638d4..e917471f 100644 --- a/widget/src/container.rs +++ b/widget/src/container.rs @@ -13,7 +13,7 @@ use crate::core::{ Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::Command; +use crate::runtime::Task; /// An element decorating some content. /// @@ -122,9 +122,6 @@ where /// Sets the [`Container`] to fill all the available space. /// - /// This can be useful to quickly position content when chained with - /// alignment functions—like [`center`]. - /// /// Calling this method is equivalent to chaining [`fill_x`] and /// [`fill_y`]. /// @@ -159,20 +156,14 @@ where self } - /// Sets the [`Container`] to fill the available space in the horizontal axis - /// and centers its contents there. - pub fn center_x(mut self) -> Self { - self.width = Length::Fill; - self.horizontal_alignment = alignment::Horizontal::Center; - self + /// Sets the width of the [`Container`] and centers its contents horizontally. + pub fn center_x(self, width: impl Into<Length>) -> Self { + self.width(width).align_x(alignment::Horizontal::Center) } - /// Sets the [`Container`] to fill the available space in the vertical axis - /// and centers its contents there. - pub fn center_y(mut self) -> Self { - self.height = Length::Fill; - self.vertical_alignment = alignment::Vertical::Center; - self + /// Sets the height of the [`Container`] and centers its contents vertically. + pub fn center_y(self, height: impl Into<Length>) -> Self { + self.height(height).align_y(alignment::Vertical::Center) } /// Centers the contents in both the horizontal and vertical axes of the @@ -182,8 +173,10 @@ where /// /// [`center_x`]: Self::center_x /// [`center_y`]: Self::center_y - pub fn center(self) -> Self { - self.center_x().center_y() + pub fn center(self, length: impl Into<Length>) -> Self { + let length = length.into(); + + self.center_x(length).center_y(length) } /// Sets whether the contents of the [`Container`] should be clipped on @@ -265,7 +258,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container( self.id.as_ref().map(|id| &id.0), @@ -464,9 +457,9 @@ impl From<Id> for widget::Id { } } -/// Produces a [`Command`] that queries the visible screen bounds of the +/// Produces a [`Task`] that queries the visible screen bounds of the /// [`Container`] with the given [`Id`]. -pub fn visible_bounds(id: Id) -> Command<Option<Rectangle>> { +pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> { struct VisibleBounds { target: widget::Id, depth: usize, @@ -545,7 +538,7 @@ pub fn visible_bounds(id: Id) -> Command<Option<Rectangle>> { } } - Command::widget(VisibleBounds { + Task::widget(VisibleBounds { target: id.into(), depth: 0, scrollables: Vec::new(), diff --git a/widget/src/helpers.rs b/widget/src/helpers.rs index fd8614f5..62343a55 100644 --- a/widget/src/helpers.rs +++ b/widget/src/helpers.rs @@ -12,7 +12,7 @@ use crate::pick_list::{self, PickList}; use crate::progress_bar::{self, ProgressBar}; use crate::radio::{self, Radio}; use crate::rule::{self, Rule}; -use crate::runtime::Command; +use crate::runtime::{Action, Task}; use crate::scrollable::{self, Scrollable}; use crate::slider::{self, Slider}; use crate::text::{self, Text}; @@ -65,6 +65,52 @@ macro_rules! stack { ); } +/// Creates a new [`Text`] widget with the provided content. +/// +/// [`Text`]: core::widget::Text +/// +/// This macro uses the same syntax as [`format!`], but creates a new [`Text`] widget instead. +/// +/// See [the formatting documentation in `std::fmt`](std::fmt) +/// for details of the macro argument syntax. +/// +/// # Examples +/// +/// ```no_run +/// # mod iced { +/// # pub struct Element<Message>(pub std::marker::PhantomData<Message>); +/// # pub mod widget { +/// # macro_rules! text { +/// # ($($arg:tt)*) => {unimplemented!()} +/// # } +/// # pub(crate) use text; +/// # } +/// # } +/// # struct Example; +/// # enum Message {} +/// use iced::Element; +/// use iced::widget::text; +/// +/// impl Example { +/// fn view(&self) -> Element<Message> { +/// let simple = text!("Hello, world!"); +/// +/// let keyword = text!("Hello, {}", "world!"); +/// +/// let planet = "Earth"; +/// let local_variable = text!("Hello, {planet}!"); +/// // ... +/// # iced::Element(std::marker::PhantomData) +/// } +/// } +/// ``` +#[macro_export] +macro_rules! text { + ($($arg:tt)*) => { + $crate::Text::new(format!($($arg)*)) + }; +} + /// Creates a new [`Container`] with the provided content. /// /// [`Container`]: crate::Container @@ -83,9 +129,10 @@ where /// /// This is equivalent to: /// ```rust,no_run +/// # use iced_widget::core::Length; /// # use iced_widget::Container; /// # fn container<A>(x: A) -> Container<'static, ()> { unreachable!() } -/// let centered = container("Centered!").center(); +/// let centered = container("Centered!").center(Length::Fill); /// ``` /// /// [`Container`]: crate::Container @@ -96,7 +143,7 @@ where Theme: container::Catalog + 'a, Renderer: core::Renderer, { - container(content).fill().center() + container(content).center(Length::Fill) } /// Creates a new [`Column`] with the given children. @@ -228,7 +275,7 @@ where state: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn operation::Operation<Message>, + operation: &mut dyn operation::Operation<()>, ) { self.content .as_widget() @@ -430,7 +477,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn operation::Operation<Message>, + operation: &mut dyn operation::Operation<()>, ) { let children = [&self.base, &self.top] .into_iter() @@ -882,19 +929,13 @@ where } /// Focuses the previous focusable widget. -pub fn focus_previous<Message>() -> Command<Message> -where - Message: 'static, -{ - Command::widget(operation::focusable::focus_previous()) +pub fn focus_previous<T>() -> Task<T> { + Task::effect(Action::widget(operation::focusable::focus_previous())) } /// Focuses the next focusable widget. -pub fn focus_next<Message>() -> Command<Message> -where - Message: 'static, -{ - Command::widget(operation::focusable::focus_next()) +pub fn focus_next<T>() -> Task<T> { + Task::effect(Action::widget(operation::focusable::focus_next())) } /// A container intercepting mouse events. diff --git a/widget/src/keyed/column.rs b/widget/src/keyed/column.rs index fdaadefa..69991d1f 100644 --- a/widget/src/keyed/column.rs +++ b/widget/src/keyed/column.rs @@ -265,7 +265,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.children diff --git a/widget/src/lazy.rs b/widget/src/lazy.rs index 04783dbe..606da22d 100644 --- a/widget/src/lazy.rs +++ b/widget/src/lazy.rs @@ -182,7 +182,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { self.with_element(|element| { element.as_widget().operate( diff --git a/widget/src/lazy/cache.rs b/widget/src/lazy/cache.rs index f922fd19..b341c234 100644 --- a/widget/src/lazy/cache.rs +++ b/widget/src/lazy/cache.rs @@ -1,3 +1,4 @@ +#![allow(dead_code)] use crate::core::overlay; use crate::core::Element; diff --git a/widget/src/lazy/component.rs b/widget/src/lazy/component.rs index 7ba71a02..f079c0df 100644 --- a/widget/src/lazy/component.rs +++ b/widget/src/lazy/component.rs @@ -59,7 +59,7 @@ pub trait Component<Message, Theme = crate::Theme, Renderer = crate::Renderer> { fn operate( &self, _state: &mut Self::State, - _operation: &mut dyn widget::Operation<Message>, + _operation: &mut dyn widget::Operation<()>, ) { } @@ -172,7 +172,7 @@ where fn rebuild_element_with_operation( &self, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { let heads = self.state.borrow_mut().take().unwrap().into_heads(); @@ -358,70 +358,17 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { self.rebuild_element_with_operation(operation); - struct MapOperation<'a, B> { - operation: &'a mut dyn widget::Operation<B>, - } - - impl<'a, T, B> widget::Operation<T> for MapOperation<'a, B> { - fn container( - &mut self, - id: Option<&widget::Id>, - bounds: Rectangle, - operate_on_children: &mut dyn FnMut( - &mut dyn widget::Operation<T>, - ), - ) { - self.operation.container(id, bounds, &mut |operation| { - operate_on_children(&mut MapOperation { operation }); - }); - } - - fn focusable( - &mut self, - state: &mut dyn widget::operation::Focusable, - id: Option<&widget::Id>, - ) { - self.operation.focusable(state, id); - } - - fn text_input( - &mut self, - state: &mut dyn widget::operation::TextInput, - id: Option<&widget::Id>, - ) { - self.operation.text_input(state, id); - } - - fn scrollable( - &mut self, - state: &mut dyn widget::operation::Scrollable, - id: Option<&widget::Id>, - bounds: Rectangle, - translation: Vector, - ) { - self.operation.scrollable(state, id, bounds, translation); - } - - fn custom( - &mut self, - state: &mut dyn std::any::Any, - id: Option<&widget::Id>, - ) { - self.operation.custom(state, id); - } - } - let tree = tree.state.downcast_mut::<Rc<RefCell<Option<Tree>>>>(); self.with_element(|element| { element.as_widget().operate( &mut tree.borrow_mut().as_mut().unwrap().children[0], layout, renderer, - &mut MapOperation { operation }, + operation, ); }); } diff --git a/widget/src/lazy/responsive.rs b/widget/src/lazy/responsive.rs index f612102e..27f52617 100644 --- a/widget/src/lazy/responsive.rs +++ b/widget/src/lazy/responsive.rs @@ -161,7 +161,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { let state = tree.state.downcast_mut::<State>(); let mut content = self.content.borrow_mut(); diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index d7235cf6..17cae53b 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -178,7 +178,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { self.content.as_widget().operate( &mut tree.children[0], diff --git a/widget/src/pane_grid.rs b/widget/src/pane_grid.rs index acfa9d44..c3da3879 100644 --- a/widget/src/pane_grid.rs +++ b/widget/src/pane_grid.rs @@ -324,7 +324,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.contents diff --git a/widget/src/pane_grid/content.rs b/widget/src/pane_grid/content.rs index 30ad52ca..d45fc0cd 100644 --- a/widget/src/pane_grid/content.rs +++ b/widget/src/pane_grid/content.rs @@ -214,7 +214,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { let body_layout = if let Some(title_bar) = &self.title_bar { let mut children = layout.children(); diff --git a/widget/src/pane_grid/title_bar.rs b/widget/src/pane_grid/title_bar.rs index c2eeebb7..c05f1252 100644 --- a/widget/src/pane_grid/title_bar.rs +++ b/widget/src/pane_grid/title_bar.rs @@ -278,7 +278,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn widget::Operation<Message>, + operation: &mut dyn widget::Operation<()>, ) { let mut children = layout.children(); let padded = children.next().unwrap(); diff --git a/widget/src/pick_list.rs b/widget/src/pick_list.rs index edccfdaa..97de5b48 100644 --- a/widget/src/pick_list.rs +++ b/widget/src/pick_list.rs @@ -161,6 +161,19 @@ where self } + /// Sets the style of the [`Menu`]. + #[must_use] + pub fn menu_style( + mut self, + style: impl Fn(&Theme) -> menu::Style + 'a, + ) -> Self + where + <Theme as menu::Catalog>::Class<'a>: From<menu::StyleFn<'a, Theme>>, + { + self.menu_class = (Box::new(style) as menu::StyleFn<'a, Theme>).into(); + self + } + /// Sets the style class of the [`PickList`]. #[cfg(feature = "advanced")] #[must_use] @@ -171,6 +184,17 @@ where self.class = class.into(); self } + + /// Sets the style class of the [`Menu`]. + #[cfg(feature = "advanced")] + #[must_use] + pub fn menu_class( + mut self, + class: impl Into<<Theme as menu::Catalog>::Class<'a>>, + ) -> Self { + self.menu_class = class.into(); + self + } } impl<'a, T, L, V, Message, Theme, Renderer> Widget<Message, Theme, Renderer> diff --git a/widget/src/row.rs b/widget/src/row.rs index fa352171..c8fcdb61 100644 --- a/widget/src/row.rs +++ b/widget/src/row.rs @@ -152,6 +152,19 @@ where } } +impl<'a, Message, Theme, Renderer: crate::core::Renderer> + FromIterator<Element<'a, Message, Theme, Renderer>> + for Row<'a, Message, Theme, Renderer> +{ + fn from_iter< + T: IntoIterator<Item = Element<'a, Message, Theme, Renderer>>, + >( + iter: T, + ) -> Self { + Self::with_children(iter) + } +} + impl<'a, Message, Theme, Renderer> Widget<Message, Theme, Renderer> for Row<'a, Message, Theme, Renderer> where @@ -197,7 +210,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.children diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 6fc00f87..c3d08223 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -15,7 +15,7 @@ use crate::core::{ self, Background, Border, Clipboard, Color, Element, Layout, Length, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::Command; +use crate::runtime::{Action, Task}; pub use operation::scrollable::{AbsoluteOffset, RelativeOffset}; @@ -295,7 +295,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { let state = tree.state.downcast_mut::<State>(); @@ -952,22 +952,18 @@ impl From<Id> for widget::Id { } } -/// Produces a [`Command`] that snaps the [`Scrollable`] with the given [`Id`] +/// Produces a [`Task`] that snaps the [`Scrollable`] with the given [`Id`] /// to the provided `percentage` along the x & y axis. -pub fn snap_to<Message: 'static>( - id: Id, - offset: RelativeOffset, -) -> Command<Message> { - Command::widget(operation::scrollable::snap_to(id.0, offset)) +pub fn snap_to<T>(id: Id, offset: RelativeOffset) -> Task<T> { + Task::effect(Action::widget(operation::scrollable::snap_to(id.0, offset))) } -/// Produces a [`Command`] that scrolls the [`Scrollable`] with the given [`Id`] +/// Produces a [`Task`] that scrolls the [`Scrollable`] with the given [`Id`] /// to the provided [`AbsoluteOffset`] along the x & y axis. -pub fn scroll_to<Message: 'static>( - id: Id, - offset: AbsoluteOffset, -) -> Command<Message> { - Command::widget(operation::scrollable::scroll_to(id.0, offset)) +pub fn scroll_to<T>(id: Id, offset: AbsoluteOffset) -> Task<T> { + Task::effect(Action::widget(operation::scrollable::scroll_to( + id.0, offset, + ))) } /// Returns [`true`] if the viewport actually changed. diff --git a/widget/src/shader.rs b/widget/src/shader.rs index fad2f4eb..3c81f8ed 100644 --- a/widget/src/shader.rs +++ b/widget/src/shader.rs @@ -107,10 +107,10 @@ where Some(Event::Keyboard(keyboard_event)) } core::Event::Touch(touch_event) => Some(Event::Touch(touch_event)), - core::Event::Window(_, window::Event::RedrawRequested(instant)) => { + core::Event::Window(window::Event::RedrawRequested(instant)) => { Some(Event::RedrawRequested(instant)) } - _ => None, + core::Event::Window(_) => None, }; if let Some(custom_shader_event) = custom_shader_event { diff --git a/widget/src/stack.rs b/widget/src/stack.rs index 5035541b..efa9711d 100644 --- a/widget/src/stack.rs +++ b/widget/src/stack.rs @@ -189,7 +189,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { operation.container(None, layout.bounds(), &mut |operation| { self.children diff --git a/widget/src/text_editor.rs b/widget/src/text_editor.rs index 7c0b98ea..fc2ade43 100644 --- a/widget/src/text_editor.rs +++ b/widget/src/text_editor.rs @@ -466,6 +466,12 @@ where shell.publish(on_edit(action)); } Update::Scroll(lines) => { + let bounds = self.content.0.borrow().editor.bounds(); + + if bounds.height >= i32::MAX as f32 { + return event::Status::Ignored; + } + let lines = lines + state.partial_scroll; state.partial_scroll = lines.fract(); @@ -768,9 +774,17 @@ impl Update { if let keyboard::Key::Named(named_key) = key.as_ref() { if let Some(motion) = motion(named_key) { - let motion = if platform::is_jump_modifier_pressed( - modifiers, - ) { + let motion = if modifiers.macos_command() { + match motion { + Motion::Left => Motion::Home, + Motion::Right => Motion::End, + _ => motion, + } + } else { + motion + }; + + let motion = if modifiers.jump() { motion.widen() } else { motion @@ -807,18 +821,6 @@ fn motion(key: key::Named) -> Option<Motion> { } } -mod platform { - use crate::core::keyboard; - - pub fn is_jump_modifier_pressed(modifiers: keyboard::Modifiers) -> bool { - if cfg!(target_os = "macos") { - modifiers.alt() - } else { - modifiers.control() - } - } -} - /// The possible status of a [`TextEditor`]. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Status { diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index e9f07838..4e89236b 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -30,7 +30,7 @@ use crate::core::{ Background, Border, Color, Element, Layout, Length, Padding, Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget, }; -use crate::runtime::Command; +use crate::runtime::{Action, Task}; /// A field that can be filled with text. /// @@ -540,7 +540,7 @@ where tree: &mut Tree, _layout: Layout<'_>, _renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>(); @@ -826,7 +826,7 @@ where } } keyboard::Key::Named(key::Named::Backspace) => { - if platform::is_jump_modifier_pressed(modifiers) + if modifiers.jump() && state.cursor.selection(&self.value).is_none() { if self.is_secure { @@ -850,7 +850,7 @@ where update_cache(state, &self.value); } keyboard::Key::Named(key::Named::Delete) => { - if platform::is_jump_modifier_pressed(modifiers) + if modifiers.jump() && state.cursor.selection(&self.value).is_none() { if self.is_secure { @@ -876,10 +876,52 @@ where update_cache(state, &self.value); } + keyboard::Key::Named(key::Named::Home) => { + if modifiers.shift() { + state.cursor.select_range( + state.cursor.start(&self.value), + 0, + ); + } else { + state.cursor.move_to(0); + } + } + keyboard::Key::Named(key::Named::End) => { + if modifiers.shift() { + state.cursor.select_range( + state.cursor.start(&self.value), + self.value.len(), + ); + } else { + state.cursor.move_to(self.value.len()); + } + } + keyboard::Key::Named(key::Named::ArrowLeft) + if modifiers.macos_command() => + { + if modifiers.shift() { + state.cursor.select_range( + state.cursor.start(&self.value), + 0, + ); + } else { + state.cursor.move_to(0); + } + } + keyboard::Key::Named(key::Named::ArrowRight) + if modifiers.macos_command() => + { + if modifiers.shift() { + state.cursor.select_range( + state.cursor.start(&self.value), + self.value.len(), + ); + } else { + state.cursor.move_to(self.value.len()); + } + } keyboard::Key::Named(key::Named::ArrowLeft) => { - if platform::is_jump_modifier_pressed(modifiers) - && !self.is_secure - { + if modifiers.jump() && !self.is_secure { if modifiers.shift() { state .cursor @@ -896,9 +938,7 @@ where } } keyboard::Key::Named(key::Named::ArrowRight) => { - if platform::is_jump_modifier_pressed(modifiers) - && !self.is_secure - { + if modifiers.jump() && !self.is_secure { if modifiers.shift() { state .cursor @@ -914,26 +954,6 @@ where state.cursor.move_right(&self.value); } } - keyboard::Key::Named(key::Named::Home) => { - if modifiers.shift() { - state.cursor.select_range( - state.cursor.start(&self.value), - 0, - ); - } else { - state.cursor.move_to(0); - } - } - keyboard::Key::Named(key::Named::End) => { - if modifiers.shift() { - state.cursor.select_range( - state.cursor.start(&self.value), - self.value.len(), - ); - } else { - state.cursor.move_to(self.value.len()); - } - } keyboard::Key::Named(key::Named::Escape) => { state.is_focused = None; state.is_dragging = false; @@ -983,14 +1003,14 @@ where state.keyboard_modifiers = modifiers; } - Event::Window(_, window::Event::Unfocused) => { + Event::Window(window::Event::Unfocused) => { let state = state::<Renderer>(tree); if let Some(focus) = &mut state.is_focused { focus.is_window_focused = false; } } - Event::Window(_, window::Event::Focused) => { + Event::Window(window::Event::Focused) => { let state = state::<Renderer>(tree); if let Some(focus) = &mut state.is_focused { @@ -1000,7 +1020,7 @@ where shell.request_redraw(window::RedrawRequest::NextFrame); } } - Event::Window(_, window::Event::RedrawRequested(now)) => { + Event::Window(window::Event::RedrawRequested(now)) => { let state = state::<Renderer>(tree); if let Some(focus) = &mut state.is_focused { @@ -1120,35 +1140,38 @@ impl From<Id> for widget::Id { } } -/// Produces a [`Command`] that focuses the [`TextInput`] with the given [`Id`]. -pub fn focus<Message: 'static>(id: Id) -> Command<Message> { - Command::widget(operation::focusable::focus(id.0)) +/// Produces a [`Task`] that focuses the [`TextInput`] with the given [`Id`]. +pub fn focus<T>(id: Id) -> Task<T> { + Task::effect(Action::widget(operation::focusable::focus(id.0))) } -/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// end. -pub fn move_cursor_to_end<Message: 'static>(id: Id) -> Command<Message> { - Command::widget(operation::text_input::move_cursor_to_end(id.0)) +pub fn move_cursor_to_end<T>(id: Id) -> Task<T> { + Task::effect(Action::widget(operation::text_input::move_cursor_to_end( + id.0, + ))) } -/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// front. -pub fn move_cursor_to_front<Message: 'static>(id: Id) -> Command<Message> { - Command::widget(operation::text_input::move_cursor_to_front(id.0)) +pub fn move_cursor_to_front<T>(id: Id) -> Task<T> { + Task::effect(Action::widget(operation::text_input::move_cursor_to_front( + id.0, + ))) } -/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the +/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// provided position. -pub fn move_cursor_to<Message: 'static>( - id: Id, - position: usize, -) -> Command<Message> { - Command::widget(operation::text_input::move_cursor_to(id.0, position)) +pub fn move_cursor_to<T>(id: Id, position: usize) -> Task<T> { + Task::effect(Action::widget(operation::text_input::move_cursor_to( + id.0, position, + ))) } -/// Produces a [`Command`] that selects all the content of the [`TextInput`] with the given [`Id`]. -pub fn select_all<Message: 'static>(id: Id) -> Command<Message> { - Command::widget(operation::text_input::select_all(id.0)) +/// Produces a [`Task`] that selects all the content of the [`TextInput`] with the given [`Id`]. +pub fn select_all<T>(id: Id) -> Task<T> { + Task::effect(Action::widget(operation::text_input::select_all(id.0))) } /// The state of a [`TextInput`]. @@ -1281,18 +1304,6 @@ impl<P: text::Paragraph> operation::TextInput for State<P> { } } -mod platform { - use crate::core::keyboard; - - pub fn is_jump_modifier_pressed(modifiers: keyboard::Modifiers) -> bool { - if cfg!(target_os = "macos") { - modifiers.alt() - } else { - modifiers.control() - } - } -} - fn offset<P: text::Paragraph>( text_bounds: Rectangle, value: &Value, diff --git a/widget/src/themer.rs b/widget/src/themer.rs index f4597458..9eb47d84 100644 --- a/widget/src/themer.rs +++ b/widget/src/themer.rs @@ -104,7 +104,7 @@ where tree: &mut Tree, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { self.content .as_widget() @@ -236,7 +236,7 @@ where &mut self, layout: Layout<'_>, renderer: &Renderer, - operation: &mut dyn Operation<Message>, + operation: &mut dyn Operation<()>, ) { self.content.operate(layout, renderer, operation); } |