Skip to content
Snippets Groups Projects
s6_computation.rs 3.12 KiB
Newer Older
Finn Bear's avatar
Finn Bear committed
use crate::component::image::Image;
use crate::ctx_img;
use crate::egui::{Context, Frame, Ui};
use crate::fade_in::{fade_in, fade_in_manual};
Finn Bear's avatar
Finn Bear committed
use crate::slide::Slide;
Finn Bear's avatar
Finn Bear committed
use eframe::egui::style::Margin;
Finn Bear's avatar
Finn Bear committed
use eframe::egui::{Pos2, TextureHandle};
Finn Bear's avatar
Finn Bear committed

#[derive(Default)]
Finn Bear's avatar
Finn Bear committed
pub struct Computation {
    /// Will fade in one by one.
    examples: Vec<ComputationExample>,
}

/// One bullet point and texture combination.
struct ComputationExample {
    /// Bullet point text.
    label: &'static str,
    /// Texture handle to render on the right side.
    texture: TextureHandle,
    /// When we started fading it ([`None`] if we haven't started yet).
    fade_start: Option<f64>,
}

impl ComputationExample {
    pub fn new(label: &'static str, texture: TextureHandle) -> Self {
        Self {
            label,
            texture,
            fade_start: None,
        }
    }
}
Finn Bear's avatar
Finn Bear committed

impl Slide for Computation {
Finn Bear's avatar
Finn Bear committed
    fn transition(&mut self, ctx: &Context) -> bool {
        for example in &mut self.examples {
            if example.fade_start.is_none() {
                // If any image has not yet started fading in, fade it in and don't go to next slide.
                example.fade_start = Some(ctx.input().time);
                return false;
            }
        }
        true
    }

    fn show(&mut self, ui: &mut Ui) {
Finn Bear's avatar
Finn Bear committed
        if self.examples.is_empty() {
            // For now, these images are somewhat like placeholders.
            self.examples = vec![
                ComputationExample::new("Raytracing", ctx_img!(ui.ctx(), "raytracing0.png")),
                ComputationExample::new("Raymarching", ctx_img!(ui.ctx(), "raymarching1.png")),
                ComputationExample::new("Particle simulation", ctx_img!(ui.ctx(), "atom0.png")),
                ComputationExample::new("Fluid simulation", ctx_img!(ui.ctx(), "fluid0.png")),
            ]
        }

        const IMAGE_SCALE: f32 = 256.0;
        let window_width = ui.available_width();
        let window_height = ui.available_height();
        let window_width_per_image = window_width / self.examples.len() as f32;

Finn Bear's avatar
Finn Bear committed
        Frame::none().margin(Margin::same(20.0)).show(ui, |ui| {
            ui.heading("More Computation-based Art");
            ui.add_space(8.0);
Finn Bear's avatar
Finn Bear committed
            for (i, example) in self.examples.iter().enumerate() {
                if let Some(fade_start) = example.fade_start {
                    fade_in(ui, fade_start, |ui| {
                        ui.label(format!(" ⏵ {}", example.label));
                    });
                    fade_in_manual(ui, fade_start, |ui, alpha| {
                        let position = Pos2::new(
                            (window_width_per_image - IMAGE_SCALE) * 0.5
                                + window_width * (i as f32) / self.examples.len() as f32,
                            window_height - IMAGE_SCALE * 1.1,
                        );
                        Image::default()
                            .height(IMAGE_SCALE)
                            .position(position)
                            .alpha(alpha)
                            .show(ui, &example.texture);
                    });
                }
            }
Finn Bear's avatar
Finn Bear committed
        });
    }
}