diff options
| author | 2024-05-08 19:16:06 +0900 | |
|---|---|---|
| committer | 2024-05-08 19:16:06 +0900 | |
| commit | 477887b3870aa5fbdab96c3a06f3b930462d7842 (patch) | |
| tree | 2b3272bb178f8757169511966589fe6a106733f4 /examples/ferris/src | |
| parent | 0ebe0629cef37aee5c48b9409fc36618a3a3e60d (diff) | |
| parent | e07b42ac96b8d098a883c93afe828a439f479c7b (diff) | |
| download | iced-477887b3870aa5fbdab96c3a06f3b930462d7842.tar.gz iced-477887b3870aa5fbdab96c3a06f3b930462d7842.tar.bz2 iced-477887b3870aa5fbdab96c3a06f3b930462d7842.zip | |
Merge branch 'master' of https://github.com/iced-rs/iced into iced-rs-master
Diffstat (limited to 'examples/ferris/src')
| -rw-r--r-- | examples/ferris/src/main.rs | 211 | 
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() +} | 
