diff options
-rw-r--r-- | core/src/window/id.rs | 8 | ||||
-rw-r--r-- | examples/multi_window/src/main.rs | 6 | ||||
-rw-r--r-- | examples/todos/Cargo.toml | 1 | ||||
-rw-r--r-- | examples/todos/src/main.rs | 7 | ||||
-rw-r--r-- | widget/src/scrollable.rs | 20 | ||||
-rw-r--r-- | widget/src/text_input.rs | 39 |
6 files changed, 49 insertions, 32 deletions
diff --git a/core/src/window/id.rs b/core/src/window/id.rs index 1a75fa27..5d5a817e 100644 --- a/core/src/window/id.rs +++ b/core/src/window/id.rs @@ -1,5 +1,5 @@ +use std::fmt; use std::hash::Hash; - use std::sync::atomic::{self, AtomicU64}; /// The id of the window. @@ -14,3 +14,9 @@ impl Id { Id(COUNT.fetch_add(1, atomic::Ordering::Relaxed)) } } + +impl fmt::Display for Id { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + self.0.fmt(f) + } +} diff --git a/examples/multi_window/src/main.rs b/examples/multi_window/src/main.rs index ab09116e..b43a627a 100644 --- a/examples/multi_window/src/main.rs +++ b/examples/multi_window/src/main.rs @@ -25,7 +25,6 @@ struct Window { scale_input: String, current_scale: f64, theme: Theme, - input_id: iced::widget::text_input::Id, } #[derive(Debug, Clone)] @@ -86,7 +85,7 @@ impl Example { } Message::WindowOpened(id) => { let window = Window::new(self.windows.len() + 1); - let focus_input = text_input::focus(window.input_id.clone()); + let focus_input = text_input::focus(format!("input-{id}")); self.windows.insert(id, window); @@ -163,7 +162,6 @@ impl Window { scale_input: "1.0".to_string(), current_scale: 1.0, theme: Theme::ALL[count % Theme::ALL.len()].clone(), - input_id: text_input::Id::unique(), } } @@ -182,7 +180,7 @@ impl Window { text("Window title:"), text_input("Window Title", &self.title) .on_input(move |msg| { Message::TitleChanged(id, msg) }) - .id(self.input_id.clone()) + .id(format!("input-{id}")) ]; let new_window_button = diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 3c62bfbc..0d72be86 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -9,7 +9,6 @@ publish = false iced.workspace = true iced.features = ["async-std", "debug"] -once_cell.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] } diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index a5f7b36a..25e3ead2 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -6,12 +6,9 @@ use iced::widget::{ use iced::window; use iced::{Center, Element, Fill, Font, Subscription, Task as Command}; -use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use uuid::Uuid; -static INPUT_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique); - pub fn main() -> iced::Result { #[cfg(not(target_arch = "wasm32"))] tracing_subscriber::fmt::init(); @@ -85,7 +82,7 @@ impl Todos { _ => {} } - text_input::focus(INPUT_ID.clone()) + text_input::focus("new-task") } Todos::Loaded(state) => { let mut saved = false; @@ -198,7 +195,7 @@ impl Todos { .align_x(Center); let input = text_input("What needs to be done?", input_value) - .id(INPUT_ID.clone()) + .id("new-task") .on_input(Message::InputChanged) .on_submit(Message::CreateTask) .padding(15) diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index af6a3945..00a6b556 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -751,7 +751,7 @@ where // TODO: Configurable speed/friction (?) -movement * 60.0 } - mouse::ScrollDelta::Pixels { x, y } => Vector::new(x, y), + mouse::ScrollDelta::Pixels { x, y } => -Vector::new(x, y), }; state.scroll( @@ -760,13 +760,17 @@ where content_bounds, ); - if notify_scroll( + let has_scrolled = notify_scroll( state, &self.on_scroll, bounds, content_bounds, shell, - ) { + ); + + let in_transaction = state.last_scrolled.is_some(); + + if has_scrolled || in_transaction { event::Status::Captured } else { event::Status::Ignored @@ -1194,11 +1198,6 @@ fn notify_viewport<Message>( return false; } - let Some(on_scroll) = on_scroll else { - state.last_notified = None; - return false; - }; - let viewport = Viewport { offset_x: state.offset_x, offset_y: state.offset_y, @@ -1229,9 +1228,12 @@ fn notify_viewport<Message>( } } - shell.publish(on_scroll(viewport)); state.last_notified = Some(viewport); + if let Some(on_scroll) = on_scroll { + shell.publish(on_scroll(viewport)); + } + true } diff --git a/widget/src/text_input.rs b/widget/src/text_input.rs index d5ede524..3032dd13 100644 --- a/widget/src/text_input.rs +++ b/widget/src/text_input.rs @@ -114,8 +114,8 @@ where } /// Sets the [`Id`] of the [`TextInput`]. - pub fn id(mut self, id: Id) -> Self { - self.id = Some(id); + pub fn id(mut self, id: impl Into<Id>) -> Self { + self.id = Some(id.into()); self } @@ -1226,38 +1226,53 @@ impl From<Id> for widget::Id { } } +impl From<&'static str> for Id { + fn from(id: &'static str) -> Self { + Self::new(id) + } +} + +impl From<String> for Id { + fn from(id: String) -> Self { + Self::new(id) + } +} + /// 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))) +pub fn focus<T>(id: impl Into<Id>) -> Task<T> { + task::effect(Action::widget(operation::focusable::focus(id.into().0))) } /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// end. -pub fn move_cursor_to_end<T>(id: Id) -> Task<T> { +pub fn move_cursor_to_end<T>(id: impl Into<Id>) -> Task<T> { task::effect(Action::widget(operation::text_input::move_cursor_to_end( - id.0, + id.into().0, ))) } /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// front. -pub fn move_cursor_to_front<T>(id: Id) -> Task<T> { +pub fn move_cursor_to_front<T>(id: impl Into<Id>) -> Task<T> { task::effect(Action::widget(operation::text_input::move_cursor_to_front( - id.0, + id.into().0, ))) } /// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the /// provided position. -pub fn move_cursor_to<T>(id: Id, position: usize) -> Task<T> { +pub fn move_cursor_to<T>(id: impl Into<Id>, position: usize) -> Task<T> { task::effect(Action::widget(operation::text_input::move_cursor_to( - id.0, position, + id.into().0, + position, ))) } /// 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))) +pub fn select_all<T>(id: impl Into<Id>) -> Task<T> { + task::effect(Action::widget(operation::text_input::select_all( + id.into().0, + ))) } /// The state of a [`TextInput`]. |