Keep long destination names inspectable without granting stale drop authority

This commit is contained in:
2026-09-12 04:41:50 -07:00
parent 1b3c401a19
commit 5ce798b713
6 changed files with 238 additions and 6 deletions
@@ -252,6 +252,7 @@ pub struct Preview {
}
struct Active {
press: Arc<Press>,
inspection_targets: Vec<usize>,
ids: BTreeMap<Id, Id>,
cache: Vec<(
plan::Destination,
@@ -261,10 +262,34 @@ struct Active {
pub struct Feedback {
pub press: Arc<Press>,
pub targets: Vec<usize>,
/// Last captured target names for inspection only; never resolver input.
pub inspection_targets: Vec<usize>,
pub text: String,
pub refused: bool,
}
impl Feedback {
pub fn inspection_identity(&self) -> String {
if self.refused && self.targets.is_empty() && !self.inspection_targets.is_empty() {
let names = self
.inspection_targets
.iter()
.map(|index| self.press.frozen.targets[*index].name.as_str())
.collect::<Vec<_>>()
.join(" / ");
format!(
"{}\nLast target{}: {}\nReturn to the canvas to choose a destination; releasing here cancels the drag.",
self.destination_identity(),
if self.inspection_targets.len() > 1 {
"s (ambiguous)"
} else {
""
},
names
)
} else {
self.destination_identity()
}
}
/// Captured accepted names, independent of clipped status/refusal prose.
pub fn destination_identity(&self) -> String {
match self.targets.as_slice() {
@@ -481,6 +506,7 @@ impl App {
self.allocation_drag.feedback = None;
self.allocation_drag.active = Some(Active {
press,
inspection_targets: Vec::new(),
ids,
cache: Vec::new(),
});
@@ -528,6 +554,13 @@ impl App {
let press = active.press.clone();
let moved = pointer.is_some_and(|p| p.distance(press.start) > 3.);
let hit = press.frozen.resolve(stamp, pointer, press.arrange);
if moved {
match &hit {
Hit::Destination(_, Some(target)) => active.inspection_targets = vec![*target],
Hit::Ambiguous(targets) => active.inspection_targets = targets.clone(),
_ => {}
}
}
let mut targets = Vec::new();
let mut preview = None;
let result: Result<String, String> = match hit {
@@ -591,11 +624,13 @@ impl App {
if release {
self.allocation_drag.retire();
} else {
let inspection_targets = active.inspection_targets.clone();
self.allocation_drag.active = Some(active);
self.allocation_drag.preview = preview;
self.allocation_drag.feedback = Some(Feedback {
press,
targets,
inspection_targets,
text,
refused,
});