mirror of
https://github.com/storytold/lightcraft.git
synced 2026-10-29 04:27:30 -06:00
LRC-LIB-KEYWORDS: drops land only on what is shown
The Keyword List took a drop wherever the pointer was inside a row's or the title's rectangle, even where the panel had scrolled it out of sight: a keyword released over the app's top bar, where the list's title was hidden, went to the top level. Drops now need the pointer on the visible part of the panel too; photos dropped from the grid alike. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
199e33043f
commit
5d4ebe5132
@@ -25,7 +25,7 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
||||
register(ui.ctx(), "keywordList:topLevel", title);
|
||||
let dragging = app.ui.dragging_keyword.clone();
|
||||
let (pointer, released) = ui.input(|i| (i.pointer.latest_pos(), i.pointer.any_released()));
|
||||
let over_title = pointer.is_some_and(|p| title.contains(p));
|
||||
let over_title = shown_under(ui, title, pointer);
|
||||
if dragging.is_some() && over_title {
|
||||
ui.painter().rect_stroke(title.shrink2(vec2(16.0, 6.0)), 4.0, Stroke::new(1.5, t.accent), StrokeKind::Inside);
|
||||
}
|
||||
@@ -89,6 +89,12 @@ pub fn show(app: &mut LightcraftApp, ui: &mut egui::Ui) {
|
||||
}
|
||||
}
|
||||
|
||||
/// The pointer is on the part of `rect` that is shown: inside it and inside the panel's visible
|
||||
/// (scrolled) area, so a drop never lands on a row or title hidden under the top bar.
|
||||
fn shown_under(ui: &egui::Ui, rect: Rect, pointer: Option<egui::Pos2>) -> bool {
|
||||
pointer.is_some_and(|p| rect.contains(p) && ui.clip_rect().contains(p))
|
||||
}
|
||||
|
||||
/// The dragged keyword's name, following the pointer.
|
||||
fn drag_label(ctx: &egui::Context, keyword: &str, at: egui::Pos2) {
|
||||
let t = Tokens::get(ctx);
|
||||
@@ -236,7 +242,7 @@ fn row(app: &mut LightcraftApp, ui: &mut egui::Ui, r: &Row, selection: &[PhotoId
|
||||
/// keyword inside this one, or gives this keyword to the photos.
|
||||
fn drop_target(app: &mut LightcraftApp, ui: &mut egui::Ui, rect: Rect, path: &str) {
|
||||
let (pointer, released) = ui.input(|i| (i.pointer.latest_pos(), i.pointer.any_released()));
|
||||
if !pointer.is_some_and(|p| rect.contains(p)) {
|
||||
if !shown_under(ui, rect, pointer) {
|
||||
return;
|
||||
}
|
||||
let t = Tokens::get(ui.ctx());
|
||||
|
||||
@@ -270,3 +270,26 @@ fn dropping_photos_on_a_keyword_tags_them() {
|
||||
assert!(ids.iter().all(|id| keywords_of(&h, *id).contains(&"Portugal".to_string())), "the selection got it");
|
||||
assert!(h.app.ui.dragging_photos.is_none());
|
||||
}
|
||||
|
||||
fn rect(h: &Headless, id: &str) -> egui::Rect {
|
||||
h.app.widgets.iter().rev().find(|(w, _)| w == id).map(|(_, r)| *r).unwrap_or_else(|| panic!("no {id}"))
|
||||
}
|
||||
|
||||
/// A drop lands only on what is shown: with the list scrolled so that its title is hidden under
|
||||
/// the top bar, a keyword released over the top bar stays where it is.
|
||||
#[test]
|
||||
fn drops_land_only_on_what_is_shown() {
|
||||
let (mut h, ids) = keywords_panel_at([1400.0, 640.0]);
|
||||
run(&mut h, "photo.setMeta", json!({"ids": [ids[0]], "keywords": ["aaa|zz"]}));
|
||||
ask(&mut h, "ui.clickWidget", json!({"id": "keywordRowToggle:aaa"}));
|
||||
let title = rect(&h, "keywordList:topLevel");
|
||||
ask(&mut h, "ui.hoverWidget", json!({"id": "keywordRow:aaa"}));
|
||||
ask(&mut h, "ui.scroll", json!({"dx": 0, "dy": -(title.top() - 20.0)}));
|
||||
let title = rect(&h, "keywordList:topLevel");
|
||||
let hidden = egui::pos2(title.center().x, title.top() + 8.0);
|
||||
assert!(hidden.y < 44.0 && title.contains(hidden), "the title's top is under the top bar: {title:?}");
|
||||
let row = rect(&h, "keywordRow:aaa|zz");
|
||||
assert!(row.top() > 44.0, "the row is shown: {row:?}");
|
||||
ask(&mut h, "ui.dragWidget", json!({"id": "keywordRow:aaa|zz", "toX": hidden.x, "toY": hidden.y, "steps": 12}));
|
||||
assert_eq!(keywords_of(&h, ids[0]), ["aaa|zz"], "not moved to the top level");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user