diff --git a/src/component/example_list.rs b/src/component/example_list.rs index 9e744faef64b04ea2a47c1e78e884489e5613022..2e7a3b84e897646c32a343878c5c173756932c2c 100644 --- a/src/component/example_list.rs +++ b/src/component/example_list.rs @@ -1,4 +1,4 @@ -use crate::component::image::Image; +use crate::component::image::{Image, ImagePosition}; use crate::egui::{Context, Frame, Ui}; use crate::fade_in::{fade_in, fade_in_manual}; use eframe::egui::style::Margin; @@ -79,7 +79,7 @@ impl ExampleList { ); Image::default() .height(IMAGE_SCALE) - .position(position) + .position(ImagePosition::Global(position)) .alpha(alpha) .show(ui, &example.texture); }); diff --git a/src/component/grid.rs b/src/component/grid.rs index 74d44d61a8dc28fbc5a3ff175630a08e0a57448e..c4399be26868bdd05baf13a12d96a3fbcf8805cf 100644 --- a/src/component/grid.rs +++ b/src/component/grid.rs @@ -28,7 +28,7 @@ pub struct Grid { /// Transparency of entire widget. pub alpha: f32, /// Fill color of each pixel (use getters and setters). - fill: Vec<Color32>, + pub fill: Vec<Color32>, } impl Default for Grid { diff --git a/src/component/image.rs b/src/component/image.rs index abb8ffff9359ed1e54079db24012ba1189c99855..1dd2d1b5ec3330214119d0ef25243e30263b9a7a 100644 --- a/src/component/image.rs +++ b/src/component/image.rs @@ -1,5 +1,5 @@ use crate::color::{set_alpha, set_style_alpha}; -use crate::egui::{Color32, TextureHandle, Ui}; +use crate::egui::{Align2, Color32, TextureHandle, Ui}; use eframe::egui; use eframe::egui::style::Margin; use eframe::egui::{Frame, Pos2, Vec2, Widget, Window}; @@ -10,22 +10,33 @@ pub struct Image { pub height: f32, /// How opaque the image is. pub alpha: f32, - /// Center position. - pub position: Option<Pos2>, + /// Where to display the image. + pub position: ImagePosition, + /// How wide the margins are. + pub margin: f32, +} + +#[derive(Default)] +pub enum ImagePosition { + #[default] + Auto, + Global(Pos2), + FromCenter(Vec2), } impl Default for Image { fn default() -> Self { - Self::new(128.0, 1.0, None) + Self::new(128.0, 1.0, ImagePosition::default()) } } impl Image { - pub fn new(height: f32, alpha: f32, position: Option<Pos2>) -> Self { + pub fn new(height: f32, alpha: f32, position: ImagePosition) -> Self { Self { height, alpha, position, + margin: 5.0, } } @@ -42,9 +53,14 @@ impl Image { } /// Change the position of the image. - pub fn position(mut self, position: Pos2) -> Self { - // We assume that, if you call this method, you don't want [`None`]. - self.position = Some(position); + pub fn position(mut self, position: ImagePosition) -> Self { + self.position = position; + self + } + + /// Change the margine of the image. + pub fn margin(mut self, margin: f32) -> Self { + self.margin = margin; self } @@ -54,11 +70,18 @@ impl Image { .resizable(false) // Reduce margin of images. .frame( - Frame::window(&set_style_alpha(ui.style(), self.alpha)).margin(Margin::same(5.0)), + Frame::window(&set_style_alpha(ui.style(), self.alpha)) + .margin(Margin::same(self.margin)), ); - if let Some(position) = self.position { - window = window.default_pos(position).fixed_pos(position); + match &self.position { + ImagePosition::Auto => {} + &ImagePosition::Global(position) => { + window = window.default_pos(position).fixed_pos(position); + } + &ImagePosition::FromCenter(offset) => { + window = window.anchor(Align2::CENTER_CENTER, offset); + } } window.show(ui.ctx(), |ui| { diff --git a/src/image/squirrel0.png b/src/image/squirrel0.png new file mode 100644 index 0000000000000000000000000000000000000000..cfbf1fb8fa75429a7fced8e525ac413abd0f8fb7 Binary files /dev/null and b/src/image/squirrel0.png differ diff --git a/src/slide/s6_fractals.rs b/src/slide/s6_fractals.rs index 1eaeedfc758856cc1402e3d1bd23cbcc883ede2e..c598867ccb89c62c9c53f4e9096af8825f70ddd0 100644 --- a/src/slide/s6_fractals.rs +++ b/src/slide/s6_fractals.rs @@ -301,7 +301,7 @@ impl Slide for Fractals { let nx = (gx as f32 + 0.5) / size_cells as f32; let ny = (gy as f32 + 0.5) / size_cells as f32; - // -4 to 4. + // -2 to 2. let x = nx * 4.0 - 2.0; let y = ny * 4.0 - 2.0; diff --git a/src/slide/s8_mosaic.rs b/src/slide/s8_mosaic.rs index 588ed33d2ef9724266bd26c9fbd7c604085ef46d..6d62308443edbca04f2773eeacc68e51174d1427 100644 --- a/src/slide/s8_mosaic.rs +++ b/src/slide/s8_mosaic.rs @@ -1,19 +1,22 @@ +use crate::component::grid::Grid; +use crate::component::image::{Image, ImagePosition}; use crate::component::triangle::Triangle; -use crate::egui::{Color32, Ui}; +use crate::ctx_img; +use crate::egui::{Color32, TextureHandle, Ui, Vec2}; use crate::slide::Slide; use eframe::egui::style::Margin; use eframe::egui::{Frame, Pos2}; #[derive(Default)] -pub struct Mosaic {} +pub struct Mosaic { + squirrel: Option<TextureHandle>, +} 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); - ui.label("TODO: Triangle mosaic"); + ui.heading("Generative Image Processing"); Triangle { points: [ @@ -27,5 +30,23 @@ impl Slide for Mosaic { } .show(ui) }); + + Image::default() + .height(512.0) + .position(ImagePosition::FromCenter(Vec2::new(-300.0, 0.0))) + .margin(16.0) + .show( + ui, + self.squirrel + .get_or_insert_with(|| ctx_img!(ui.ctx(), "squirrel0.png")), + ); + + Grid { + size_pixels: 512.0, + alpha: 1.0, + offset_x: 300.0, + ..Grid::default() + } + .show(ui.ctx()); } }