Compare commits

..

2 commits

Author SHA1 Message Date
aa8dae639a painting 2024-05-01 17:23:04 +02:00
f71502f32a editor stuff 2024-05-01 16:42:43 +02:00
2 changed files with 65 additions and 33 deletions

View file

@ -180,6 +180,12 @@ impl RulePattern {
} }
} }
pub fn set(&mut self, x: usize, y: usize, cell: Option<Cell>) {
if x < self.width && y < self.height {
self.contents[x + self.width * y] = cell
}
}
pub fn height(&self) -> usize { pub fn height(&self) -> usize {
self.height self.height
} }

View file

@ -1,8 +1,8 @@
use eframe::{ use eframe::{
egui::{CentralPanel, Color32, Painter, Rect, Sense, SidePanel, Ui, Vec2}, egui::{CentralPanel, Color32, Painter, Pos2, Rect, Sense, SidePanel, Slider, Ui, Vec2},
NativeOptions, NativeOptions,
}; };
use petri::{Chunk, Dish, Rule, CHUNK_SIZE}; use petri::{Cell, Chunk, Dish, Rule, RulePattern, CHUNK_SIZE};
fn main() { fn main() {
eframe::run_native( eframe::run_native(
@ -16,6 +16,8 @@ fn main() {
#[derive(Debug)] #[derive(Debug)]
struct UScope { struct UScope {
dish: Dish, dish: Dish,
brush: Cell,
speed: usize,
celltypes: Vec<CellData>, celltypes: Vec<CellData>,
} }
@ -29,6 +31,8 @@ impl UScope {
fn new(_cc: &eframe::CreationContext<'_>) -> Self { fn new(_cc: &eframe::CreationContext<'_>) -> Self {
Self { Self {
dish: Dish::new(), dish: Dish::new(),
speed: 100,
brush: Cell(1),
celltypes: vec![ celltypes: vec![
CellData::new("air", 0, 0, 0), CellData::new("air", 0, 0, 0),
CellData::new("pink_sand", 255, 147, 219), CellData::new("pink_sand", 255, 147, 219),
@ -40,15 +44,22 @@ impl UScope {
impl eframe::App for UScope { impl eframe::App for UScope {
fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &eframe::egui::Context, _frame: &mut eframe::Frame) {
ctx.request_repaint(); ctx.request_repaint();
for _ in 0..100 { for _ in 0..self.speed {
self.dish.fire_blindly(); self.dish.fire_blindly();
} }
SidePanel::left("left_panel").show(ctx, |ui| { SidePanel::left("left_panel").show(ctx, |ui| {
ui.heading("Rules"); ui.heading("Simulation");
ui.text_edit_singleline(&mut "dummy"); ui.add(Slider::new(&mut self.speed, 0..=5000));
if ui.button("aaa").clicked() { ui.heading("Cells");
dbg!(&self.dish.rules); for (i, cell) in self.celltypes.iter_mut().enumerate() {
ui.horizontal(|ui| {
ui.set_width(100.);
ui.radio_value(&mut self.brush.0, i as u16, "");
ui.text_edit_singleline(&mut cell.name);
ui.color_edit_button_srgba(&mut cell.color);
});
} }
ui.heading("Rules");
for rule in &mut self.dish.rules { for rule in &mut self.dish.rules {
rule_editor(ui, rule, &self.celltypes); rule_editor(ui, rule, &self.celltypes);
} }
@ -57,60 +68,75 @@ impl eframe::App for UScope {
let bounds = ui.available_rect_before_wrap(); let bounds = ui.available_rect_before_wrap();
let painter = ui.painter_at(bounds); let painter = ui.painter_at(bounds);
paint_chunk(painter, &self.dish.chunk, &self.celltypes); paint_chunk(painter, &self.dish.chunk, &self.celltypes);
let rect = ui.allocate_rect(bounds, Sense::click_and_drag());
if let Some(pos) = rect.interact_pointer_pos() {
let p = ((pos - bounds.min) / GRID_SIZE).floor();
let x = p.x as usize;
let y = p.y as usize;
self.dish.set_cell(x, y, self.brush);
}
}); });
} }
} }
const GRID_SIZE: f32 = 16.;
fn paint_chunk(painter: Painter, chunk: &Chunk, cells: &[CellData]) { fn paint_chunk(painter: Painter, chunk: &Chunk, cells: &[CellData]) {
let bounds = painter.clip_rect(); let bounds = painter.clip_rect();
let size = 16.;
for x in 0..CHUNK_SIZE { for x in 0..CHUNK_SIZE {
for y in 0..CHUNK_SIZE { for y in 0..CHUNK_SIZE {
let cell = &chunk.get_cell(x, y); let cell = &chunk.get_cell(x, y);
let corner = bounds.min + (Vec2::from((x as f32, y as f32)) * size); let corner = bounds.min + (Vec2::from((x as f32, y as f32)) * GRID_SIZE);
let rect = Rect::from_min_size(corner, Vec2::splat(size)); let rect = Rect::from_min_size(corner, Vec2::splat(GRID_SIZE));
let color = cells[cell.id()].color; let color = cells[cell.id()].color;
painter.rect(rect, 0., color, (1., Color32::GRAY)); painter.rect(rect, 0., color, (1., Color32::GRAY));
} }
} }
} }
const CSIZE: f32 = 24.;
const OUTLINE: (f32, Color32) = (1., Color32::GRAY);
fn rule_editor(ui: &mut Ui, rule: &mut Rule, cells: &[CellData]) { fn rule_editor(ui: &mut Ui, rule: &mut Rule, cells: &[CellData]) {
let patt_height = rule.from.height(); let patt_height = rule.from.height();
let patt_width = rule.from.height(); let patt_width = rule.from.height();
const CSIZE: f32 = 24.;
const OUTLINE: (f32, Color32) = (1., Color32::GRAY);
let (_, bounds) = ui.allocate_space(Vec2::new( let (_, bounds) = ui.allocate_space(Vec2::new(
CSIZE * (patt_width * 2 + 1) as f32, CSIZE * (patt_width * 2 + 1) as f32,
CSIZE * patt_height as f32, CSIZE * patt_height as f32,
)); ));
for x in 0..patt_width { for x in 0..patt_width {
for y in 0..patt_height { for y in 0..patt_height {
rule_cell_edit(ui, bounds.min, &mut rule.from, x, y, cells);
let offset = Vec2::X * (patt_width as f32 + 1.) * CSIZE;
rule_cell_edit(ui, bounds.min + offset, &mut rule.to, x, y, cells);
}
}
}
fn rule_cell_edit(
ui: &mut Ui,
origin: Pos2,
rule: &mut RulePattern,
x: usize,
y: usize,
cells: &[CellData],
) {
let rect = Rect::from_min_size( let rect = Rect::from_min_size(
bounds.min + Vec2::from((x as f32, y as f32)) * CSIZE, origin + Vec2::from((x as f32, y as f32)) * CSIZE,
Vec2::splat(CSIZE), Vec2::splat(CSIZE),
); );
if let Some(cell) = rule.from.get_mut(x, y) { let aabb = ui.allocate_rect(rect, Sense::click());
if let Some(cell) = rule.get_mut(x, y) {
let color = cells[cell.id()].color; let color = cells[cell.id()].color;
ui.painter().rect(rect, 2., color, OUTLINE); ui.painter().rect(rect, 2., color, OUTLINE);
let a = ui.allocate_rect(rect, Sense::click()); if aabb.clicked() {
if a.clicked() { cell.0 += 1;
cell.0 = (cell.0 + 1) % cells.len() as u16; if cell.0 as usize == cells.len() {
} rule.set(x, y, None);
}
if let Some(cell) = rule.to.get_mut(x, y) {
let rect = rect.translate(Vec2::X * (patt_width as f32 + 1.) * CSIZE);
let color = cells[cell.id()].color;
ui.painter().rect(rect, 2., color, OUTLINE);
let a = ui.allocate_rect(rect, Sense::click());
if a.clicked() {
cell.0 = (cell.0 + 1) % cells.len() as u16;
}
} }
} }
} else if aabb.clicked() {
rule.set(x, y, Some(Cell(0)));
} }
} }