summaryrefslogtreecommitdiffstats
path: root/widget
diff options
context:
space:
mode:
Diffstat (limited to 'widget')
-rw-r--r--widget/src/button.rs2
-rw-r--r--widget/src/canvas.rs2
-rw-r--r--widget/src/column.rs15
-rw-r--r--widget/src/container.rs37
-rw-r--r--widget/src/helpers.rs71
-rw-r--r--widget/src/keyed/column.rs2
-rw-r--r--widget/src/lazy.rs2
-rw-r--r--widget/src/lazy/cache.rs1
-rw-r--r--widget/src/lazy/component.rs61
-rw-r--r--widget/src/lazy/responsive.rs2
-rw-r--r--widget/src/mouse_area.rs2
-rw-r--r--widget/src/pane_grid.rs2
-rw-r--r--widget/src/pane_grid/content.rs2
-rw-r--r--widget/src/pane_grid/title_bar.rs2
-rw-r--r--widget/src/pick_list.rs24
-rw-r--r--widget/src/row.rs15
-rw-r--r--widget/src/scrollable.rs24
-rw-r--r--widget/src/shader.rs4
-rw-r--r--widget/src/stack.rs2
-rw-r--r--widget/src/text_editor.rs32
-rw-r--r--widget/src/text_input.rs137
-rw-r--r--widget/src/themer.rs4
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);
}