summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/src/angle.rs43
-rw-r--r--core/src/content_fit.rs14
-rw-r--r--core/src/rotation.rs7
-rw-r--r--examples/ferris/Cargo.toml10
-rw-r--r--examples/ferris/src/main.rs161
5 files changed, 234 insertions, 1 deletions
diff --git a/core/src/angle.rs b/core/src/angle.rs
index 69630717..8322273c 100644
--- a/core/src/angle.rs
+++ b/core/src/angle.rs
@@ -7,6 +7,11 @@ use std::ops::{Add, AddAssign, Div, Mul, RangeInclusive, Sub, SubAssign};
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct Degrees(pub f32);
+impl Degrees {
+ /// The range of degrees of a circle.
+ pub const RANGE: RangeInclusive<Self> = Self(0.0)..=Self(360.0);
+}
+
impl PartialEq<f32> for Degrees {
fn eq(&self, other: &f32) -> bool {
self.0.eq(other)
@@ -19,6 +24,44 @@ impl PartialOrd<f32> for Degrees {
}
}
+impl From<f32> for Degrees {
+ fn from(degrees: f32) -> Self {
+ Self(degrees)
+ }
+}
+
+impl From<u8> for Degrees {
+ fn from(degrees: u8) -> Self {
+ Self(f32::from(degrees))
+ }
+}
+
+impl From<Degrees> for f32 {
+ fn from(degrees: Degrees) -> Self {
+ degrees.0
+ }
+}
+
+impl From<Degrees> for f64 {
+ fn from(degrees: Degrees) -> Self {
+ Self::from(degrees.0)
+ }
+}
+
+impl num_traits::FromPrimitive for Degrees {
+ fn from_i64(n: i64) -> Option<Self> {
+ Some(Self(n as f32))
+ }
+
+ fn from_u64(n: u64) -> Option<Self> {
+ Some(Self(n as f32))
+ }
+
+ fn from_f64(n: f64) -> Option<Self> {
+ Some(Self(n as f32))
+ }
+}
+
/// Radians
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
pub struct Radians(pub f32);
diff --git a/core/src/content_fit.rs b/core/src/content_fit.rs
index 56d2ffa6..19642716 100644
--- a/core/src/content_fit.rs
+++ b/core/src/content_fit.rs
@@ -1,6 +1,8 @@
//! Control the fit of some content (like an image) within a space.
use crate::Size;
+use std::fmt;
+
/// The strategy used to fit the contents of a widget to its bounding box.
///
/// Each variant of this enum is a strategy that can be applied for resolving
@@ -118,3 +120,15 @@ impl ContentFit {
}
}
}
+
+impl fmt::Display for ContentFit {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ f.write_str(match self {
+ ContentFit::Contain => "Contain",
+ ContentFit::Cover => "Cover",
+ ContentFit::Fill => "Fill",
+ ContentFit::None => "None",
+ ContentFit::ScaleDown => "Scale Down",
+ })
+ }
+}
diff --git a/core/src/rotation.rs b/core/src/rotation.rs
index ebb85f3c..f36ef089 100644
--- a/core/src/rotation.rs
+++ b/core/src/rotation.rs
@@ -1,5 +1,5 @@
//! Control the rotation of some content (like an image) within a space.
-use crate::{Radians, Size};
+use crate::{Degrees, Radians, Size};
/// The strategy used to rotate the content.
///
@@ -31,6 +31,11 @@ impl Rotation {
}
}
+ /// Returns the angle of the [`Rotation`] in [`Degrees`].
+ pub fn degrees(self) -> Degrees {
+ Degrees(self.radians().0.to_degrees())
+ }
+
/// Rotates the given [`Size`].
pub fn apply(self, size: Size) -> Size {
match self {
diff --git a/examples/ferris/Cargo.toml b/examples/ferris/Cargo.toml
new file mode 100644
index 00000000..c9fb8c13
--- /dev/null
+++ b/examples/ferris/Cargo.toml
@@ -0,0 +1,10 @@
+[package]
+name = "ferris"
+version = "0.1.0"
+authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"]
+edition = "2021"
+publish = false
+
+[dependencies]
+iced.workspace = true
+iced.features = ["image"]
diff --git a/examples/ferris/src/main.rs b/examples/ferris/src/main.rs
new file mode 100644
index 00000000..d846f560
--- /dev/null
+++ b/examples/ferris/src/main.rs
@@ -0,0 +1,161 @@
+use iced::widget::{column, container, image, pick_list, row, slider, text};
+use iced::{
+ Alignment, Color, ContentFit, Degrees, Element, Length, Rotation, Theme,
+};
+
+pub fn main() -> iced::Result {
+ iced::program("Ferris - Iced", Image::update, Image::view)
+ .theme(|_| Theme::TokyoNight)
+ .run()
+}
+
+struct Image {
+ width: f32,
+ rotation: Rotation,
+ content_fit: ContentFit,
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Message {
+ WidthChanged(f32),
+ RotationStrategyChanged(RotationStrategy),
+ RotationChanged(Degrees),
+ ContentFitChanged(ContentFit),
+}
+
+impl Image {
+ fn update(&mut self, message: Message) {
+ match message {
+ Message::WidthChanged(width) => {
+ self.width = width;
+ }
+ Message::RotationStrategyChanged(strategy) => {
+ self.rotation = match strategy {
+ RotationStrategy::Floating => {
+ Rotation::Floating(self.rotation.radians())
+ }
+ RotationStrategy::Solid => {
+ Rotation::Solid(self.rotation.radians())
+ }
+ };
+ }
+ Message::RotationChanged(rotation) => {
+ self.rotation = match self.rotation {
+ Rotation::Floating(_) => {
+ Rotation::Floating(rotation.into())
+ }
+ Rotation::Solid(_) => Rotation::Solid(rotation.into()),
+ };
+ }
+ Message::ContentFitChanged(content_fit) => {
+ self.content_fit = content_fit;
+ }
+ }
+ }
+
+ fn view(&self) -> Element<Message> {
+ let i_am_ferris = container(
+ column![
+ "Hello!",
+ Element::from(
+ image(format!(
+ "{}/../tour/images/ferris.png",
+ env!("CARGO_MANIFEST_DIR")
+ ))
+ .width(self.width)
+ .content_fit(self.content_fit)
+ .rotation(self.rotation)
+ )
+ .explain(Color::WHITE),
+ "I am Ferris!"
+ ]
+ .spacing(20)
+ .align_items(Alignment::Center),
+ )
+ .width(Length::Fill)
+ .height(Length::Fill)
+ .center_x()
+ .center_y();
+
+ let sizing = row![
+ pick_list(
+ [
+ ContentFit::Contain,
+ ContentFit::Cover,
+ ContentFit::Fill,
+ ContentFit::None,
+ ContentFit::ScaleDown
+ ],
+ Some(self.content_fit),
+ Message::ContentFitChanged
+ )
+ .width(Length::Fill),
+ column![
+ slider(100.0..=500.0, self.width, Message::WidthChanged),
+ text(format!("Width: {}px", self.width))
+ .size(14)
+ .line_height(1.0)
+ ]
+ .spacing(5)
+ .align_items(Alignment::Center)
+ ]
+ .spacing(10);
+
+ let rotation = row![
+ pick_list(
+ [RotationStrategy::Floating, RotationStrategy::Solid],
+ Some(match self.rotation {
+ Rotation::Floating(_) => RotationStrategy::Floating,
+ Rotation::Solid(_) => RotationStrategy::Solid,
+ }),
+ Message::RotationStrategyChanged,
+ )
+ .width(Length::Fill),
+ column![
+ slider(
+ Degrees::RANGE,
+ self.rotation.degrees(),
+ Message::RotationChanged
+ ),
+ text(format!(
+ "Rotation: {:.0}°",
+ f32::from(self.rotation.degrees())
+ ))
+ .size(14)
+ .line_height(1.0)
+ ]
+ .spacing(5)
+ .align_items(Alignment::Center)
+ ]
+ .spacing(10);
+
+ container(column![i_am_ferris, sizing, rotation].spacing(10))
+ .padding(10)
+ .into()
+ }
+}
+
+impl Default for Image {
+ fn default() -> Self {
+ Self {
+ width: 300.0,
+ rotation: Rotation::default(),
+ content_fit: ContentFit::default(),
+ }
+ }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+enum RotationStrategy {
+ Floating,
+ Solid,
+}
+
+impl std::fmt::Display for RotationStrategy {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ Self::Floating => "Floating",
+ Self::Solid => "Solid",
+ })
+ }
+}