| author | |
| committer | |
| log | 5e10e17cd5f73270850258fba1ea45a4b203de7d |
| tree | 024366bcd779a0cdc94645ec55a9c5fbad0ecc5b |
| parent | 7a0b2662303af3d08687c1a26ff0cf6555c56723 |
| signature | Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU |
As a double click on the tab does, rather than opening the sidebar on the
section's row. A menu counts as the tab's when it opened over the tab row.
Assisted-by: claude-opus-5.52 files changed, 37 insertions(+), 6 deletions(-)
crates/snowbound/src/menus.rs+29-1| ... | ... | @@ -376,12 +376,40 @@ impl State { |
| 376 | 376 | } |
| 377 | 377 | (Some(action), _) => { |
| 378 | 378 | self.menu = None; |
| 379 | self.act_on(target, action); | |
| 379 | match target { | |
| 380 | // From its tab, as a double click there renames it. | |
| 381 | Target::Section { library, path } | |
| 382 | if action == Action::Rename && self.on_tab(&library, &path, point) => | |
| 383 | { | |
| 384 | self.rename(crate::rename::Target::Entry { | |
| 385 | library, | |
| 386 | path, | |
| 387 | in_tab: true, | |
| 388 | }); | |
| 389 | } | |
| 390 | target => self.act_on(target, action), | |
| 391 | } | |
| 380 | 392 | } |
| 381 | 393 | (None, _) => {} |
| 382 | 394 | } |
| 383 | 395 | } |
| 384 | 396 | |
| 397 | /// Whether `point`, where a context menu opened, is on the tab of section `path`. | |
| 398 | fn on_tab(&self, library: &Arc<Library>, path: &str, point: [f32; 2]) -> bool { | |
| 399 | let shown = self.session.as_ref().is_some_and(|session| { | |
| 400 | Arc::ptr_eq(&session.library, library) | |
| 401 | && session.tabs.iter().any(|tab| tab.path == path) | |
| 402 | }); | |
| 403 | let [x, y] = point; | |
| 404 | shown | |
| 405 | && self | |
| 406 | .ui | |
| 407 | .rect(crate::sections()) | |
| 408 | .is_some_and(|[left, top, right, bottom]| { | |
| 409 | x >= left && x < right && y >= top && y < bottom | |
| 410 | }) | |
| 411 | } | |
| 412 | ||
| 385 | 413 | /// What can be done to `target`, in its context menu's order, as each shows there. |
| 386 | 414 | pub(crate) fn actions(&self, target: &Target) -> Vec<(Action, Item<'static>)> { |
| 387 | 415 | // An action, its label, whether it is disabled, and whether a rule starts its group. |
crates/snowbound/tests/replay.rs+8-5| ... | ... | @@ -564,23 +564,26 @@ fn a_version_copied_into_its_section_is_listed_and_found() { |
| 564 | 564 | assert!(!search_results(&found).is_empty(), "{found}"); |
| 565 | 565 | } |
| 566 | 566 | |
| 567 | /// Rename on a section tab's menu opens the shut sidebar on a field that takes what is | |
| 568 | /// typed over the old name at once. | |
| 567 | /// Rename on a section tab's menu opens the field on the tab, as a double click there does, | |
| 568 | /// which takes what is typed over the old name at once; the shut sidebar stays shut. | |
| 569 | 569 | #[test] |
| 570 | fn renaming_a_section_from_its_tab_types_into_the_sidebar_at_once() { | |
| 571 | let scratch = Scratch::new("rename-shut-sidebar"); | |
| 570 | fn renaming_a_section_from_its_tab_types_into_the_tab_at_once() { | |
| 571 | let scratch = Scratch::new("rename-tab"); | |
| 572 | 572 | let notebook = |
| 573 | 573 | Path::new(env!("CARGO_MANIFEST_DIR")).join("../../corpus/cross-container/candidate"); |
| 574 | 574 | let mut steps = vec!["move 110 53", "press right", "release right", "settle"]; |
| 575 | 575 | steps.extend(["key Down", "key Enter", "settle"]); |
| 576 | 576 | steps.extend(["type Renamed", "accessibility typed"]); |
| 577 | let [typed] = replay(&scratch, Some(&notebook), &steps) | |
| 577 | steps.extend(["key Enter", "settle", "accessibility renamed"]); | |
| 578 | let [typed, renamed] = replay(&scratch, Some(&notebook), &steps) | |
| 578 | 579 | .try_into() |
| 579 | 580 | .unwrap(); |
| 580 | 581 | assert!( |
| 581 | 582 | typed.contains(r#"TextInput "Name" = "Renamed" [focused]"#), |
| 582 | 583 | "{typed}" |
| 583 | 584 | ); |
| 585 | assert!(notebooks(&typed).is_empty(), "the sidebar opened:\n{typed}"); | |
| 586 | assert!(renamed.contains(r#"Tab "Renamed""#), "{renamed}"); | |
| 584 | 587 | } |
| 585 | 588 | |
| 586 | 589 | /// Finding on the page leaves the query room beside the match count: a press just past |