mirror of
https://github.com/storytold/effectcraft.git
synced 2026-11-05 18:18:49 +00:00
Timeline: the marker bin's double-click needs both clicks on the bin (#1826)
egui takes any click within a few points of the last one for the first click of a double-click, so a click on the ruler right beside the bin and then one on the bin added a marker. The bin now remembers when it was last clicked and adds one only when the first click was on it too (or both came in one frame over it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5cb2658e38
commit
5e96b2a385
2 files changed
+47
-2
No files matched your search
@@ -435,8 +435,9 @@ pub(crate) fn marker_bin(app: &mut EffectcraftApp, ui: &mut egui::Ui, comp: &Com
|
||||
// The bin senses drags only, so a drag starts as soon as it is pressed: sensing clicks too
|
||||
// would hold that back until the pointer moved, and a drag out released within that frame
|
||||
// would add nothing. The double-click is read from the pointer instead.
|
||||
let double_clicked = resp.contains_pointer() && ui.input(|i| i.pointer.button_double_clicked(egui::PointerButton::Primary));
|
||||
if double_clicked && let Err(e) = app.session.execute("comp.addMarker", json!({})) {
|
||||
if bin_double_clicked(ui, resp.id, bin, resp.contains_pointer())
|
||||
&& let Err(e) = app.session.execute("comp.addMarker", json!({}))
|
||||
{
|
||||
app.ui.status = e.to_string();
|
||||
}
|
||||
app.auto.add("timeline.markerBin", bin, "Composition marker bin");
|
||||
@@ -463,6 +464,38 @@ pub(crate) fn marker_bin(app: &mut EffectcraftApp, ui: &mut egui::Ui, comp: &Com
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether the marker bin `bin` (widget `id`, under the pointer when `here`) was double-clicked
|
||||
/// this frame: egui's double-click, with its first click on the bin too. egui takes any click
|
||||
/// within a few points of the last for the first one, so a click on the ruler right beside the
|
||||
/// bin and then one on the bin would count. The bin remembers when it was last clicked; two
|
||||
/// clicks on it within one frame need no memory.
|
||||
fn bin_double_clicked(ui: &egui::Ui, id: egui::Id, bin: Rect, here: bool) -> bool {
|
||||
use egui::{Event, PointerButton};
|
||||
if !here {
|
||||
return false;
|
||||
}
|
||||
let (time, clicked, double, releases) = ui.input(|i| {
|
||||
let releases = i
|
||||
.events
|
||||
.iter()
|
||||
.filter(|e| matches!(e, Event::PointerButton { button: PointerButton::Primary, pressed: false, pos, .. } if bin.contains(*pos)))
|
||||
.count();
|
||||
(i.time, i.pointer.button_clicked(PointerButton::Primary), i.pointer.button_double_clicked(PointerButton::Primary), releases)
|
||||
});
|
||||
if !clicked {
|
||||
return false;
|
||||
}
|
||||
let delay = ui.ctx().options(|o| o.input_options.max_double_click_delay);
|
||||
let id = id.with("last click");
|
||||
let last = ui.data_mut(|d| {
|
||||
let last = d.get_temp::<f64>(id);
|
||||
d.insert_temp(id, time);
|
||||
last
|
||||
});
|
||||
let last = last.unwrap_or(f64::NEG_INFINITY);
|
||||
double && (releases >= 2 || time - last < delay)
|
||||
}
|
||||
|
||||
/// Layer markers on a layer's row `r`; on a precomp layer, its comp's markers too (read-only,
|
||||
/// outlined: hover names them, a double-click opens the nested comp at the marker).
|
||||
pub(crate) fn layer_markers(app: &mut EffectcraftApp, ui: &mut egui::Ui, clip: Rect, comp: &Comp, layer: &Layer, tm: TMap, r: Rect) {
|
||||
|
||||
@@ -431,6 +431,18 @@ fn double_clicking_the_marker_bin_adds_a_comp_marker_at_the_current_time() {
|
||||
h.step();
|
||||
h.run_steps(3);
|
||||
assert_eq!(markers(&h), vec![21.5, 22.0], "a double-click released while the bin is dragged");
|
||||
// A click on the ruler right beside the bin and then one on the bin, in one frame: egui
|
||||
// takes them for a double-click (they are a few points apart), but only one was on the bin.
|
||||
let (beside, on) = (pos2(bin.min.x - 2.0, bin.center().y), pos2(bin.min.x + 2.0, bin.center().y));
|
||||
assert!(ruler.contains(beside) && !bin.contains(beside) && bin.contains(on));
|
||||
h.event(Event::PointerMoved(beside));
|
||||
h.step();
|
||||
for (pos, pressed) in [(beside, true), (beside, false), (on, true), (on, false)] {
|
||||
h.input_mut().events.push(Event::PointerButton { pos, button: egui::PointerButton::Primary, pressed, modifiers: Modifiers::NONE });
|
||||
}
|
||||
h.step();
|
||||
h.run_steps(3);
|
||||
assert_eq!(markers(&h), vec![21.5, 22.0], "one click beside the bin and one on it");
|
||||
// Dragged out 3 s into the visible span (from 10 s at 200 px/s): a marker at 13 s too.
|
||||
drag(&mut h, bin.center(), pos2(ruler.min.x + 6.0 + 600.0, ruler.center().y));
|
||||
assert_eq!(markers(&h), vec![13.0, 21.5, 22.0]);
|
||||
|
||||
Reference in new issue
Block a user