fix: show finished shapes as the export draws them

This commit is contained in:
elwrcl committed 2026-10-02 18:31:29 +03:00
1 parent cf8b043e1f
commit bf8e0500eb
2 files changed
+44 -3

No files matched your search

+27
View File
@@ -8,6 +8,7 @@ pub struct Doc {
shapes: Vec<Shape>,
redo: Vec<Shape>,
saved: Vec<Shape>,
revision: u64,
}
impl Doc {
@@ -22,6 +23,7 @@ impl Doc {
pub fn add(&mut self, shape: Shape) {
self.shapes.push(shape);
self.redo.clear();
self.revision += 1;
}
pub fn undo(&mut self) -> bool {
@@ -29,6 +31,7 @@ impl Doc {
return false;
};
self.redo.push(shape);
self.revision += 1;
true
}
@@ -37,9 +40,15 @@ impl Doc {
return false;
};
self.shapes.push(shape);
self.revision += 1;
true
}
/// Changes whenever the drawn shapes do.
pub fn revision(&self) -> u64 {
self.revision
}
pub fn can_undo(&self) -> bool {
!self.shapes.is_empty()
}
@@ -87,6 +96,24 @@ mod tests {
assert!(!d.redo());
}
#[test]
fn revision_follows_the_shapes() {
let mut d = Doc::new();
let r0 = d.revision();
d.add(line(1.0));
let r1 = d.revision();
assert_ne!(r1, r0);
d.mark_saved();
assert_eq!(d.revision(), r1, "saving doesn't change what is drawn");
d.undo();
assert_ne!(d.revision(), r1);
let r2 = d.revision();
assert!(!d.undo(), "nothing left");
assert_eq!(d.revision(), r2);
d.redo();
assert_ne!(d.revision(), r2);
}
#[test]
fn a_new_shape_clears_redo() {
let mut d = Doc::new();
+17 -3
View File
@@ -52,7 +52,11 @@ pub fn run(path: &Path) -> Result<()> {
struct Editor {
path: PathBuf,
base: RgbaImage,
/// The base with every finished shape, drawn by the export renderer so
/// the canvas shows the saved pixels.
texture: egui::TextureHandle,
/// The `Doc::revision` the texture shows.
shown: u64,
doc: Doc,
tool: Tool,
color: usize,
@@ -74,6 +78,7 @@ impl Editor {
path,
base,
texture,
shown: 0,
doc: Doc::new(),
tool: Tool::Arrow,
color: 0,
@@ -299,6 +304,14 @@ impl Editor {
Color32::WHITE,
);
if self.doc.revision() != self.shown {
let composite = export::render(&self.base, self.doc.shapes());
let size = [composite.width() as usize, composite.height() as usize];
let pixels = egui::ColorImage::from_rgba_unmultiplied(size, composite.as_raw());
self.texture.set(pixels, egui::TextureOptions::LINEAR);
self.shown = self.doc.revision();
}
let shift = ui.input(|i| i.modifiers.shift);
let pointer = response
.interact_pointer_pos()
@@ -321,9 +334,10 @@ impl Editor {
}
}
let live = self.drag.as_ref().map(|d| d.shape(shift));
for shape in self.doc.shapes().iter().chain(live.as_ref()) {
for prim in geometry(shape) {
// Finished shapes are in the texture; only the one being drawn is
// painted here.
if let Some(live) = self.drag.as_ref().map(|d| d.shape(shift)) {
for prim in geometry(&live) {
paint(&painter, &prim, fit.scale, to_pos);
}
}