mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-09 09:29:44 -06:00
Type: discard queued font wheel turns after text selection changes
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
//! filters as the remaining families. In the Character and Properties panels and the Control bar,
|
||||
//! the mouse wheel turned over the closed field applies the next family (or previous one) to the
|
||||
//! selected text, one undo step per notch. The menu's order at the first turn stays fixed until the
|
||||
//! pointer leaves the field; steps stop at its first and last family.
|
||||
//! pointer leaves the field or the text selection changes; steps stop at its first and last family.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -287,7 +287,7 @@ struct MenuState {
|
||||
/// The height of the search field and filters last frame.
|
||||
header: f32,
|
||||
/// The families the wheel steps through, listed at its first notch over the closed field and
|
||||
/// kept while the pointer stays on it: each step makes its family a recent one, which would
|
||||
/// kept for that text selection while the pointer stays on it: each step makes its family a recent one, which would
|
||||
/// otherwise move it in the order.
|
||||
wheel_order: Option<Arc<[String]>>,
|
||||
wheel_target: Option<WheelTarget>,
|
||||
@@ -451,15 +451,22 @@ fn wheel_fields_id(viewport: egui::ViewportId) -> egui::Id {
|
||||
egui::Id::unique("font-wheel-fields").with(viewport)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[derive(Clone, PartialEq)]
|
||||
struct WheelTarget {
|
||||
input: crate::state::InputGeneration,
|
||||
workspace: u64,
|
||||
selection: Vec<vectorcraft_doc::NodeId>,
|
||||
range: Option<(vectorcraft_doc::NodeId, usize, usize)>,
|
||||
}
|
||||
|
||||
/// Pending turns and field rectangles belong to their input target and visible workspace.
|
||||
pub(crate) fn sync_wheel_target(app: &VectorcraftApp, ctx: &egui::Context, viewport: egui::ViewportId) {
|
||||
let target = WheelTarget { input: app.input_generation(), workspace: app.ui.docking_generation };
|
||||
let target = WheelTarget {
|
||||
input: app.input_generation(),
|
||||
workspace: app.ui.docking_generation,
|
||||
selection: app.session.active().map_or_else(Vec::new, |document| document.selection.objects.clone()),
|
||||
range: crate::panels::character::text_editing(app),
|
||||
};
|
||||
let key = wheel_fields_id(viewport);
|
||||
let (previous, mut fields) = ctx.data(|d| (d.get_temp::<WheelTarget>(key.with("target")), d.get_temp::<WheelFields>(key)));
|
||||
if previous.is_some_and(|old| old != target) {
|
||||
|
||||
@@ -22,6 +22,44 @@ fn deselecting_type_leaves_the_missing_control_fields_wheel_available() {
|
||||
assert!(control_wheel_available_after("select.set", json!({"ids": []})));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_queued_font_wheel_does_not_restyle_a_new_object_selection() {
|
||||
assert_queued_wheel_discarded_after_target_change(false);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_queued_font_wheel_does_not_restyle_a_new_character_range() {
|
||||
assert_queued_wheel_discarded_after_target_change(true);
|
||||
}
|
||||
|
||||
fn assert_queued_wheel_discarded_after_target_change(range: bool) {
|
||||
let (ctx, mut app) = selected_type_with_control();
|
||||
let first = app.session.active().unwrap().selection.objects.first().unwrap().0;
|
||||
let second = app.run("text.create", json!({"x": 30, "y": 120, "text": "Other text", "font": "Inter"})).unwrap()["id"].clone();
|
||||
app.run("select.set", json!({"ids": [first]})).unwrap();
|
||||
if range {
|
||||
app.select_tool("type");
|
||||
app.session.set_tool_option("textSelection", &json!({"editing": first, "anchor": 0, "caret": 2}));
|
||||
}
|
||||
let mut texts = Vec::new();
|
||||
for _ in 0..8 {
|
||||
texts = frame(&mut app, &ctx, vec![]);
|
||||
}
|
||||
let point = texts.iter().find(|(t, p)| t == "Inter" && p.y < 150.0).unwrap().1;
|
||||
let mut raw = wheel_input(point);
|
||||
app.raw_input_hook(&ctx, &mut raw);
|
||||
assert!(!raw.events.iter().any(|e| matches!(e, Event::MouseWheel { .. })), "the original field captured its turn");
|
||||
if range {
|
||||
app.session.set_tool_option("textSelection", &json!({"editing": first, "anchor": 2, "caret": 4}));
|
||||
} else {
|
||||
app.run("select.set", json!({"ids": [second]})).unwrap();
|
||||
}
|
||||
let before = app.session.active().unwrap().history.undo.len();
|
||||
let mut out = ctx.run_ui(raw, |ui| app.ui(ui));
|
||||
out.textures_delta.clear();
|
||||
assert_eq!(app.session.active().unwrap().history.undo.len(), before, "the captured turn cannot restyle the new target");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn artboard_controls_leave_replaced_font_fields_wheel_available() {
|
||||
let (ctx, mut app) = selected_type_with_control();
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user