mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 15:27:02 +00:00
Keep font wheel events with their overlay target
This commit is contained in:
@@ -452,6 +452,13 @@ struct QueuedWheel {
|
||||
positions_after: Vec<egui::Pos2>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ReplayWheel {
|
||||
target: egui::LayerId,
|
||||
position: egui::Pos2,
|
||||
event: egui::Event,
|
||||
}
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
struct WheelFields {
|
||||
pass: u64,
|
||||
@@ -462,7 +469,7 @@ struct WheelFields {
|
||||
fields: Vec<WheelField>,
|
||||
pending: HashMap<egui::Id, Vec<WheelInput>>,
|
||||
queued: Vec<QueuedWheel>,
|
||||
replay: Vec<egui::Event>,
|
||||
replay: Vec<ReplayWheel>,
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
@@ -505,8 +512,9 @@ impl egui::Plugin for WheelLayerSnapshot {
|
||||
let id = event.field.with("wheel");
|
||||
if !active {
|
||||
ctx.data_mut(|d| d.remove::<f32>(id));
|
||||
fields.replay.push(egui::Event::PointerMoved(event.position));
|
||||
fields.replay.push(event.event);
|
||||
if let Some(target) = ctx.layer_id_at(event.position) {
|
||||
fields.replay.push(ReplayWheel { target, position: event.position, event: event.event });
|
||||
}
|
||||
} else {
|
||||
let notches = ctx.data(|d| d.get_temp::<f32>(id)).unwrap_or(0.0) + event.amount;
|
||||
let whole = notches.trunc();
|
||||
@@ -521,7 +529,6 @@ impl egui::Plugin for WheelLayerSnapshot {
|
||||
}
|
||||
}
|
||||
if fields.replay.len() > replayed {
|
||||
fields.replay.push(fields.pointer.map_or(egui::Event::PointerGone, egui::Event::PointerMoved));
|
||||
ctx.request_repaint();
|
||||
}
|
||||
ctx.data_mut(|d| d.insert_temp(key, fields));
|
||||
@@ -796,7 +803,21 @@ pub(crate) fn take_raw_wheel(ctx: &egui::Context, raw: &mut egui::RawInput) {
|
||||
true
|
||||
});
|
||||
if !fields.replay.is_empty() {
|
||||
raw.events.splice(0..0, std::mem::take(&mut fields.replay));
|
||||
let mut replay = Vec::new();
|
||||
for wheel in std::mem::take(&mut fields.replay) {
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
let target_still_visible = native_layers.as_ref().is_some_and(|layers| (layers.0)(wheel.position) == Some(wheel.target));
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
let target_still_visible = false;
|
||||
if target_still_visible {
|
||||
replay.push(egui::Event::PointerMoved(wheel.position));
|
||||
replay.push(wheel.event);
|
||||
}
|
||||
}
|
||||
if !replay.is_empty() {
|
||||
replay.push(pointer.map_or(egui::Event::PointerGone, egui::Event::PointerMoved));
|
||||
raw.events.splice(0..0, replay);
|
||||
}
|
||||
}
|
||||
fields.pointer = pointer;
|
||||
ctx.data_mut(|d| d.insert_temp(key, fields));
|
||||
|
||||
@@ -785,6 +785,49 @@ fn an_overlay_raised_with_the_wheel_event_does_not_change_the_font() {
|
||||
assert_eq!(h.app.run("text.fonts", json!({})).unwrap(), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_closed_overlay_does_not_replay_its_wheel_into_the_panel() {
|
||||
let mut h = Harness::new();
|
||||
h.app.run("text.create", json!({"x": 30, "y": 50, "text": "Hi", "font": "Source Sans 3"})).unwrap();
|
||||
let viewport = h.float("character");
|
||||
let field = h
|
||||
.host
|
||||
.borrow()
|
||||
.windows
|
||||
.get(&viewport)
|
||||
.and_then(|w| w.texts.iter().find(|(text, _)| text == "Source Sans 3").map(|(_, rect)| *rect))
|
||||
.expect("the Character panel's font family field");
|
||||
let pointer = pos2(field.min.x + 4.0, field.center().y);
|
||||
h.host.borrow_mut().child_raise_overlay = Some((viewport, field.expand(10.0), false));
|
||||
h.frames(2);
|
||||
let field_layer = crate::font_menu::wheel_field_layer_for_test(&h.ctx, viewport, pointer).expect("the font field layer");
|
||||
h.host.borrow_mut().child_raise_layer = Some((viewport, field_layer));
|
||||
h.frame(vec![]);
|
||||
h.host.borrow_mut().child_raise_layer = None;
|
||||
h.frame(vec![]);
|
||||
let before = h.app.run("text.fonts", json!({})).unwrap();
|
||||
h.host.borrow_mut().child_raise_overlay = Some((viewport, field.expand(10.0), true));
|
||||
h.host.borrow_mut().windows.get_mut(&viewport).unwrap().events.extend([
|
||||
Event::PointerMoved(pointer),
|
||||
Event::MouseWheel {
|
||||
unit: egui::MouseWheelUnit::Line,
|
||||
delta: vec2(0.0, -1.0),
|
||||
phase: egui::TouchPhase::Move,
|
||||
modifiers: Default::default(),
|
||||
source: egui::MouseWheelSource::Unknown,
|
||||
},
|
||||
]);
|
||||
h.frame(vec![]);
|
||||
h.host.borrow_mut().child_raise_overlay = None;
|
||||
h.frame(vec![]);
|
||||
h.frame(vec![]);
|
||||
assert!(
|
||||
!h.ctx.input_for(viewport, |input| input.raw.events.iter().any(|event| matches!(event, Event::MouseWheel { .. }))),
|
||||
"a closed overlay cannot receive a later wheel event"
|
||||
);
|
||||
assert_eq!(h.app.run("text.fonts", json!({})).unwrap(), before);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn wheel_events_on_both_sides_of_an_overlay_are_checked_separately() {
|
||||
let mut h = Harness::new();
|
||||
|
||||
Reference in New Issue
Block a user