Merge pull request #984 from MarekSpodBiedry/issue-957

Show the Continuously Rasterize switch on vector footage layers (#957)

# Conflicts:
#	crates/ui-egui/src/panels/timeline.rs
This commit is contained in:
Brandon Thomas committed 2026-10-12 05:21:57 -04:00
commit 84c6281da9
1 file changed
+32 -1
+32 -1
View File
@@ -1909,7 +1909,7 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
// Switches.
let sws: [(Icon, bool, &str, bool); 8] = [
(Icon::Shy, sw.shy, "shy", true),
(Icon::Collapse, sw.collapse, "collapse", matches!(layer.source, LayerSource::Comp { .. } | LayerSource::Shape | LayerSource::Text)),
(Icon::Collapse, sw.collapse, "collapse", collapse_applies(layer, &app.session.project)),
(Icon::Quality, sw.quality == effectcraft_engine::project::Quality::Best, "quality", layer.source.is_av()),
(Icon::Fx, sw.effects, "fx", layer.effects().is_some_and(|f| !f.children.is_empty())),
(
@@ -3505,6 +3505,19 @@ pub(crate) fn vector_footage_layer(project: &effectcraft_engine::project::Projec
.is_some_and(|item| matches!(&item.kind, effectcraft_engine::project::ItemKind::Footage(footage) if effectcraft_engine::vector::is_vector(footage)))
}
/// Whether the Collapse Transformations / Continuously Rasterize switch applies: precomps, shape and text
/// layers, and vector footage (SVG, PDF, AI, EPS), which the renderer re-rasterizes at the layer's scale.
fn collapse_applies(layer: &Layer, project: &effectcraft_engine::project::Project) -> bool {
match &layer.source {
LayerSource::Comp { .. } | LayerSource::Shape | LayerSource::Text => true,
LayerSource::Footage { item } => {
let kind = project.item(*item).map(|i| &i.kind);
matches!(kind, Some(effectcraft_engine::project::ItemKind::Footage(f)) if effectcraft_engine::render::is_vector_footage(f))
}
_ => false,
}
}
fn layer_context_menu(resp: &egui::Response, comp: &Comp, layer: &Layer, selected: &[LayerId], vector: bool, actions: &mut Vec<(String, serde_json::Value)>) {
let in_selection = selected.contains(&layer.id);
if resp.secondary_clicked() && !in_selection && !layer.switches.locked {
@@ -3835,6 +3848,24 @@ mod tests {
assert!(track_matte_pick(&bottom, &candidates, 1, "-").is_none(), "a separator does nothing");
}
/// #957: vector footage gets the Continuously Rasterize switch; raster footage does not.
#[test]
fn collapse_switch_shows_for_vector_footage_only() {
use effectcraft_engine::color::Label;
use effectcraft_engine::project::{Footage, ItemKind, Project};
let mut p = Project::default();
let mut layer_for = |name: &str, codec: &str| {
let footage = Footage { path: name.into(), codec: codec.into(), ..Default::default() };
let item = p.add_item(name, Label::SeaFoam, None, ItemKind::Footage(footage));
let comp = Comp::new(64, 36, effectcraft_engine::time::FrameRate::new(30, 1), Tick::from_seconds_f64(1.0));
effectcraft_engine::project::build::layer(&mut p, &comp, name, LayerSource::Footage { item }, (0, 0), None)
};
let svg = layer_for("logo.svg", "SVG");
let png = layer_for("photo.png", "PNG");
assert!(collapse_applies(&svg, &p));
assert!(!collapse_applies(&png, &p));
}
/// A comp with two solids; "Box" has an animated Position and a Gaussian Blur.
fn app() -> EffectcraftApp {
let mut s = effectcraft_engine::Session::default();