Blend: arrow keys step from the widget's shown value; a double-click on a widget leaves the art alone

- After a drag past either end of the range, the first arrow key now
  steps back from the value shown instead of doing nothing.
- With the Selection tool, a plain double-click on a blend widget no
  longer edits or isolates the artwork under it, or leaves isolation.
  Ctrl/Cmd+Shift double-click still releases a guide there.
- docs/mcp.md says the lower widget shows only when the steps follow
  the spine, and the G13 blend easing entry in docs/gaps.md no longer
  lists on-canvas easing handles as missing.
This commit is contained in:
dotCooCoo
2026-11-12 00:54:15 -08:00
parent bd82a598dd
commit e7f2601847
4 changed files with 46 additions and 8 deletions
+36 -4
View File
@@ -239,11 +239,11 @@ impl BlendWidgetDrag {
/// An arrow key during the drag: one point more (`more`) or less, ten with Shift.
pub fn step(&mut self, cx: &ToolContext, more: bool, big: bool) -> Vec<Action> {
let by = if big { 10.0 } else { 1.0 };
self.keys += if more { by } else { -by };
// Past either end, the keys stop adding: the way back starts at once.
// The step goes from the value shown, so past either end (by keys or by the drag) the way
// back starts at once.
let (lo, hi) = self.widget.control.range();
let free = self.dragged(cx);
self.keys = self.keys.clamp(lo - free, hi - free);
let stepped = (self.value_now(cx) + if more { by } else { -by }).clamp(lo, hi);
self.keys = stepped - self.dragged(cx);
self.preview(cx)
}
@@ -533,4 +533,36 @@ mod tests {
assert!(!t.busy() && !t.transforming());
assert!(t.pointer(&c, &ev(PointerKind::Up, at)).is_empty(), "the release commits nothing");
}
/// A double-click on a widget with the Selection tool does nothing to the artwork under it.
#[test]
fn a_double_click_on_a_widget_leaves_the_artwork_under_it_alone() {
let (mut d, _, s) = blend_doc(&[(100.0, 200.0), (300.0, 200.0)], eased());
cover(&mut d, 190.0, 206.0, 210.0, 226.0);
let p = paint();
let c = cx(&d, &s, &p);
let at = Point::new(200.0, 216.0);
assert!(over_widget(&c, at));
let mut t = SelectionTool::default();
assert!(t.pointer(&c, &ev(PointerKind::DoubleClick, at)).is_empty());
// Beside the widget, the double-click reaches the artwork.
assert!(!t.pointer(&c, &ev(PointerKind::DoubleClick, Point::new(192.0, 224.0))).is_empty());
}
/// After a drag past either end, the first arrow key steps back from the value shown.
#[test]
fn an_arrow_key_after_a_drag_past_an_end_steps_from_the_value_shown() {
let (d, id, s) = blend_doc(&[(100.0, 200.0), (300.0, 200.0)], eased());
let p = paint();
let c = cx(&d, &s, &p);
let at = Point::new(200.0, 216.0);
let ramp = |v: f64| vec![Action::Preview("object.blend.setEasing".into(), json!({"id": id.0, "ramp": v}))];
for (moved, back, shown) in [(200.0, ToolKey::Left, 99.0), (-200.0, ToolKey::Right, 1.0)] {
let mut t = SelectionTool::default();
t.pointer(&c, &ev(PointerKind::Down, at));
t.pointer(&c, &ev(PointerKind::Drag, at + Vec2::new(moved, 0.0)));
assert_eq!(t.key(&c, back, Mods::default()), ramp(shown), "{moved}");
assert_eq!(t.pointer(&c, &ev(PointerKind::Up, at + Vec2::new(moved, 0.0))), vec![Action::Commit]);
}
}
}
+5
View File
@@ -1531,6 +1531,11 @@ impl SelectionTool {
if let Some(a) = release_guide_at(cx, p, m) {
return vec![a];
}
// A selected blend's widget takes a plain double-click: the artwork under it is neither
// edited nor isolated.
if blendwidget::over_widget(cx, p) {
return vec![];
}
if crate::rulerguide::guide_at(cx, p).is_some() {
return vec![];
}
+3 -2
View File
@@ -534,8 +534,9 @@ macOS cursor delivery (#2292) is narrowed to a native host adapter using the exi
(#1676). A linked image is refused, as the public documentation has it.
- **Partial:** blend easing (#1124, 30.7): Window › Blend has Type (Ease In, Ease Out, Ease In Out,
Ease Out In), Ramp 0–100% and independent color Shift; easing is disabled without a spine.
The original polynomial distributions approximate the public description. On-canvas easing handles
and their synchronization remain missing. [Public source](https://helpx.adobe.com/illustrator/desktop/manage-colors/apply-transparency-and-blending/blend-panel-overview.html).
The original polynomial distributions approximate the public description. With the Selection or
Blend tool, on-canvas widgets set the color Shift and, when the steps follow a spine, the Ramp; the
Blend panel shows the values they set. [Public source](https://helpx.adobe.com/illustrator/desktop/manage-colors/apply-transparency-and-blending/blend-panel-overview.html).
- **Done:** gradient Dither (30.0): the Gradient panel's Dither box (`paint.editGradient` `dither`, also in `paint.setFill`'s
`gradient`, swatches and the native file) draws a linear or radial gradient fill as pixels with seeded noise of up to a
+2 -2
View File
@@ -8632,10 +8632,10 @@ first selected blend without `id`) and returns `{id, easingType, ramp, colorShif
replaced or edited spine, or `orientation: "path"`) and not made without one (`createSpine: "never"`), as the Blend
panel's Type and Ramp do. A value out of range, a hidden or locked blend and a target that is not a blend are errors,
and a call that changes nothing records no undo step (`changed: false`). With one blend selected that has a spine,
the Selection and Blend tools show the same two values as widgets
the Selection and Blend tools show the same values as widgets
16 px above and below the spine's halfway point (where the boxes of three or more other visible objects hold that
spot, a widget moves out in 16 px steps, up to 144 px, joined to the halfway point by a line): the upper one sets
`colorShift` and the lower one `ramp`, by one per screen pixel dragged along the spine and by one per arrow key
`colorShift` and the lower one, shown only when the steps follow the spine as `ramp` needs, sets `ramp`, by one per screen pixel dragged along the spine and by one per arrow key
during the drag (ten with Shift). Each drag is one undo step, and `press_key` Escape or a switch to another tool
during it puts the value back: