mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-24 10:09:32 -06:00
#1368: dragging an effect lights up the layer it will land on
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
549e9d8251
commit
9f02bd2a72
@@ -3330,8 +3330,18 @@ pub fn show(app: &mut EffectcraftApp, ui: &mut egui::Ui, rect: Rect) {
|
||||
{
|
||||
let released = ctx.input(|i| i.pointer.any_released());
|
||||
if let crate::panels::DragPayload::Effect(e) = payload.as_ref() {
|
||||
p.rect_stroke(rows_rect, 0.0, Stroke::new(2.0, t.accent), StrokeKind::Inside);
|
||||
let target = hit_rows.iter().find(|(r, _)| ptr.y >= r.min.y && ptr.y < r.max.y).map(|(_, row)| row.layer);
|
||||
// The layer the effect would land on (its row and its open properties) is the one
|
||||
// that lights up, not the whole timeline.
|
||||
if let Some(l) = target
|
||||
&& let Some(span) = hit_rows.iter().filter(|(_, row)| row.layer == l).map(|(r, _)| *r).reduce(|a, b| a.union(b))
|
||||
{
|
||||
let lit = span.intersect(rows_rect);
|
||||
let rp = p.with_clip_rect(rows_rect);
|
||||
rp.rect_filled(lit, 0.0, t.accent.gamma_multiply(0.18));
|
||||
rp.rect_stroke(lit, 0.0, Stroke::new(2.0, t.accent), StrokeKind::Inside);
|
||||
app.auto.add("timeline.dropTarget", lit, "Drop target layer");
|
||||
}
|
||||
if released && let Some(l) = target {
|
||||
actions.push(("effect.apply".into(), json!({"effect": e, "layers": [l.0]})));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
//! Dragging an effect over the Timeline lights up the layer it would land on, not the whole panel.
|
||||
use effectcraft_engine::Session;
|
||||
use effectcraft_ui_egui::{EffectcraftApp, panels::DragPayload};
|
||||
use egui::{Event, Modifiers, PointerButton, Pos2, Rect, pos2, vec2};
|
||||
use egui_kittest::Harness;
|
||||
use serde_json::json;
|
||||
|
||||
fn rect(h: &Harness<'_, EffectcraftApp>, id: &str) -> Rect {
|
||||
let e = h.state().auto.find(id).unwrap_or_else(|| panic!("missing {id}"));
|
||||
Rect::from_min_size(pos2(e.rect[0], e.rect[1]), vec2(e.rect[2], e.rect[3]))
|
||||
}
|
||||
|
||||
fn drag_to(h: &mut Harness<'_, EffectcraftApp>, p: Pos2) {
|
||||
h.input_mut().events.push(Event::PointerMoved(p));
|
||||
h.input_mut().events.push(Event::PointerButton { pos: p, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
|
||||
egui::DragAndDrop::set_payload(&h.ctx, DragPayload::Effect("CC Bend It".into()));
|
||||
h.run_steps(2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn effect_drag_highlights_the_layer_under_the_pointer() {
|
||||
let mut s = Session::default();
|
||||
s.execute("comp.new", json!({"name": "Main", "width": 640, "height": 360, "duration": 4})).unwrap();
|
||||
let a = s.execute("layer.newNull", json!({})).unwrap()["layer"].as_u64().unwrap();
|
||||
let b = s.execute("layer.newNull", json!({})).unwrap()["layer"].as_u64().unwrap();
|
||||
let mut h = Harness::builder().with_size(vec2(1600.0, 1000.0)).build_eframe(|_| EffectcraftApp::new(s));
|
||||
h.run_steps(3);
|
||||
assert!(h.state().auto.find("timeline.dropTarget").is_none(), "nothing is lit without a drag");
|
||||
let (row_a, row_b) = (rect(&h, &format!("timeline.layer.{a}.row")), rect(&h, &format!("timeline.layer.{b}.row")));
|
||||
let panel = rect(&h, "timeline.layerMarquee");
|
||||
|
||||
drag_to(&mut h, row_b.center());
|
||||
let lit = rect(&h, "timeline.dropTarget");
|
||||
assert!(lit.contains(row_b.center()) && !lit.contains(row_a.center()), "lit {lit:?} for row {row_b:?}");
|
||||
assert!(lit.height() < panel.height(), "only the layer is lit, not the whole timeline");
|
||||
|
||||
drag_to(&mut h, row_a.center());
|
||||
let lit = rect(&h, "timeline.dropTarget");
|
||||
assert!(lit.contains(row_a.center()) && !lit.contains(row_b.center()), "the highlight follows the pointer: {lit:?}");
|
||||
}
|
||||
Reference in New Issue
Block a user