mirror of
https://github.com/storytold/cadcraft.git
synced 2026-10-25 11:26:46 -06:00
79 lines
3.1 KiB
Rust
79 lines
3.1 KiB
Rust
//! Double-clicking text with no command running edits it, as in AutoCAD (#842).
|
|
|
|
use cadcraft_engine::doc::EntityKind;
|
|
use cadcraft_engine::geom::Vec2;
|
|
use cadcraft_engine::{Input, Session};
|
|
use cadcraft_ui_egui::{CadApp, Services};
|
|
use egui::{Event, Modifiers, PointerButton, Pos2, vec2};
|
|
use egui_kittest::Harness;
|
|
use serde_json::json;
|
|
|
|
fn harness() -> Harness<'static, CadApp> {
|
|
let mut app = CadApp::new(Session::new(), Services::default());
|
|
app.run("text", json!({ "at": [0, 0], "text": "HELLO", "height": 2.5 })).unwrap();
|
|
app.run("mtext", json!({ "at": [0, 20], "text": "first\\Psecond", "height": 2.5, "width": 20 })).unwrap();
|
|
app.run("line", json!({ "points": [[30, 0], [30, 20]] })).unwrap();
|
|
app.session.execute("view.set", &json!({ "center": [15, 10], "height": 40 })).unwrap();
|
|
app.canvas.zoom_pending = false;
|
|
// 60 frames a second: the default step (0.25 s) spreads two clicks past the double-click delay.
|
|
let mut h = Harness::builder().with_size(vec2(1600.0, 1000.0)).with_step_dt(1.0 / 60.0).build_ui_state(
|
|
|ui, app: &mut CadApp| {
|
|
app.logic(ui.ctx());
|
|
app.ui(ui);
|
|
},
|
|
app,
|
|
);
|
|
h.run_steps(5);
|
|
h
|
|
}
|
|
|
|
fn double_click(h: &mut Harness<'_, CadApp>, at: Vec2) {
|
|
let pos: Pos2 = h.state().canvas.xf.unwrap().to_screen(at);
|
|
h.event(Event::PointerMoved(pos));
|
|
h.run_steps(2);
|
|
for _ in 0..2 {
|
|
for pressed in [true, false] {
|
|
h.event(Event::PointerButton { pos, button: PointerButton::Primary, pressed, modifiers: Modifiers::NONE });
|
|
h.run_steps(1);
|
|
}
|
|
}
|
|
h.run_steps(2);
|
|
}
|
|
|
|
fn text_at(h: &Harness<'_, CadApp>, i: usize) -> String {
|
|
let d = h.state().session.doc().unwrap();
|
|
let e = d.model.iter().nth(i).unwrap();
|
|
match &e.kind {
|
|
EntityKind::Text(t) => t.value.clone(),
|
|
EntityKind::MText(t) => t.contents.clone(),
|
|
k => panic!("not text: {}", k.type_name()),
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn double_click_on_text_starts_textedit_for_that_object() {
|
|
for (i, at, old, new) in [(0, Vec2::new(4.0, 1.2), "HELLO", "HELLO WORLD"), (1, Vec2::new(3.0, 18.8), "first\nsecond", "edited")] {
|
|
let mut h = harness();
|
|
double_click(&mut h, at);
|
|
let s = &h.state().session;
|
|
assert_eq!(s.running.as_ref().map(|r| r.id.as_str()), Some("textedit"), "object {i}");
|
|
let p = s.current_prompt().unwrap();
|
|
assert_eq!(p.message, "Enter new text", "object {i}: the clicked text is already picked");
|
|
assert_eq!(p.default.as_deref(), Some(old), "object {i}");
|
|
h.state_mut().session.input(Input::Text(new.into())).unwrap();
|
|
h.run_steps(2);
|
|
assert_eq!(text_at(&h, i), new);
|
|
// TEXTEDIT goes on asking for objects (its Multiple mode), as AutoCAD's does.
|
|
assert_eq!(h.state().session.current_prompt().unwrap().message, "Select an annotation object");
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn double_click_elsewhere_starts_no_command() {
|
|
for at in [Vec2::new(30.0, 5.0), Vec2::new(15.0, 30.0)] {
|
|
let mut h = harness();
|
|
double_click(&mut h, at);
|
|
assert_eq!(h.state().session.running.as_ref().map(|r| r.id.as_str()), None, "{at:?}");
|
|
}
|
|
}
|