fix: show finished shapes as the export draws them
This commit is contained in:
1 parent
cf8b043e1f
commit
bf8e0500eb
2 files changed
+44
-3
No files matched your search
@@ -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
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user