mirror of
https://github.com/storytold/gridcraft.git
synced 2026-10-26 11:46:49 -06:00
The corner drag now grabs the chart where the press began and the selected object's corner shows a resize cursor. The Format Chart Area Size fields, chart and axis title fields and the Table Name field reloaded their value from the workbook every frame, so typed or dragged edits were thrown away; they now keep a draft until the field loses focus (Escape cancels, like sheet tab rename).
82 lines
3.3 KiB
Rust
82 lines
3.3 KiB
Rust
//! Text fields over workbook values (chart titles, table name) keep what the user types until they commit it.
|
|
|
|
use egui::{Event, Key, Modifiers, accesskit::Role, vec2};
|
|
use egui_kittest::kittest::Queryable as _;
|
|
use gridcraft_engine::Session;
|
|
use gridcraft_ui_egui::SheetApp;
|
|
use serde_json::json;
|
|
|
|
type Harness = egui_kittest::Harness<'static, SheetApp>;
|
|
|
|
fn harness(session: Session) -> Harness {
|
|
let mut h = egui_kittest::Harness::builder().with_size(vec2(1200.0, 800.0)).build_ui_state(
|
|
|ui, app: &mut SheetApp| {
|
|
let ctx = ui.ctx().clone();
|
|
app.logic(&ctx);
|
|
app.ui(ui);
|
|
},
|
|
SheetApp::new(session, Default::default()),
|
|
);
|
|
h.run_steps(4);
|
|
h
|
|
}
|
|
|
|
fn session() -> Session {
|
|
let mut session = Session::new();
|
|
session.new_workbook();
|
|
session.execute("range.setValues", json!({"range": "A1", "values": [["Name", "Qty"], ["a", 1], ["b", 2]]})).unwrap();
|
|
session
|
|
}
|
|
|
|
/// Clicks the field, replaces its text with `text` and presses Enter.
|
|
fn retype(h: &mut Harness, field: egui::Rect, text: &str) {
|
|
h.input_mut().events.push(Event::PointerMoved(field.center()));
|
|
h.run_steps(1);
|
|
h.get_all_by_role(Role::TextInput).find(|n| n.rect() == field).unwrap().click();
|
|
h.run_steps(2);
|
|
h.key_press_modifiers(Modifiers::COMMAND, Key::A);
|
|
h.run_steps(1);
|
|
// One keystroke per frame, as a person types: each must survive the next frame.
|
|
for c in text.chars() {
|
|
h.input_mut().events.push(Event::Text(c.to_string()));
|
|
h.run_steps(2);
|
|
}
|
|
h.key_press(Key::Enter);
|
|
h.run_steps(2);
|
|
}
|
|
|
|
#[test]
|
|
fn typing_a_chart_title_in_format_chart_area_sets_it() {
|
|
let mut session = session();
|
|
session.execute("selection.set", json!({"range": "A1:B3"})).unwrap();
|
|
let chart = session.execute("insert.chart", json!({"type": "column", "at": "D3"})).unwrap();
|
|
let id = chart["chart"].as_u64().unwrap() as u32;
|
|
let mut h = harness(session);
|
|
h.state_mut().selected_chart = Some(id);
|
|
h.state_mut().grid.pane = Some("formatChart".into());
|
|
h.run_steps(2);
|
|
h.get_by_role_and_label(Role::Button, "Chart Title").click();
|
|
h.run_steps(2);
|
|
// The pane sits on the right; the formula bar and name box are further left.
|
|
let field = h.get_all_by_role(Role::TextInput).map(|n| n.rect()).find(|r| r.left() > 850.0).unwrap();
|
|
retype(&mut h, field, "Sales");
|
|
let title = h.state().session.active().unwrap().wb.active().unwrap().charts.iter().find(|c| c.id == id).unwrap().title.clone();
|
|
assert_eq!(title.as_deref(), Some("Sales"));
|
|
}
|
|
|
|
#[test]
|
|
fn typing_a_table_name_on_the_table_design_tab_renames_the_table() {
|
|
let mut session = session();
|
|
session.execute("insert.table", json!({"range": "A1:B3", "header": true})).unwrap();
|
|
session.execute("selection.set", json!({"range": "A2"})).unwrap();
|
|
let mut h = harness(session);
|
|
h.state_mut().ui.ribbon_tab = "Table Design".into();
|
|
h.run_steps(2);
|
|
let label = h.get_by_label("Table Name:").rect();
|
|
let below_label = |r: &egui::Rect| r.top() >= label.bottom() - 2.0 && (r.left() - label.left()).abs() < 20.0;
|
|
let field = h.get_all_by_role(Role::TextInput).map(|n| n.rect()).find(below_label).unwrap();
|
|
retype(&mut h, field, "Sales");
|
|
let name = h.state().session.active().unwrap().wb.active().unwrap().tables[0].name.clone();
|
|
assert_eq!(name, "Sales");
|
|
}
|