-
Finn Bear authoredf389df21
main.rs 4.44 KiB
#![feature(derive_default_enum)]
#![feature(mixed_integer_ops)]
pub mod component;
pub mod governor;
pub mod image;
pub mod slide;
use crate::slide::s1_title::Title;
use crate::slide::s2_introduction::Introduction;
use crate::slide::s3_complexity::Complexity;
use crate::slide::s4_automata::Automata;
use crate::slide::s5_fractals::Fractals;
use crate::slide::s6_computation::Computation;
use crate::slide::s7_mosaic::Mosaic;
use crate::slide::s8_conclusion::Conclusion;
use crate::slide::Slide;
use eframe::egui::style::Margin;
use eframe::egui::{Key, Style, TextStyle, Visuals};
use eframe::epi::{Frame, Storage};
use eframe::{egui, epi};
fn main() {
let app = Cartoon::default();
let size = egui::Vec2::new(1280f32, 720f32);
let native_options = eframe::NativeOptions {
always_on_top: false,
maximized: false,
decorated: true,
drag_and_drop_support: false,
icon_data: None,
initial_window_pos: None,
initial_window_size: None,
min_window_size: Some(size),
max_window_size: Some(size),
resizable: false,
transparent: false,
};
eframe::run_native(Box::new(app), native_options);
}
pub struct Cartoon {
slides: Vec<Box<dyn Slide>>,
slide_index: usize,
}
impl Default for Cartoon {
fn default() -> Self {
Self {
slides: create_slides(),
slide_index: 0,
}
}
}
fn create_slides() -> Vec<Box<dyn Slide>> {
vec![
Box::new(Title::default()) as Box<dyn Slide>,
Box::new(Introduction::default()),
Box::new(Complexity::default()),
Box::new(Automata::default()),
Box::new(Fractals::default()),
Box::new(Computation::default()),
Box::new(Mosaic::default()),
Box::new(Conclusion::default()),
]
}
impl epi::App for Cartoon {
fn name(&self) -> &str {
"Generative Art Cartoon"
}
fn setup(&mut self, ctx: &egui::Context, _frame: &Frame, _storage: Option<&dyn Storage>) {
let mut style = Style::default();
style.animation_time = 0.5;
style.visuals = Visuals::light();
style.spacing.window_margin = Margin::same(24.0);
{
let header_style = style.text_styles.get_mut(&TextStyle::Heading).unwrap();
header_style.size = 48.0;
}
{
let body_style = style.text_styles.get_mut(&TextStyle::Body).unwrap();
body_style.size = 30.0;
}
{
let small_style = style.text_styles.get_mut(&TextStyle::Small).unwrap();
small_style.size = 22.0;
}
/*
{
let monospaced_style = style.text_styles.get_mut(&TextStyle::Monospace).unwrap();
monospaced_style.size = 22.0;
}
*/
ctx.set_style(style);
}
/// Put your widgets into a `SidePanel`, `TopPanel`, `CentralPanel`, `Window` or `Area`.
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
// For inspiration and more examples, go to https://emilk.github.io/egui
/*
egui::TopBottomPanel::top("top_panel").show(ctx, |ui| {
egui::menu::bar(ui, |ui| {
ui.menu_button("File", |ui| {
if ui.button("Quit").clicked() {
frame.quit();
}
});
});
});
*/
let force_advance =
ctx.input().key_pressed(Key::ArrowRight) || ctx.input().key_pressed(Key::D);
let advance = force_advance || ctx.input().key_pressed(Key::Space);
let retreat = ctx.input().key_pressed(Key::ArrowLeft) || ctx.input().key_pressed(Key::A);
if advance || retreat {
self.slide_index = if advance {
if force_advance || self.slides[self.slide_index].transition(ctx) {
let new = (self.slide_index + 1) % self.slides.len();
if new == 0 {
self.slides = create_slides();
}
ctx.request_repaint();
new
} else {
self.slide_index
}
} else {
ctx.request_repaint();
self.slide_index
.checked_sub(1)
.unwrap_or(self.slides.len() - 1)
};
}
egui::CentralPanel::default().show(ctx, |ui| {
self.slides[self.slide_index].show(ui, ctx);
});
}
}