mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-07 14:33:34 +00:00
Merge pull request #5837 from mockydevs/fix/move-cursor-5246
Dialogs: the header that moves a dialog keeps the arrow cursor until dragged (#5246)
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
//! The modal dialog window: a backdrop that keeps the rest of the app from taking clicks, and a
|
||||
//! window with no title bar that opens centred and moves by dragging its heading (the band from its
|
||||
//! top edge down to the heading), as a title bar would. Where it was moved to stays, per window, for
|
||||
//! the session, and the window never leaves the screen. Rows too many for the screen's height
|
||||
//! scroll inside it ([`scrolled_rows`]), so its heading and buttons stay in view.
|
||||
//! top edge down to the heading), as a title bar would, showing the arrow until it is dragged. Where
|
||||
//! it was moved to stays, per window, for the session, and the window never leaves the screen. Rows
|
||||
//! too many for the screen's height scroll inside it ([`scrolled_rows`]), so its heading and buttons
|
||||
//! stay in view.
|
||||
|
||||
use egui::{Id, Rect, Vec2};
|
||||
|
||||
@@ -60,10 +61,10 @@ pub(crate) fn drag_band(ui: &mut egui::Ui, bottom: f32) {
|
||||
let band = Rect::from_x_y_ranges(outer.x_range(), outer.top()..=bottom.max(outer.top()));
|
||||
// Not focusable (`Sense::drag()` is): Tab goes through the dialog's controls, not the band.
|
||||
let r = ui.interact(band, handle(id), egui::Sense::DRAG);
|
||||
// Hovered, it keeps the arrow, as a title bar does (the grab cursor is Windows' four-way move
|
||||
// arrows: #5246); only while it is dragged does it show the window being carried.
|
||||
if r.dragged() {
|
||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Grabbing);
|
||||
} else if r.hovered() {
|
||||
ui.ctx().set_cursor_icon(egui::CursorIcon::Grab);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,31 @@ fn dialogs_move_by_their_heading_stay_on_screen_and_where_they_were_moved() {
|
||||
}
|
||||
}
|
||||
|
||||
/// #5246: the band that moves a dialog keeps the arrow when hovered, as a title bar does (the grab
|
||||
/// cursor is the four-way move arrows on Windows); it shows the window held only while dragged.
|
||||
#[test]
|
||||
fn the_band_that_moves_a_dialog_keeps_the_arrow_until_dragged() {
|
||||
let opens: [(&str, Open, egui::Id); 2] = [
|
||||
("Offset Path", |app| crate::menus::invoke(app, "object.path.offsetPath", json!({})), egui::Id::unique(("dialog", "offsetPath"))),
|
||||
("New Document", open_new_document, egui::Id::unique(("dialog", "newDocument"))),
|
||||
];
|
||||
for (name, open, id) in opens {
|
||||
let (ctx, mut app) = (ctx(), app_with_selection());
|
||||
open(&mut app);
|
||||
settle(&ctx, &mut app);
|
||||
let at = rect_of(&ctx, id).left_top() + vec2(40.0, 6.0);
|
||||
let cursor = |ctx: &egui::Context, app: &mut VectorcraftApp, events: Vec<Event>| {
|
||||
let input = egui::RawInput { screen_rect: Some(Rect::from_min_size(Pos2::ZERO, SCREEN)), events, ..Default::default() };
|
||||
ctx.run_ui(input, |ui| show(app, ui.ctx())).platform_output.cursor_icon
|
||||
};
|
||||
cursor(&ctx, &mut app, vec![Event::PointerMoved(at)]);
|
||||
assert_eq!(cursor(&ctx, &mut app, vec![]), egui::CursorIcon::Default, "{name}: hovering the band");
|
||||
cursor(&ctx, &mut app, vec![button(at, true)]);
|
||||
assert_eq!(cursor(&ctx, &mut app, vec![Event::PointerMoved(at + vec2(20.0, 10.0))]), egui::CursorIcon::Grabbing, "{name}: dragging it");
|
||||
cursor(&ctx, &mut app, vec![button(at + vec2(20.0, 10.0), false)]);
|
||||
}
|
||||
}
|
||||
|
||||
/// Tab goes through a dialog's controls and does not stop on the band that moves the window.
|
||||
#[test]
|
||||
fn tab_skips_the_band_that_moves_a_dialog() {
|
||||
|
||||
Reference in New Issue
Block a user