From c73497846b4dfcf64309fc69bf52bd512ac1eda5 Mon Sep 17 00:00:00 2001
From: Finn Bear <finnbearlabs@gmail.com>
Date: Wed, 27 Apr 2022 20:37:50 -0700
Subject: [PATCH] Document the slides.

---
 src/slide/s1_title.rs        | 25 ++++++++++++-------------
 src/slide/s2_introduction.rs |  2 ++
 src/slide/s3_complexity.rs   | 15 +++++++++++++++
 src/slide/s4_automata.rs     | 10 ++++++++++
 src/slide/s5_fractals.rs     | 28 +++++++++++++++++++++++++++-
 src/slide/s7_mosaic.rs       |  1 +
 6 files changed, 67 insertions(+), 14 deletions(-)

diff --git a/src/slide/s1_title.rs b/src/slide/s1_title.rs
index 947ecd2..8a983ba 100644
--- a/src/slide/s1_title.rs
+++ b/src/slide/s1_title.rs
@@ -3,6 +3,7 @@ use crate::{ctx_img, img, Margin, Slide};
 use eframe::egui;
 use eframe::egui::{Frame, Ui, Vec2, Window};
 
+/// The first slide in the cartoon.
 #[derive(Default)]
 pub struct Title {
     examples: Vec<egui::TextureHandle>,
@@ -11,6 +12,7 @@ pub struct Title {
 impl Slide for Title {
     fn show(&mut self, ui: &mut Ui) {
         if self.examples.is_empty() {
+            // For now, these images are somewhat like placeholders.
             self.examples = vec![
                 ctx_img!(ui.ctx(), "raymarching0.png"),
                 ctx_img!(ui.ctx(), "raymarching1.png"),
@@ -20,19 +22,16 @@ impl Slide for Title {
             ];
         }
 
-        ui.scope(|ui| {
-            ui.style_mut().spacing.window_margin = Margin::same(4.0);
-
-            for example in &self.examples {
-                Window::new(example.name())
-                    .title_bar(false)
-                    .resizable(false)
-                    .frame(Frame::window(&ui.style()).margin(Margin::same(5.0)))
-                    .show(ui.ctx(), |ui| {
-                        ui.image(example, Vec2::splat(128.0));
-                    });
-            }
-        });
+        for example in &self.examples {
+            Window::new(example.name())
+                .title_bar(false)
+                .resizable(false)
+                // Reduce margin of example images.
+                .frame(Frame::window(&ui.style()).margin(Margin::same(5.0)))
+                .show(ui.ctx(), |ui| {
+                    ui.image(example, Vec2::splat(128.0));
+                });
+        }
 
         Window::new("title")
             .title_bar(false)
diff --git a/src/slide/s2_introduction.rs b/src/slide/s2_introduction.rs
index fe97817..6c476ea 100644
--- a/src/slide/s2_introduction.rs
+++ b/src/slide/s2_introduction.rs
@@ -1,6 +1,7 @@
 use crate::{fade_in, Margin, Slide};
 use eframe::egui::{Context, Frame, Ui};
 
+/// A slide that sets some expectations about generative art.
 #[derive(Default)]
 pub struct Introduction {
     state: IntroductionState,
@@ -11,6 +12,7 @@ enum IntroductionState {
     #[default]
     Weaknesses,
     Strengths {
+        /// What time we started fading in the strengths.
         transition_time: f64,
     },
 }
diff --git a/src/slide/s3_complexity.rs b/src/slide/s3_complexity.rs
index 92e09ce..3dd1dfa 100644
--- a/src/slide/s3_complexity.rs
+++ b/src/slide/s3_complexity.rs
@@ -4,27 +4,36 @@ use eframe::egui::text_edit::{CCursorRange, TextEditState};
 use eframe::egui::{Align2, Frame, TextEdit, Vec2, Widget};
 use eframe::epaint::text::cursor::CCursor;
 
+/// Introduction for emergent complexity.
 #[derive(Default)]
 pub struct Complexity {
     state: ComplexityState,
     last_time: f64,
 }
 
+/// What state we are in, with respect to the action of selecting "Complex" and replacing it
+/// with "Simple."
 #[derive(Default, Eq, PartialEq, Debug)]
 enum ComplexityState {
+    /// Haven't started the transition yet.
     #[default]
     Before,
+    /// Selected this many characters of "Complex."
     Selecting(usize),
+    /// Typed this many characters of "Simple."
     Typing(usize),
+    /// Animation over.
     After,
 }
 
 impl Slide for Complexity {
     fn transition(&mut self, _ctx: &Context) -> bool {
         if self.state == ComplexityState::Before {
+            // If we haven't started the animation, start it.
             self.state = ComplexityState::Selecting(0);
             false
         } else {
+            // Otherwise, continue to next slide.
             true
         }
     }
@@ -33,11 +42,15 @@ impl Slide for Complexity {
         Window::new("complexity")
             .title_bar(false)
             .resizable(false)
+            // Don't show window background.
             .frame(Frame::none())
             .anchor(Align2::CENTER_CENTER, Vec2::ZERO)
+            // Width was determined anecdotally. Height is arbitrary.
             .fixed_size(Vec2::new(440.0, 100.0))
             .show(ui.ctx(), |ui| {
                 ui.ctx().request_repaint();
+
+                // TODO(finnb) replace with [`Governor`].
                 let time = ui.input().time;
                 let time_delta = (time - self.last_time).min(1.0);
                 let made_progress = time_delta > 0.1;
@@ -85,8 +98,10 @@ impl Slide for Complexity {
                         .desired_width(f32::INFINITY)
                         .ui(ui);
                     if state.ccursor_range().is_some() {
+                        // Necessary to render selecting.
                         text_edit.request_focus();
                     } else {
+                        // We're done selecting.
                         text_edit.surrender_focus();
                     }
                     TextEdit::store_state(ui.ctx(), text_edit.id, state);
diff --git a/src/slide/s4_automata.rs b/src/slide/s4_automata.rs
index 5ba5385..4239c4b 100644
--- a/src/slide/s4_automata.rs
+++ b/src/slide/s4_automata.rs
@@ -5,15 +5,21 @@ use eframe::egui::style::Margin;
 use eframe::egui::{Color32, Frame, Ui};
 use rand::Rng;
 
+/// Conway's Game of Life, etc.
 pub struct Automata {
+    /// Persistent state of the grid.
     life: Grid,
+    /// For knowing when to advance the simulation.
     governor: Governor,
 }
 
 impl Default for Automata {
     fn default() -> Self {
         let mut life = Grid::default();
+        // Unique identifier for the grid.
         life.name = "life";
+
+        // Fill grid with random cells.
         for y in 0..life.size_cells {
             for x in 0..life.size_cells {
                 if rand::thread_rng().gen_bool(0.5) {
@@ -22,6 +28,7 @@ impl Default for Automata {
             }
         }
 
+        // This would replace the grid with a single oscillator.
         /*
         life.clear_fill();
         life.set_fill(5, 5, Color32::BLACK);
@@ -44,7 +51,9 @@ impl Slide for Automata {
             });
         });
 
+        // Need to continuously animate the grid, or at least poll the governor.
         ui.ctx().request_repaint();
+
         if self.governor.ready(ui.ctx().input().time, 0.2) {
             self.life = conways_game_of_life(&self.life);
         }
@@ -52,6 +61,7 @@ impl Slide for Automata {
     }
 }
 
+/// Run one iteration of Conway's Game of Life on the grid, producing a new grid.
 fn conways_game_of_life(grid: &Grid) -> Grid {
     let mut new = grid.clone();
     new.clear_fill();
diff --git a/src/slide/s5_fractals.rs b/src/slide/s5_fractals.rs
index 037baa4..adafb70 100644
--- a/src/slide/s5_fractals.rs
+++ b/src/slide/s5_fractals.rs
@@ -11,27 +11,37 @@ use crate::slide::s5_fractals::rectangle::rectangle;
 use crate::Slide;
 use eframe::egui::style::Margin;
 
+/// Mandelbrot, etc.
 pub struct Fractals {
+    /// Where we are in the transitions.
     state: FractalsState,
+    /// Pseudocode display.
     code: Code,
+    /// Persistent grid state.
     grid: Grid,
 }
 
 #[derive(Default)]
 #[allow(unused)]
 enum FractalsState {
+    /// Nothing on screen (except header).
     #[default]
     Before,
+    /// Fading in grid.
     Grid {
+        /// When we started fading in the grid.
         fade_start: f64,
     },
     Rectangle {
+        /// TODO(finnb): How many pixels of the grid we've filled in.
         pixel: usize,
     },
     Circle {
+        /// TODO(finnb): How many pixels of the grid we've filled in.
         pixel: usize,
     },
     Mandelbrot {
+        /// TODO(finnb): How many pixels of the grid we've filled in.
         pixel: usize,
     },
 }
@@ -40,15 +50,19 @@ impl Default for Fractals {
     fn default() -> Self {
         const HORIZONTAL_OFFSET: f32 = 275.0;
 
+        // Code goes on the left.
         let mut code = Code::default();
         code.name = "fractal_code";
         code.offset_x = -HORIZONTAL_OFFSET;
 
+        // Grid goes on the right.
         let mut grid = Grid::default();
         grid.name = "fractal_grid";
         grid.offset_x = HORIZONTAL_OFFSET;
 
         grid.size_cells = 256;
+
+        // Grid cell stroke aliases too much at this resolution.
         grid.stroke_width = 0.0;
 
         Self {
@@ -68,7 +82,13 @@ impl Slide for Fractals {
                     fade_start: ctx.input().time,
                 }
             }
-            FractalsState::Grid { .. } => self.state = FractalsState::Rectangle { pixel: 0 },
+            FractalsState::Grid { .. } => {
+                // Make sure we finished fading in.
+                self.code.alpha = 1.0;
+                self.grid.alpha = 1.0;
+
+                self.state = FractalsState::Rectangle { pixel: 0 }
+            }
             FractalsState::Rectangle { .. } => self.state = FractalsState::Circle { pixel: 0 },
             FractalsState::Circle { .. } => self.state = FractalsState::Mandelbrot { pixel: 0 },
             FractalsState::Mandelbrot { .. } => return true,
@@ -85,13 +105,16 @@ impl Slide for Fractals {
 
         ui.ctx().request_repaint();
 
+        // The function that will be used to color the grid.
         let algo: Box<dyn Fn(f32, f32) -> bool>;
 
         match self.state {
             FractalsState::Before => {
+                // Don't proceed to render the code/grid.
                 return;
             }
             FractalsState::Grid { fade_start } => {
+                // Fade in the code and grid.
                 let elapsed = ui.ctx().input().time - fade_start;
                 let alpha = (elapsed * 2.0).min(1.0) as f32;
                 self.code.alpha = alpha;
@@ -112,8 +135,11 @@ impl Slide for Fractals {
             }
         }
 
+        // TODO: Different demos may need different resolutions.
         const RESOLUTION: usize = 256;
 
+        // Paint the grid.
+        // TODO(finnb): Paint pixel by pixel.
         for (gx, gy, c) in self.grid.iter_mut() {
             // 0 to 1.
             let nx = (gx as f32 + 0.5) / RESOLUTION as f32;
diff --git a/src/slide/s7_mosaic.rs b/src/slide/s7_mosaic.rs
index 36241f1..e04e522 100644
--- a/src/slide/s7_mosaic.rs
+++ b/src/slide/s7_mosaic.rs
@@ -8,6 +8,7 @@ pub struct Mosaic {}
 
 impl Slide for Mosaic {
     fn show(&mut self, ui: &mut Ui) {
+        // TODO: Finish this slide.
         Frame::none().margin(Margin::same(20.0)).show(ui, |ui| {
             ui.heading("Going Further");
             ui.add_space(8.0);
-- 
GitLab