-
Finn Bear authored1e61685f
example_list.rs 2.90 KiB
use crate::component::image::Image;
use crate::egui::{Context, Frame, Ui};
use crate::fade_in::{fade_in, fade_in_manual};
use eframe::egui::style::Margin;
use eframe::egui::{Pos2, TextureHandle};
#[derive(Default)]
pub struct ExampleList {
/// Heading text.
title: &'static str,
/// Examples to show.
examples: Vec<Example>,
}
/// One bullet point and texture combination.
pub struct Example {
/// 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 Example {
pub fn new(label: &'static str, texture: TextureHandle) -> Self {
Self {
label,
texture,
fade_start: None,
}
}
}
impl ExampleList {
pub fn new(title: &'static str) -> Self {
Self {
title,
examples: Vec::new(),
}
}
pub 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
}
/// Will call setter function once to populate examples.
pub fn show(&mut self, ui: &mut Ui, setter: impl FnOnce() -> Vec<Example>) {
if self.examples.is_empty() {
self.examples = setter();
}
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;
let aspect_ratio_gap = (window_width_per_image - IMAGE_SCALE) * 0.5;
Frame::none().margin(Margin::same(20.0)).show(ui, |ui| {
ui.heading(self.title);
ui.add_space(8.0);
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(
aspect_ratio_gap
+ window_width * (i as f32) / self.examples.len() as f32,
window_height - IMAGE_SCALE - aspect_ratio_gap,
);
Image::default()
.height(IMAGE_SCALE)
.position(position)
.alpha(alpha)
.show(ui, &example.texture);
});
}
}
});
}
}