mirror of
https://github.com/storytold/effectcraft.git
synced 2026-10-22 19:52:57 -05:00
ui-egui: a click that opens the colour picker no longer closes it in the same frame (#1476)
This commit is contained in:
1 parent
05955c08b4
commit
0f38f507ee
2 files changed
+38
-2
No files matched your search
@@ -45,7 +45,13 @@ pub fn color_popup(ui: &mut Ui, id: egui::Id, pos: egui::Pos2, c: &mut [f32; 3])
|
||||
if ui.input_mut(|i| i.consume_key(egui::Modifiers::NONE, egui::Key::Escape)) {
|
||||
out.close = Some(false);
|
||||
}
|
||||
if pressed_outside(ui.ctx(), &area.response) {
|
||||
// A press in the pass that first draws the picker must not close it: an Area's rect is only
|
||||
// at its requested position from its second pass on (the first pass reports it at the
|
||||
// origin), so the click that just opened the picker would be read as a press outside it and
|
||||
// the picker would flash and close in that one frame (#1476).
|
||||
let pass_id = id.with("open-pass");
|
||||
let drawn_before = ui.data(|d| d.get_temp::<u64>(pass_id)).is_some_and(|p| p < ui.ctx().cumulative_pass_nr());
|
||||
if drawn_before && pressed_outside(ui.ctx(), &area.response) {
|
||||
out.close.get_or_insert(true);
|
||||
}
|
||||
if let Some(keep) = out.close {
|
||||
@@ -56,13 +62,17 @@ pub fn color_popup(ui: &mut Ui, id: egui::Id, pos: egui::Pos2, c: &mut [f32; 3])
|
||||
ui.data_mut(|d| {
|
||||
d.insert_temp(id.with("open"), false);
|
||||
d.remove::<[f32; 3]>(orig_id);
|
||||
d.remove::<u64>(pass_id);
|
||||
// Closed: the next Escape is the dialog's again.
|
||||
d.remove::<u64>(open_pass_id());
|
||||
});
|
||||
} else {
|
||||
// Still open after this pass: dialogs leave Escape to the picker (see `open_recently`).
|
||||
let pass = ui.ctx().cumulative_pass_nr();
|
||||
ui.data_mut(|d| d.insert_temp(open_pass_id(), pass));
|
||||
ui.data_mut(|d| {
|
||||
d.insert_temp(pass_id, pass);
|
||||
d.insert_temp(open_pass_id(), pass);
|
||||
});
|
||||
}
|
||||
out.changed
|
||||
}
|
||||
|
||||
@@ -114,6 +114,32 @@ fn is_open(h: &Harness<'_, [f32; 3]>) -> bool {
|
||||
h.query_by_role_and_label(Role::TextInput, "#").is_some()
|
||||
}
|
||||
|
||||
/// #1476: the click that opens the picker must not close it. The picker's area only reports its
|
||||
/// real position from its second pass — on the pass it first draws, its rect is at the origin —
|
||||
/// so a click on a swatch outside that stale rect was read as a press outside the popup and the
|
||||
/// picker flashed and closed in the frame it opened.
|
||||
#[test]
|
||||
fn a_click_that_opens_the_picker_does_not_close_it_in_the_same_frame() {
|
||||
let mut h = Harness::builder().with_size(vec2(560.0, 400.0)).build_ui_state(
|
||||
|ui, c: &mut [f32; 3]| {
|
||||
// Away from the top-left corner: the stale first-pass rect covers it.
|
||||
ui.allocate_space(vec2(440.0, 120.0));
|
||||
ui.horizontal(|ui| {
|
||||
ui.add_space(440.0);
|
||||
widgets::srgb_color_button(ui, c);
|
||||
});
|
||||
},
|
||||
[1.0, 0.0, 0.0],
|
||||
);
|
||||
h.run_steps(2);
|
||||
let button = h.get_by_role(Role::ColorWell).rect().center();
|
||||
h.input_mut().events.push(Event::PointerMoved(button));
|
||||
h.input_mut().events.push(Event::PointerButton { pos: button, button: egui::PointerButton::Primary, pressed: true, modifiers: Modifiers::NONE });
|
||||
h.input_mut().events.push(Event::PointerButton { pos: button, button: egui::PointerButton::Primary, pressed: false, modifiers: Modifiers::NONE });
|
||||
h.run_steps(2);
|
||||
assert!(is_open(&h), "the click that opens the picker must not close it");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn the_dialog_colour_button_stores_srgb() {
|
||||
let mut h = picker([1.0, 1.0, 1.0]);
|
||||
|
||||
Reference in new issue
Block a user