diff options
-rw-r--r-- | .github/workflows/test.yml | 2 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/application.rs | 20 | ||||
-rw-r--r-- | src/daemon.rs | 17 | ||||
-rw-r--r-- | src/program.rs | 74 | ||||
-rw-r--r-- | widget/src/markdown.rs | 2 | ||||
-rw-r--r-- | widget/src/mouse_area.rs | 2 | ||||
-rw-r--r-- | widget/src/scrollable.rs | 18 |
8 files changed, 124 insertions, 13 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 47c61f5e..ea941509 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest, macOS-latest] - rust: [stable, beta] + rust: [stable, beta, "1.80"] steps: - uses: hecrj/setup-rust-action@v2 with: @@ -9,6 +9,7 @@ repository.workspace = true homepage.workspace = true categories.workspace = true keywords.workspace = true +rust-version.workspace = true [lints] workspace = true @@ -124,6 +125,7 @@ repository = "https://github.com/iced-rs/iced" homepage = "https://iced.rs" categories = ["gui"] keywords = ["gui", "ui", "graphics", "interface", "widgets"] +rust-version = "1.80" [workspace.dependencies] iced = { version = "0.13.0", path = "." } diff --git a/src/application.rs b/src/application.rs index d0f77304..2ba764be 100644 --- a/src/application.rs +++ b/src/application.rs @@ -32,7 +32,9 @@ //! ``` use crate::program::{self, Program}; use crate::window; -use crate::{Element, Font, Result, Settings, Size, Subscription, Task}; +use crate::{ + Element, Executor, Font, Result, Settings, Size, Subscription, Task, +}; use std::borrow::Cow; @@ -376,6 +378,22 @@ impl<P: Program> Application<P> { window: self.window, } } + + /// Sets the executor of the [`Application`]. + pub fn executor<E>( + self, + ) -> Application< + impl Program<State = P::State, Message = P::Message, Theme = P::Theme>, + > + where + E: Executor, + { + Application { + raw: program::with_executor::<P, E>(self.raw), + settings: self.settings, + window: self.window, + } + } } /// The title logic of some [`Application`]. diff --git a/src/daemon.rs b/src/daemon.rs index 6a6ad133..81254bf9 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -2,7 +2,7 @@ use crate::application; use crate::program::{self, Program}; use crate::window; -use crate::{Element, Font, Result, Settings, Subscription, Task}; +use crate::{Element, Executor, Font, Result, Settings, Subscription, Task}; use std::borrow::Cow; @@ -223,6 +223,21 @@ impl<P: Program> Daemon<P> { settings: self.settings, } } + + /// Sets the executor of the [`Daemon`]. + pub fn executor<E>( + self, + ) -> Daemon< + impl Program<State = P::State, Message = P::Message, Theme = P::Theme>, + > + where + E: Executor, + { + Daemon { + raw: program::with_executor::<P, E>(self.raw), + settings: self.settings, + } + } } /// The title logic of some [`Daemon`]. diff --git a/src/program.rs b/src/program.rs index 2b697fbe..94cb9a7d 100644 --- a/src/program.rs +++ b/src/program.rs @@ -550,6 +550,80 @@ pub fn with_scale_factor<P: Program>( } } +pub fn with_executor<P: Program, E: Executor>( + program: P, +) -> impl Program<State = P::State, Message = P::Message, Theme = P::Theme> { + use std::marker::PhantomData; + + struct WithExecutor<P, E> { + program: P, + executor: PhantomData<E>, + } + + impl<P: Program, E> Program for WithExecutor<P, E> + where + E: Executor, + { + type State = P::State; + type Message = P::Message; + type Theme = P::Theme; + type Renderer = P::Renderer; + type Executor = E; + + fn title(&self, state: &Self::State, window: window::Id) -> String { + self.program.title(state, window) + } + + fn update( + &self, + state: &mut Self::State, + message: Self::Message, + ) -> Task<Self::Message> { + self.program.update(state, message) + } + + fn view<'a>( + &self, + state: &'a Self::State, + window: window::Id, + ) -> Element<'a, Self::Message, Self::Theme, Self::Renderer> { + self.program.view(state, window) + } + + fn subscription( + &self, + state: &Self::State, + ) -> Subscription<Self::Message> { + self.program.subscription(state) + } + + fn theme( + &self, + state: &Self::State, + window: window::Id, + ) -> Self::Theme { + self.program.theme(state, window) + } + + fn style( + &self, + state: &Self::State, + theme: &Self::Theme, + ) -> Appearance { + self.program.style(state, theme) + } + + fn scale_factor(&self, state: &Self::State, window: window::Id) -> f64 { + self.program.scale_factor(state, window) + } + } + + WithExecutor { + program, + executor: PhantomData::<E>, + } +} + /// The renderer of some [`Program`]. pub trait Renderer: text::Renderer + compositor::Default {} diff --git a/widget/src/markdown.rs b/widget/src/markdown.rs index 6e592998..81bea0c5 100644 --- a/widget/src/markdown.rs +++ b/widget/src/markdown.rs @@ -325,7 +325,7 @@ pub fn parse(markdown: &str) -> impl Iterator<Item = Item> + '_ { ) if !metadata && !table => { #[cfg(feature = "highlighter")] { - use iced_highlighter::{self, Highlighter}; + use iced_highlighter::Highlighter; use text::Highlighter as _; highlighter = diff --git a/widget/src/mouse_area.rs b/widget/src/mouse_area.rs index d255ac99..7330874a 100644 --- a/widget/src/mouse_area.rs +++ b/widget/src/mouse_area.rs @@ -316,7 +316,7 @@ fn update<Message: Clone, Theme, Renderer>( let cursor_position = cursor.position(); let bounds = layout.bounds(); - if state.cursor_position != cursor_position && state.bounds != bounds { + if state.cursor_position != cursor_position || state.bounds != bounds { let was_hovered = state.is_hovered; state.is_hovered = cursor.is_over(layout.bounds()); diff --git a/widget/src/scrollable.rs b/widget/src/scrollable.rs index 01638a48..6d7f251e 100644 --- a/widget/src/scrollable.rs +++ b/widget/src/scrollable.rs @@ -800,13 +800,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 @@ -1234,11 +1238,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, @@ -1269,9 +1268,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 } |