From ef14cef49b71ee719d9f401f22e99708d3609b41 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Sat, 4 May 2024 14:59:13 +0200 Subject: [PATCH] add names to groups --- petri/src/lib.rs | 34 ++++++++++++++++++---------- uscope/src/main.rs | 55 ++++++++++++++++++++-------------------------- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/petri/src/lib.rs b/petri/src/lib.rs index 73406ef..cbc32b4 100644 --- a/petri/src/lib.rs +++ b/petri/src/lib.rs @@ -10,7 +10,14 @@ pub struct Cell(pub u16); pub struct Dish { pub chunk: Chunk, pub rules: Vec, - pub cell_groups: Vec>>, + pub cell_groups: Vec, +} + +#[derive(Debug, Default, Serialize, Deserialize)] +pub struct CellGroup { + pub name: String, + pub void: bool, + pub cells: Vec, } #[derive(Debug)] @@ -26,12 +33,10 @@ pub struct Rule { #[serde(skip)] variants: Vec, pub enabled: bool, - // probability: u8 - #[serde(alias = "flip_h")] pub flip_x: bool, - #[serde(alias = "flip_v")] pub flip_y: bool, pub rotate: bool, + // probability: u8 } #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] @@ -331,7 +336,11 @@ impl Dish { Self { chunk: Chunk::new().fill_random(), rules: default_rules, - cell_groups: vec![vec![None, Some(Cell(1))]], + cell_groups: vec![CellGroup { + name: "empty".into(), + void: true, + cells: vec![Cell(0)], + }], } } @@ -395,11 +404,9 @@ impl Dish { } RuleCellTo::GroupRandom(group_id) => { let group = &self.cell_groups[group_id]; - let i = random::() % group.len(); - let cell = group[i]; - if let Some(cell) = cell { - self.set_cell(px, py, cell); - } + let i = random::() % group.cells.len(); + let cell = group.cells[i]; + self.set_cell(px, py, cell); } RuleCellTo::Copy(x, y) => { let cell = old_state[x + y * variant.width]; @@ -427,7 +434,12 @@ impl Dish { } } RuleCellFrom::Group(group_id) => { - if !self.cell_groups[group_id].contains(&cell) { + let group = &self.cell_groups[group_id]; + if let Some(cell) = cell { + if !group.cells.contains(&cell) { + return false; + } + } else if !group.void { return false; } } diff --git a/uscope/src/main.rs b/uscope/src/main.rs index 8daacb4..f0f0efd 100644 --- a/uscope/src/main.rs +++ b/uscope/src/main.rs @@ -15,7 +15,7 @@ use native_dialog::FileDialog; use rand::prelude::*; use serde::{Deserialize, Serialize}; -use petri::{Cell, Chunk, Dish, Rule, RuleCellFrom, RuleCellTo, CHUNK_SIZE}; +use petri::{Cell, CellGroup, Chunk, Dish, Rule, RuleCellFrom, RuleCellTo, CHUNK_SIZE}; use serde_json::{json, Value}; fn main() { @@ -147,29 +147,25 @@ impl eframe::App for UScope { let (rect, _response) = ui.allocate_exact_size(Vec2::splat(CSIZE), Sense::click()); draw_group(ui, rect, group, &self.cell_types); - ui.menu_button("edit", |ui| { - let mut void = group.contains(&None); - if ui.checkbox(&mut void, "void").changed() { - if void { - group.push(None); - } else { - group.retain(|c| c.is_some()); - } - } - for (i, celldata) in self.cell_types.iter().enumerate() { - let mut included = group.contains(&Some(Cell(i as u16))); - if ui.checkbox(&mut included, &celldata.name).changed() { - if included { - group.push(Some(Cell(i as u16))); - } else { - group.retain(|c| c != &Some(Cell(i as u16))); + ui.horizontal(|ui| { + ui.menu_button("edit", |ui| { + ui.checkbox(&mut group.void, "void"); + for (i, celldata) in self.cell_types.iter().enumerate() { + let mut included = group.cells.contains(&Cell(i as u16)); + if ui.checkbox(&mut included, &celldata.name).changed() { + if included { + group.cells.push(Cell(i as u16)); + } else { + group.cells.retain(|c| c != &Cell(i as u16)); + } } } - } + }); + ui.text_edit_singleline(&mut group.name); }); } if ui.button("add group").clicked() { - self.dish.cell_groups.push(Vec::new()); + self.dish.cell_groups.push(CellGroup::default()); } ui.heading("Rules"); @@ -177,7 +173,6 @@ impl eframe::App for UScope { let mut to_remove = None; let mut to_clone = None; for (i, rule) in self.dish.rules.iter_mut().enumerate() { - // ui.separator(); rule_editor( ui, rule, @@ -252,7 +247,7 @@ fn rule_editor( rule: &mut Rule, index: usize, cells: &[CellData], - groups: &[Vec>], + groups: &[CellGroup], to_remove: &mut Option, to_clone: &mut Option, ) { @@ -408,7 +403,7 @@ fn rule_cell_edit_from( x: usize, y: usize, cells: &[CellData], - groups: &[Vec>], + groups: &[CellGroup], ) -> bool { let mut changed = false; let rect = Rect::from_min_size( @@ -471,7 +466,7 @@ fn rule_cell_edit_to( rule: &mut RuleCellTo, (x, y): (usize, usize), cells: &[CellData], - groups: &[Vec>], + groups: &[CellGroup], (rule_width, rule_height): (usize, usize), overlay_lines: &mut Vec<(Pos2, Pos2)>, ) -> bool { @@ -552,23 +547,21 @@ fn rule_cell_edit_to( changed } -fn draw_group(ui: &mut Ui, rect: Rect, group: &[Option], cells: &[CellData]) { - let mut group_size = group.len(); - let has_void = group.contains(&None); - if has_void { - group_size -= 1; - } +fn draw_group(ui: &mut Ui, rect: Rect, group: &CellGroup, cells: &[CellData]) { + let group_size = group.cells.len(); let radius_per_color = (CSIZE * 0.7) / (group_size as f32); - for (i, cell) in group.iter().flatten().enumerate() { + for (i, cell) in group.cells.iter().enumerate() { let color = cells[cell.id()].color; let radius = radius_per_color * ((group_size - i) as f32); ui.painter_at(rect) .circle_filled(rect.center(), radius, color); } - if has_void { + if group.void { ui.painter_at(rect) .line_segment([rect.min, rect.max], (1., Color32::WHITE)); } + ui.allocate_rect(rect, Sense::hover()) + .on_hover_text(&group.name); } impl CellData {