summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-05-02 15:21:22 +0200
committerLibravatar Héctor Ramón Jiménez <hector@hecrj.dev>2024-05-02 17:28:28 +0200
commita57313b23ecb9843856ca0ea08635b6121fcb2cb (patch)
tree42a88a4e42031ae99ae87aeb92fea85ab590b01e /core
parent09a6bcfffc24f5abdc8709403bab7ae1e01563f1 (diff)
downloadiced-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.rs6
-rw-r--r--core/src/content_fit.rs3
-rw-r--r--core/src/image.rs5
-rw-r--r--core/src/lib.rs2
-rw-r--r--core/src/rectangle.rs16
-rw-r--r--core/src/renderer/null.rs9
-rw-r--r--core/src/rotation.rs71
-rw-r--r--core/src/size.rs14
-rw-r--r--core/src/svg.rs5
-rw-r--r--core/src/vector.rs3
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>