diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/src/animation.rs | 12 | ||||
-rw-r--r-- | core/src/element.rs | 5 | ||||
-rw-r--r-- | core/src/length.rs | 6 | ||||
-rw-r--r-- | core/src/lib.rs | 57 | ||||
-rw-r--r-- | core/src/pixels.rs | 6 | ||||
-rw-r--r-- | core/src/widget/operation/focusable.rs | 27 |
6 files changed, 105 insertions, 8 deletions
diff --git a/core/src/animation.rs b/core/src/animation.rs index 258fd084..14cbb5c3 100644 --- a/core/src/animation.rs +++ b/core/src/animation.rs @@ -13,6 +13,7 @@ where T: Clone + Copy + PartialEq + Float, { raw: lilt::Animated<T, Instant>, + duration: Duration, // TODO: Expose duration getter in `lilt` } impl<T> Animation<T> @@ -23,6 +24,7 @@ where pub fn new(state: T) -> Self { Self { raw: lilt::Animated::new(state), + duration: Duration::from_millis(100), } } @@ -58,6 +60,7 @@ where /// Sets the duration of the [`Animation`] to the given value. pub fn duration(mut self, duration: Duration) -> Self { self.raw = self.raw.duration(duration.as_secs_f32() * 1_000.0); + self.duration = duration; self } @@ -133,4 +136,13 @@ impl Animation<bool> { { self.raw.animate_bool(start, end, at) } + + /// Returns the remaining [`Duration`] of the [`Animation`]. + pub fn remaining(&self, at: Instant) -> Duration { + Duration::from_secs_f32(self.interpolate( + self.duration.as_secs_f32(), + 0.0, + at, + )) + } } diff --git a/core/src/element.rs b/core/src/element.rs index ede9e16c..b7d51aeb 100644 --- a/core/src/element.rs +++ b/core/src/element.rs @@ -93,6 +93,7 @@ impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer> { /// /// ```no_run /// # mod iced { + /// # pub use iced_core::Function; /// # pub type Element<'a, Message> = iced_core::Element<'a, Message, iced_core::Theme, ()>; /// # /// # pub mod widget { @@ -119,7 +120,7 @@ impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer> { /// use counter::Counter; /// /// use iced::widget::row; - /// use iced::Element; + /// use iced::{Element, Function}; /// /// struct ManyCounters { /// counters: Vec<Counter>, @@ -142,7 +143,7 @@ impl<'a, Message, Theme, Renderer> Element<'a, Message, Theme, Renderer> { /// // Here we turn our `Element<counter::Message>` into /// // an `Element<Message>` by combining the `index` and the /// // message of the `element`. - /// counter.map(move |message| Message::Counter(index, message)) + /// counter.map(Message::Counter.with(index)) /// }), /// ) /// .into() diff --git a/core/src/length.rs b/core/src/length.rs index 5f24169f..363833c4 100644 --- a/core/src/length.rs +++ b/core/src/length.rs @@ -77,8 +77,8 @@ impl From<f32> for Length { } } -impl From<u16> for Length { - fn from(units: u16) -> Self { - Length::Fixed(f32::from(units)) +impl From<u32> for Length { + fn from(units: u32) -> Self { + Length::Fixed(units as f32) } } diff --git a/core/src/lib.rs b/core/src/lib.rs index d5c221ac..03cc0632 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -93,3 +93,60 @@ pub use smol_str::SmolStr; pub fn never<T>(never: std::convert::Infallible) -> T { match never {} } + +/// A trait extension for binary functions (`Fn(A, B) -> O`). +/// +/// It enables you to use a bunch of nifty functional programming paradigms +/// that work well with iced. +pub trait Function<A, B, O> { + /// Applies the given first argument to a binary function and returns + /// a new function that takes the other argument. + /// + /// This lets you partially "apply" a function—equivalent to currying, + /// but it only works with binary functions. If you want to apply an + /// arbitrary number of arguments, create a little struct for them. + /// + /// # When is this useful? + /// Sometimes you will want to identify the source or target + /// of some message in your user interface. This can be achieved through + /// normal means by defining a closure and moving the identifier + /// inside: + /// + /// ```rust + /// # let element: Option<()> = Some(()); + /// # enum Message { ButtonPressed(u32, ()) } + /// let id = 123; + /// + /// # let _ = { + /// element.map(move |result| Message::ButtonPressed(id, result)) + /// # }; + /// ``` + /// + /// That's quite a mouthful. [`with`](Self::with) lets you write: + /// + /// ```rust + /// # use iced_core::Function; + /// # let element: Option<()> = Some(()); + /// # enum Message { ButtonPressed(u32, ()) } + /// let id = 123; + /// + /// # let _ = { + /// element.map(Message::ButtonPressed.with(id)) + /// # }; + /// ``` + /// + /// Effectively creating the same closure that partially applies + /// the `id` to the message—but much more concise! + fn with(self, prefix: A) -> impl Fn(B) -> O; +} + +impl<F, A, B, O> Function<A, B, O> for F +where + F: Fn(A, B) -> O, + Self: Sized, + A: Copy, +{ + fn with(self, prefix: A) -> impl Fn(B) -> O { + move |result| self(prefix, result) + } +} diff --git a/core/src/pixels.rs b/core/src/pixels.rs index 7d6267cf..c87e2b31 100644 --- a/core/src/pixels.rs +++ b/core/src/pixels.rs @@ -20,9 +20,9 @@ impl From<f32> for Pixels { } } -impl From<u16> for Pixels { - fn from(amount: u16) -> Self { - Self(f32::from(amount)) +impl From<u32> for Pixels { + fn from(amount: u32) -> Self { + Self(amount as f32) } } diff --git a/core/src/widget/operation/focusable.rs b/core/src/widget/operation/focusable.rs index 8f66e575..a1327bc1 100644 --- a/core/src/widget/operation/focusable.rs +++ b/core/src/widget/operation/focusable.rs @@ -61,6 +61,33 @@ pub fn focus<T>(target: Id) -> impl Operation<T> { Focus { target } } +/// Produces an [`Operation`] that unfocuses the focused widget. +pub fn unfocus<T>() -> impl Operation<T> { + struct Unfocus; + + impl<T> Operation<T> for Unfocus { + fn focusable( + &mut self, + _id: Option<&Id>, + _bounds: Rectangle, + state: &mut dyn Focusable, + ) { + state.unfocus(); + } + + fn container( + &mut self, + _id: Option<&Id>, + _bounds: Rectangle, + operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>), + ) { + operate_on_children(self); + } + } + + Unfocus +} + /// Produces an [`Operation`] that generates a [`Count`] and chains it with the /// provided function to build a new [`Operation`]. pub fn count() -> impl Operation<Count> { |