mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-25 10:51:07 +00:00
Merge PR #1914@2f88d847f into round3a-integration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -308,6 +308,8 @@ pub fn show(app: &mut LightcraftApp, ctx: &egui::Context) {
|
||||
let widest = if settings { ctx.data(|d| d.get_temp::<f32>(widest_id)).unwrap_or(0.0).min(screen.width() * 0.9) } else { 0.0 };
|
||||
let mut content_w = 0.0f32;
|
||||
let mut body_h = None;
|
||||
// before the window: drawing it closes a dropdown the click lands outside of
|
||||
let popup_was_open = egui::Popup::is_any_open(ctx);
|
||||
let shown = egui::Window::new(crate::i18n::tr(&title)).id(window_id)
|
||||
.collapsible(false)
|
||||
.resizable(import)
|
||||
@@ -1491,7 +1493,7 @@ pub fn show(app: &mut LightcraftApp, ctx: &egui::Context) {
|
||||
}
|
||||
if let Some(w) = &shown {
|
||||
// (the import review keeps its hand-picked photos however the click lands)
|
||||
if app.ui.settings.close_dialogs_outside && !import && clicked_backdrop(ctx, w.response.rect) {
|
||||
if app.ui.settings.close_dialogs_outside && !import && clicked_backdrop(ctx, w.response.rect, popup_was_open) {
|
||||
close = true;
|
||||
}
|
||||
}
|
||||
@@ -1595,11 +1597,12 @@ const BACKDROP_SHOWN: &str = "dialog-backdrop-shown";
|
||||
|
||||
/// A click on the dimmed backdrop around the dialog: it closes the dialog like Esc. Pressed and
|
||||
/// released outside the window, so a slider dragged past its edge doesn't close it; a press while a
|
||||
/// popup is open (a dropdown, a date picker's calendar) only closes the popup. Only a press made
|
||||
/// popup is open (a dropdown, a date picker's calendar) only closes the popup: `popup_was_open` is
|
||||
/// read before the window is drawn, since drawing it already closes the popup. Only a press made
|
||||
/// while the dialog is shown counts: in the frame a dialog appears, its input is the click that
|
||||
/// opened it (a quick click on a slow frame presses and releases in that one frame), so it never
|
||||
/// closes it. (Read from the raw events: egui forgets the press origin on release.)
|
||||
fn clicked_backdrop(ctx: &egui::Context, window: egui::Rect) -> bool {
|
||||
fn clicked_backdrop(ctx: &egui::Context, window: egui::Rect, popup_was_open: bool) -> bool {
|
||||
let press_id = egui::Id::new("dialog-backdrop-press");
|
||||
let frame = ctx.cumulative_frame_nr();
|
||||
// the same frame too: a second pass of it gets no input
|
||||
@@ -1618,7 +1621,7 @@ fn clicked_backdrop(ctx: &egui::Context, window: egui::Rect) -> bool {
|
||||
(at(true), at(false), i.pointer.primary_clicked())
|
||||
});
|
||||
if let Some(p) = press {
|
||||
let outside = !window.contains(p) && !egui::Popup::is_any_open(ctx);
|
||||
let outside = !window.contains(p) && !popup_was_open;
|
||||
ctx.data_mut(|d| d.insert_temp(press_id, outside));
|
||||
}
|
||||
let Some(release) = release else { return false };
|
||||
|
||||
@@ -128,6 +128,28 @@ fn a_click_outside_closes_the_dialog_when_settings_allow_it() {
|
||||
assert!(h.app.ui.dialog.is_none(), "the next click on the backdrop does");
|
||||
}
|
||||
|
||||
/// With a dropdown open in the dialog, a click on the backdrop only closes the dropdown, even when
|
||||
/// it arrives pressed and released in one frame (the dropdown closes while the dialog is drawn).
|
||||
#[test]
|
||||
fn a_click_outside_an_open_dropdown_keeps_the_dialog() {
|
||||
let mut h = demo([1400.0, 1000.0], json!({"view": "detail", "right": "edit"}));
|
||||
h.app.ui.settings.close_dialogs_outside = true;
|
||||
h.app.run("dialog.export", json!({})).unwrap();
|
||||
h.step();
|
||||
h.step();
|
||||
let r = h.request("ui.clickWidget", json!({"id": "combo:exportPreset"}), T);
|
||||
assert_eq!(r["ok"], true, "{r}");
|
||||
h.step();
|
||||
assert!(egui::Popup::is_any_open(&h.view.ctx), "the preset dropdown is open");
|
||||
let at = egui::pos2(10.0, 990.0);
|
||||
let press = |pressed| egui::Event::PointerButton { pos: at, button: egui::PointerButton::Primary, pressed, modifiers: egui::Modifiers::NONE };
|
||||
h.events.extend([egui::Event::PointerMoved(at), press(true), press(false)]);
|
||||
h.step();
|
||||
h.step();
|
||||
assert!(!egui::Popup::is_any_open(&h.view.ctx), "the click closes the dropdown");
|
||||
assert!(h.app.ui.dialog.is_some(), "but not the dialog");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn modal_dialogs_close_background_menus() {
|
||||
let mut h = demo([1400.0, 1000.0], json!({"view": "detail", "right": "edit"}));
|
||||
|
||||
Reference in New Issue
Block a user