summaryrefslogtreecommitdiffstats
path: root/examples/ferris/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ferris/src/main.rs')
-rw-r--r--examples/ferris/src/main.rs211
1 files changed, 211 insertions, 0 deletions
diff --git a/examples/ferris/src/main.rs b/examples/ferris/src/main.rs
new file mode 100644
index 00000000..0400c376
--- /dev/null
+++ b/examples/ferris/src/main.rs
@@ -0,0 +1,211 @@
+use iced::time::Instant;
+use iced::widget::{
+ center, checkbox, column, container, image, pick_list, row, slider, text,
+};
+use iced::window;
+use iced::{
+ Alignment, Color, ContentFit, Degrees, Element, Length, Radians, Rotation,
+ Subscription, Theme,
+};
+
+pub fn main() -> iced::Result {
+ iced::program("Ferris - Iced", Image::update, Image::view)
+ .subscription(Image::subscription)
+ .theme(|_| Theme::TokyoNight)
+ .run()
+}
+
+struct Image {
+ width: f32,
+ opacity: f32,
+ rotation: Rotation,
+ content_fit: ContentFit,
+ spin: bool,
+ last_tick: Instant,
+}
+
+#[derive(Debug, Clone, Copy)]
+enum Message {
+ WidthChanged(f32),
+ OpacityChanged(f32),
+ RotationStrategyChanged(RotationStrategy),
+ RotationChanged(Degrees),
+ ContentFitChanged(ContentFit),
+ SpinToggled(bool),
+ RedrawRequested(Instant),
+}
+
+impl Image {
+ fn update(&mut self, message: Message) {
+ match message {
+ Message::WidthChanged(width) => {
+ self.width = width;
+ }
+ Message::OpacityChanged(opacity) => {
+ self.opacity = opacity;
+ }
+ 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;
+ }
+ Message::SpinToggled(spin) => {
+ self.spin = spin;
+ self.last_tick = Instant::now();
+ }
+ Message::RedrawRequested(now) => {
+ const ROTATION_SPEED: Degrees = Degrees(360.0);
+
+ let delta = (now - self.last_tick).as_millis() as f32 / 1_000.0;
+
+ *self.rotation.radians_mut() = (self.rotation.radians()
+ + ROTATION_SPEED * delta)
+ % (2.0 * Radians::PI);
+
+ self.last_tick = now;
+ }
+ }
+ }
+
+ fn subscription(&self) -> Subscription<Message> {
+ if self.spin {
+ window::frames().map(Message::RedrawRequested)
+ } else {
+ Subscription::none()
+ }
+ }
+
+ fn view(&self) -> Element<Message> {
+ let i_am_ferris = 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)
+ .opacity(self.opacity)
+ )
+ .explain(Color::WHITE),
+ "I am Ferris!"
+ ]
+ .spacing(20)
+ .align_items(Alignment::Center);
+
+ let fit = row![
+ pick_list(
+ [
+ ContentFit::Contain,
+ ContentFit::Cover,
+ ContentFit::Fill,
+ ContentFit::None,
+ ContentFit::ScaleDown
+ ],
+ Some(self.content_fit),
+ Message::ContentFitChanged
+ )
+ .width(Length::Fill),
+ pick_list(
+ [RotationStrategy::Floating, RotationStrategy::Solid],
+ Some(match self.rotation {
+ Rotation::Floating(_) => RotationStrategy::Floating,
+ Rotation::Solid(_) => RotationStrategy::Solid,
+ }),
+ Message::RotationStrategyChanged,
+ )
+ .width(Length::Fill),
+ ]
+ .spacing(10)
+ .align_items(Alignment::End);
+
+ let properties = row![
+ with_value(
+ slider(100.0..=500.0, self.width, Message::WidthChanged),
+ format!("Width: {}px", self.width)
+ ),
+ with_value(
+ slider(0.0..=1.0, self.opacity, Message::OpacityChanged)
+ .step(0.01),
+ format!("Opacity: {:.2}", self.opacity)
+ ),
+ with_value(
+ row![
+ slider(
+ Degrees::RANGE,
+ self.rotation.degrees(),
+ Message::RotationChanged
+ ),
+ checkbox("Spin!", self.spin)
+ .text_size(12)
+ .on_toggle(Message::SpinToggled)
+ .size(12)
+ ]
+ .spacing(10)
+ .align_items(Alignment::Center),
+ format!("Rotation: {:.0}°", f32::from(self.rotation.degrees()))
+ )
+ ]
+ .spacing(10)
+ .align_items(Alignment::End);
+
+ container(column![fit, center(i_am_ferris), properties].spacing(10))
+ .padding(10)
+ .into()
+ }
+}
+
+impl Default for Image {
+ fn default() -> Self {
+ Self {
+ width: 300.0,
+ opacity: 1.0,
+ rotation: Rotation::default(),
+ content_fit: ContentFit::default(),
+ spin: false,
+ last_tick: Instant::now(),
+ }
+ }
+}
+
+#[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",
+ })
+ }
+}
+
+fn with_value<'a>(
+ control: impl Into<Element<'a, Message>>,
+ value: String,
+) -> Element<'a, Message> {
+ column![control.into(), text(value).size(12).line_height(1.0)]
+ .spacing(2)
+ .align_items(Alignment::Center)
+ .into()
+}