Merge pull request #679 from marcoarnulfo:fix/validation-tooltip-list

This commit is contained in:
Brandon Thomas 2026-10-12 23:48:44 -04:00
commit 1d4806ff70
2 changed files with 58 additions and 1 deletions

View File

@ -2722,8 +2722,9 @@ pub(crate) fn paint_overlays(
p.rect_stroke(r, 2.0, Stroke::new(1.0, Color32::from_gray(160)), StrokeKind::Inside);
crate::icons::paint(p, r.shrink(3.0), crate::icons::Icon::Chevron, Color32::from_gray(60));
}
// Input message of the active cell's validation.
// Input message of the active cell's validation, hidden while its list is open: it would cover the items.
if app.editor.is_none()
&& app.grid.list_picker != Some(sel.active)
&& let Some(dv) = sh.validations.iter().find(|d| d.ranges.iter().any(|r| r.contains(sel.active)))
&& dv.show_input
&& !(dv.input_title.is_empty() && dv.input_message.is_empty())

View File

@ -0,0 +1,56 @@
//! A list validation's input message must not cover the dropdown it describes (#505).
use egui::{Event, Key, Modifiers, PointerButton};
use egui_kittest::kittest::Queryable;
use gridcraft_engine::Session;
use gridcraft_engine::core::CellRef;
use gridcraft_ui_egui::{SheetApp, grid};
use serde_json::json;
type Harness = egui_kittest::Harness<'static, SheetApp>;
const MESSAGE: &str = "Pick a colour from the list";
fn harness() -> Harness {
let mut session = Session::new();
session.new_workbook();
session.execute("data.validation", json!({"range": "B2", "type": "list", "formula1": "\"Red,Green,Blue\"", "inputMessage": MESSAGE})).unwrap();
session.execute("selection.set", json!({"cell": "B2"})).unwrap();
let mut h = egui_kittest::Harness::builder().with_size(egui::vec2(1200.0, 800.0)).build_ui_state(
|ui, app: &mut SheetApp| {
app.logic(ui.ctx());
app.ui(ui);
},
SheetApp::new(session, Default::default()),
);
h.run_steps(4);
h
}
fn message_shown(h: &Harness) -> bool {
h.query_by_label(MESSAGE).is_some()
}
#[test]
fn input_message_hides_while_the_list_is_open() {
let mut h = harness();
assert!(message_shown(&h), "the selected cell's input message is shown");
let app = h.state();
let sh = app.session.active().unwrap().wb.active().unwrap();
let geo = grid::Geo::new(sh, app.grid.rect.unwrap(), app.view().scroll);
let pos = grid::validation_arrow(sh, &geo, CellRef::parse("B2").unwrap()).unwrap().center();
h.input_mut().events.push(Event::PointerMoved(pos));
h.input_mut().events.push(Event::PointerButton { pos, button: PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
h.input_mut().events.push(Event::PointerButton { pos, button: PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });
h.run_steps(2);
assert!(h.state().grid.list_picker.is_some(), "the dropdown arrow opens the list");
assert!(h.query_by_label("Green").is_some(), "the list shows its items");
assert!(!message_shown(&h), "the input message must not cover the open list");
h.input_mut().events.push(Event::Key { key: Key::Escape, physical_key: None, pressed: true, repeat: false, modifiers: Modifiers::NONE });
h.run_steps(2);
assert!(h.state().grid.list_picker.is_none(), "Escape closes the list");
assert!(message_shown(&h), "the input message comes back once the list is closed");
}