mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 13:47:21 -06:00
Merge pull request #4617 from VoiceLessQ/fix/3098-trace-inputs-and-repaint
Image Trace: background traces see library colour changes, and keep frames coming (#3098)
This commit is contained in:
@@ -377,8 +377,11 @@ fn grouped(d: &mut Document, nodes: Vec<Node>, parents: &[Option<usize>]) -> Vec
|
||||
struct TraceInputs {
|
||||
target: NodeId,
|
||||
image: Box<ImageObject>,
|
||||
/// The settings traced with, as JSON, the library's colours in.
|
||||
/// The settings traced with, as JSON.
|
||||
params: Value,
|
||||
/// Document Library: the library's colours, which the JSON leaves out
|
||||
/// ([`tr::TraceParams::swatches`]).
|
||||
swatches: Vec<[u8; 3]>,
|
||||
}
|
||||
|
||||
/// What `imageTrace.make` and `imageTrace.makeAndExpand` take from the session before they trace.
|
||||
@@ -431,7 +434,7 @@ fn prepare(s: &Session, c: &str, p: &Value) -> Result<Prepared> {
|
||||
let bytes = Arc::clone(&blob.bytes);
|
||||
let library = trace_library(c, s, &mut params)?;
|
||||
let traced_with = serde_json::to_value(¶ms).map_err(|e| EngineError::Other(e.to_string()))?;
|
||||
let inputs = TraceInputs { target, image, params: traced_with };
|
||||
let inputs = TraceInputs { target, image, params: traced_with, swatches: params.swatches.clone() };
|
||||
Ok(Prepared { inputs, trace: params, view, params_json, preset_label, library, bytes })
|
||||
}
|
||||
|
||||
@@ -544,7 +547,7 @@ pub(super) fn trace_make(s: &mut Session, p: &Value, expand: bool) -> Result<Val
|
||||
Some(traced) if traced.inputs == inputs => traced,
|
||||
_ => trace_now(&inputs, &trace, &bytes, &|_, _| true)?,
|
||||
};
|
||||
let TraceInputs { target, image: img, params: _ } = inputs;
|
||||
let TraceInputs { target, image: img, .. } = inputs;
|
||||
let warnings = trace_warnings((img.width, img.height), raster, res.worked_at);
|
||||
// Pixel space of the decoded raster → the image object's pixel space → document.
|
||||
let sx = img.width.max(1) as f64 / raster.0.max(1) as f64;
|
||||
|
||||
@@ -2768,6 +2768,21 @@ fn a_trace_run_hands_its_trace_to_the_command() {
|
||||
assert!((bb.center().x - 160.0).abs() < 1.5, "traced where the image is now: {bb:?}");
|
||||
}
|
||||
|
||||
/// A Document Library trace made away from its command no longer applies once the library's
|
||||
/// colours change: the settings' JSON leaves them out (#4605 review).
|
||||
#[test]
|
||||
fn a_trace_run_needs_the_library_colours_it_traced_with() {
|
||||
let mut s = session();
|
||||
image_doc(&mut s);
|
||||
let p = json!({"preset": "6 Colors", "params": {"palette": "documentLibrary"}});
|
||||
let run = cmd::TraceRun::prepare(&s, "imageTrace.make", &p).unwrap();
|
||||
assert!(run.current(&s));
|
||||
let swatch = |w: &&vectorcraft_color::Swatch| matches!(w.paint, Paint::Solid { .. }) && !w.name.starts_with('[');
|
||||
let name = s.doc().unwrap().doc.swatches_iter().find(swatch).map(|w| w.name.clone()).unwrap();
|
||||
s.execute("swatch.edit", &json!({"name": name, "color": "#123456"})).unwrap();
|
||||
assert!(!run.current(&s), "{name} changed");
|
||||
}
|
||||
|
||||
/// Shapes: the disc of the test image comes out as a live ellipse where the image lies, the same
|
||||
/// circle as its traced path; without the option it is a plain path.
|
||||
#[test]
|
||||
|
||||
@@ -298,6 +298,7 @@ impl VectorcraftApp {
|
||||
|| !self.opening.pending.is_empty()
|
||||
|| !self.plugin_runs.running.is_empty()
|
||||
|| !self.placing.pending.is_empty()
|
||||
|| !self.trace_runs.running.is_empty()
|
||||
{
|
||||
// Keep the status bar's progress moving and pick the result up when it arrives.
|
||||
ctx.request_repaint_after(std::time::Duration::from_millis(100));
|
||||
|
||||
@@ -76,6 +76,27 @@ fn make_traces_off_the_ui_thread_as_one_undo_step() {
|
||||
assert_eq!(app.session.doc().unwrap().history.undo.last().unwrap().label, "Image Trace (Make and Expand)");
|
||||
}
|
||||
|
||||
/// Starting a trace asks for a frame, so its result is picked up without input: the frame that
|
||||
/// started it may have asked for its next one before it did (#4617 review).
|
||||
#[test]
|
||||
fn starting_a_trace_asks_for_a_frame() {
|
||||
let mut app = app();
|
||||
let ctx = egui::Context::default();
|
||||
app.adopt_context(&ctx);
|
||||
for _ in 0..5 {
|
||||
if !ctx.has_requested_repaint() {
|
||||
break;
|
||||
}
|
||||
let mut out = ctx.run_ui(Default::default(), |_| {});
|
||||
out.textures_delta.clear();
|
||||
}
|
||||
assert!(!ctx.has_requested_repaint(), "the context settled");
|
||||
crate::menus::invoke(&mut app, "imageTrace.make", json!({"preset": "Default"}));
|
||||
assert_eq!(app.trace_runs.running.len(), 1);
|
||||
assert!(ctx.has_requested_repaint());
|
||||
wait(&mut app);
|
||||
}
|
||||
|
||||
/// Without threads (the web, `VECTORCRAFT_SYNC_OPEN`, unit tests that don't ask), Make traces at once.
|
||||
#[test]
|
||||
fn without_threads_make_traces_at_once() {
|
||||
|
||||
@@ -121,6 +121,10 @@ pub fn start(app: &mut VectorcraftApp, command: &str, p: Value, from_panel: bool
|
||||
let runs = &mut app.trace_runs;
|
||||
runs.next_id += 1;
|
||||
runs.running.push(Running { id: runs.next_id, doc, target, token, superseded: false, steps, from_panel, hidden: false, done });
|
||||
// This frame may have asked for its next one before the trace started (`tick`): ask now.
|
||||
if let Some(ctx) = &app.ui_ctx {
|
||||
ctx.request_repaint();
|
||||
}
|
||||
let status = format!("{}…", crate::i18n::msg(LABEL));
|
||||
app.status(status.clone());
|
||||
Ok(json!({ "background": true, "status": status }))
|
||||
|
||||
Reference in New Issue
Block a user