diff options
author | 2024-05-02 15:21:22 +0200 | |
---|---|---|
committer | 2024-05-02 17:28:28 +0200 | |
commit | a57313b23ecb9843856ca0ea08635b6121fcb2cb (patch) | |
tree | 42a88a4e42031ae99ae87aeb92fea85ab590b01e /core | |
parent | 09a6bcfffc24f5abdc8709403bab7ae1e01563f1 (diff) | |
download | iced-a57313b23ecb9843856ca0ea08635b6121fcb2cb.tar.gz iced-a57313b23ecb9843856ca0ea08635b6121fcb2cb.tar.bz2 iced-a57313b23ecb9843856ca0ea08635b6121fcb2cb.zip |
Simplify image rotation API and its internals
Diffstat (limited to 'core')
-rw-r--r-- | core/src/angle.rs | 6 | ||||
-rw-r--r-- | core/src/content_fit.rs | 3 | ||||
-rw-r--r-- | core/src/image.rs | 5 | ||||
-rw-r--r-- | core/src/lib.rs | 2 | ||||
-rw-r--r-- | core/src/rectangle.rs | 16 | ||||
-rw-r--r-- | core/src/renderer/null.rs | 9 | ||||
-rw-r--r-- | core/src/rotation.rs | 71 | ||||
-rw-r--r-- | core/src/size.rs | 14 | ||||
-rw-r--r-- | core/src/svg.rs | 5 | ||||
-rw-r--r-- | core/src/vector.rs | 3 |
10 files changed, 101 insertions, 33 deletions
diff --git a/core/src/angle.rs b/core/src/angle.rs index dc3c0e93..69630717 100644 --- a/core/src/angle.rs +++ b/core/src/angle.rs @@ -65,6 +65,12 @@ impl From<u8> for Radians { } } +impl From<Radians> for f32 { + fn from(radians: Radians) -> Self { + radians.0 + } +} + impl From<Radians> for f64 { fn from(radians: Radians) -> Self { Self::from(radians.0) diff --git a/core/src/content_fit.rs b/core/src/content_fit.rs index 6bbedc7a..56d2ffa6 100644 --- a/core/src/content_fit.rs +++ b/core/src/content_fit.rs @@ -11,7 +11,7 @@ use crate::Size; /// in CSS, see [Mozilla's docs][1], or run the `tour` example /// /// [1]: https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq, Default)] pub enum ContentFit { /// Scale as big as it can be without needing to crop or hide parts. /// @@ -23,6 +23,7 @@ pub enum ContentFit { /// This is a great fit for when you need to display an image without losing /// any part of it, particularly when the image itself is the focus of the /// screen. + #[default] Contain, /// Scale the image to cover all of the bounding box, cropping if needed. diff --git a/core/src/image.rs b/core/src/image.rs index 5d1ab441..91a7fd36 100644 --- a/core/src/image.rs +++ b/core/src/image.rs @@ -1,7 +1,7 @@ //! Load and draw raster graphics. pub use bytes::Bytes; -use crate::{Rectangle, Size}; +use crate::{Radians, Rectangle, Size}; use rustc_hash::FxHasher; use std::hash::{Hash, Hasher}; @@ -173,7 +173,6 @@ pub trait Renderer: crate::Renderer { handle: Self::Handle, filter_method: FilterMethod, bounds: Rectangle, - rotation: f32, - scale: Size, + rotation: Radians, ); } diff --git a/core/src/lib.rs b/core/src/lib.rs index da3ddcac..32156441 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -65,7 +65,7 @@ pub use pixels::Pixels; pub use point::Point; pub use rectangle::Rectangle; pub use renderer::Renderer; -pub use rotation::RotationLayout; +pub use rotation::Rotation; pub use shadow::Shadow; pub use shell::Shell; pub use size::Size; diff --git a/core/src/rectangle.rs b/core/src/rectangle.rs index 2ab50137..fb66131a 100644 --- a/core/src/rectangle.rs +++ b/core/src/rectangle.rs @@ -227,3 +227,19 @@ where } } } + +impl<T> std::ops::Mul<Vector<T>> for Rectangle<T> +where + T: std::ops::Mul<Output = T> + Copy, +{ + type Output = Rectangle<T>; + + fn mul(self, scale: Vector<T>) -> Self { + Rectangle { + x: self.x * scale.x, + y: self.y * scale.y, + width: self.width * scale.x, + height: self.height * scale.y, + } + } +} diff --git a/core/src/renderer/null.rs b/core/src/renderer/null.rs index d2dcfe4d..91519b40 100644 --- a/core/src/renderer/null.rs +++ b/core/src/renderer/null.rs @@ -4,7 +4,8 @@ use crate::renderer::{self, Renderer}; use crate::svg; use crate::text::{self, Text}; use crate::{ - Background, Color, Font, Pixels, Point, Rectangle, Size, Transformation, + Background, Color, Font, Pixels, Point, Radians, Rectangle, Size, + Transformation, }; impl Renderer for () { @@ -171,8 +172,7 @@ impl image::Renderer for () { _handle: Self::Handle, _filter_method: image::FilterMethod, _bounds: Rectangle, - _rotation: f32, - _scale: Size, + _rotation: Radians, ) { } } @@ -187,8 +187,7 @@ impl svg::Renderer for () { _handle: svg::Handle, _color: Option<Color>, _bounds: Rectangle, - _rotation: f32, - _scale: Size, + _rotation: Radians, ) { } } diff --git a/core/src/rotation.rs b/core/src/rotation.rs index 821aa494..ebb85f3c 100644 --- a/core/src/rotation.rs +++ b/core/src/rotation.rs @@ -1,37 +1,68 @@ -//! Control the rotation of some content (like an image) with the `RotationLayout` within a -//! space. -use crate::Size; +//! Control the rotation of some content (like an image) within a space. +use crate::{Radians, Size}; /// The strategy used to rotate the content. /// /// This is used to control the behavior of the layout when the content is rotated /// by a certain angle. -#[derive(Debug, Hash, Clone, Copy, PartialEq, Eq)] -pub enum RotationLayout { - /// The layout is kept exactly as it was before the rotation. +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum Rotation { + /// The element will float while rotating. The layout will be kept exactly as it was + /// before the rotation. /// /// This is especially useful when used for animations, as it will avoid the /// layout being shifted or resized when smoothly i.e. an icon. - Keep, - /// The layout is adjusted to fit the rotated content. + /// + /// This is the default. + Floating(Radians), + /// The element will be solid while rotating. The layout will be adjusted to fit + /// the rotated content. /// /// This allows you to rotate an image and have the layout adjust to fit the new /// size of the image. - Change, + Solid(Radians), } -impl RotationLayout { - /// Applies the rotation to the layout while respecting the [`RotationLayout`] strategy. - /// The rotation is given in radians. - pub fn apply_to_size(&self, size: Size, rotation: f32) -> Size { +impl Rotation { + /// Returns the angle of the [`Rotation`] in [`Radians`]. + pub fn radians(self) -> Radians { + match self { + Rotation::Floating(radians) | Rotation::Solid(radians) => radians, + } + } + + /// Rotates the given [`Size`]. + pub fn apply(self, size: Size) -> Size { match self { - Self::Keep => size, - Self::Change => Size { - width: (size.width * rotation.cos()).abs() - + (size.height * rotation.sin()).abs(), - height: (size.width * rotation.sin()).abs() - + (size.height * rotation.cos()).abs(), - }, + Self::Floating(_) => size, + Self::Solid(rotation) => { + let radians = f32::from(rotation); + + Size { + width: (size.width * radians.cos()).abs() + + (size.height * radians.sin()).abs(), + height: (size.width * radians.sin()).abs() + + (size.height * radians.cos()).abs(), + } + } } } } + +impl Default for Rotation { + fn default() -> Self { + Self::Floating(Radians(0.0)) + } +} + +impl From<Radians> for Rotation { + fn from(radians: Radians) -> Self { + Self::Floating(radians) + } +} + +impl From<f32> for Rotation { + fn from(radians: f32) -> Self { + Self::Floating(Radians(radians)) + } +} diff --git a/core/src/size.rs b/core/src/size.rs index c2b5671a..66be2d85 100644 --- a/core/src/size.rs +++ b/core/src/size.rs @@ -113,3 +113,17 @@ where } } } + +impl<T> std::ops::Mul<Vector<T>> for Size<T> +where + T: std::ops::Mul<Output = T> + Copy, +{ + type Output = Size<T>; + + fn mul(self, scale: Vector<T>) -> Self::Output { + Size { + width: self.width * scale.x, + height: self.height * scale.y, + } + } +} diff --git a/core/src/svg.rs b/core/src/svg.rs index 74dd7f4a..01f102e3 100644 --- a/core/src/svg.rs +++ b/core/src/svg.rs @@ -1,5 +1,5 @@ //! Load and draw vector graphics. -use crate::{Color, Rectangle, Size}; +use crate::{Color, Radians, Rectangle, Size}; use rustc_hash::FxHasher; use std::borrow::Cow; @@ -100,7 +100,6 @@ pub trait Renderer: crate::Renderer { handle: Handle, color: Option<Color>, bounds: Rectangle, - rotation: f32, - scale: Size, + rotation: Radians, ); } diff --git a/core/src/vector.rs b/core/src/vector.rs index 1380c3b3..049e648f 100644 --- a/core/src/vector.rs +++ b/core/src/vector.rs @@ -18,6 +18,9 @@ impl<T> Vector<T> { impl Vector { /// The zero [`Vector`]. pub const ZERO: Self = Self::new(0.0, 0.0); + + /// The unit [`Vector`]. + pub const UNIT: Self = Self::new(0.0, 0.0); } impl<T> std::ops::Add for Vector<T> |