Add points by double-click and delete the picked one (#288)
Four editors edit points, and all of them put a point down on a single press on the line and took one away on a double-click. A stray click added a point, and there was no way to see which point a key would hit. All four now work the same way: the Curve tab, the Vector art tab, a polygon collider in the scene view and a frame's collision outline in the Texture tab. - A double-click on a line, edge or segment puts a point there, in the Curve tab on free space too. The point is picked and stays in place. It can be dragged with the next press, as answered in the issue. - A click on a point picks it, and it is drawn filled. A double-click on a point takes nothing away any more. - Delete or Backspace takes the picked point away. Without a picked point the key removes the shape, the object or the outline as before. - A right-click on a point picks it and opens a menu with Delete point. In the Curve and Vector art tab the four point types stand below it. Alt-click stays. - A polygon keeps three corners and a curve keeps its ends. The entry is greyed out then. - The pick ends with a click beside the points, with another object, shape or frame, and after the point is gone. - editor/pointGestures.ts holds the rule as a pure function, and editor/pointMenu.ts builds the menu for all four. Decided here: - A single click on a line no longer adds anything. In Vector art it drags the shape, on a polygon it drops the pick, and in the Texture tab it makes that outline the active one and drops the pick. - In the Texture tab a click inside the frame still appends a corner, and that corner is picked. Delete takes the last corner first. To remove the whole outline, click one of its edges before. - The point the Pen put down last is picked, so Delete takes it and not the shape. - Delete hits the picked point also when the tab has lost the keyboard focus, after a click in the shape list or after the menu. - A vector shape that loses its last point is removed whole. Before, an empty shape stayed in the list. Findings: - Fixed: the new hint line in the Texture tab was cut off at the edge. The shorter text was not looked at in a picture again. - Not fixed: in the scene view the collider's name label covers a corner that sits near the centre. That was so before. Tests: - Gate: 200 files, 2967 tests (2944 + 23), exit 0 - e2e, full run: 1629 checks passed (1625 + 4), exit 0 - Smokes: 24 / 19 / 21, exit 0 - After the full run an unused parameter and a comment were tidied. For that final state the gate and e2e 42,47,53 (105 checks) ran again, the full run did not. - 23 unit tests in tests/editor/point-gestures.test.ts, for the rule and for each of the four editors - Four e2e checks with a real mouse, two in module 42 and one each in 47 and 53. The existing checks for adding and removing a point use the new gestures. - 20 unit counter-probes all fail tests, run on stein2 - Two browser counter-probes fail, the build went through both times. Without the Delete wiring the key removes the collider. Without the right-click hook the menu is missing, and that run stops in module 42, so 47 and 53 were not reached with it. - Three screenshots looked at, the picked point is filled. None of the Vector art tab. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1aa824ecb4
commit
0f85476b93
19 files changed
+1180
-168
No files matched your search
@@ -276,13 +276,53 @@ export async function vectorArt(t) {
|
||||
|
||||
await shot('47-vector-tab');
|
||||
|
||||
const firstPoint = await json(`__gm.vectorArt.pointAt(${TRIANGLE[0].x}, ${TRIANGLE[0].y})`);
|
||||
await doubleClick(firstPoint.x, firstPoint.y);
|
||||
const left = (await json("__gm.vectorArt.shapes('va-art')")).at(-1).rings[0].points;
|
||||
// #288: a double-click on a line puts a point there and picks it, Delete takes the picked point
|
||||
// away and leaves the shape, and a point's menu does the same.
|
||||
const ringPoints = async () => (await json("__gm.vectorArt.shapes('va-art')")).at(-1).rings[0].points;
|
||||
const lineSpot = await json(`__gm.vectorArt.pointAt(75, 75)`);
|
||||
const linePoints = (await ringPoints()).length;
|
||||
await click(lineSpot.x, lineSpot.y);
|
||||
const onlyClicked = (await ringPoints()).length;
|
||||
await sleep(500);
|
||||
await doubleClick(lineSpot.x, lineSpot.y);
|
||||
const withPoint = await ringPoints();
|
||||
const pickedAdded = await json('__gm.vectorArt.picked()');
|
||||
await press('Delete');
|
||||
const withoutPoint = await ringPoints();
|
||||
check(
|
||||
'a double-click takes a point away',
|
||||
left.length === 2 && near(left[0].x, 180),
|
||||
JSON.stringify(left.map((p) => [Math.round(p.x), Math.round(p.y)])),
|
||||
'a click on a line adds nothing, a double-click puts a picked point there, and Delete takes it away again',
|
||||
onlyClicked === linePoints &&
|
||||
withPoint.length === linePoints + 1 &&
|
||||
Boolean(pickedAdded) &&
|
||||
near(withPoint[pickedAdded.index].x, 75) &&
|
||||
near(withPoint[pickedAdded.index].y, 75) &&
|
||||
withoutPoint.length === linePoints &&
|
||||
(await json("__gm.vectorArt.shapes('va-art')")).length > 0,
|
||||
JSON.stringify({
|
||||
linePoints,
|
||||
onlyClicked,
|
||||
withPoint: withPoint.length,
|
||||
pickedAdded,
|
||||
withoutPoint: withoutPoint.length,
|
||||
}),
|
||||
);
|
||||
|
||||
const firstPoint = await json(`__gm.vectorArt.pointAt(${TRIANGLE[0].x}, ${TRIANGLE[0].y})`);
|
||||
await sleep(500);
|
||||
await doubleClick(firstPoint.x, firstPoint.y);
|
||||
const keptPoints = (await ringPoints()).length;
|
||||
await click(firstPoint.x, firstPoint.y, 'right');
|
||||
const pointMenu = await json('__gm.menuRows()');
|
||||
await clickText('Delete point');
|
||||
const left = await ringPoints();
|
||||
check(
|
||||
'a double-click keeps a point; its menu offers Delete point and the four types, and takes it away',
|
||||
keptPoints === 3 &&
|
||||
JSON.stringify(pointMenu) ===
|
||||
JSON.stringify(['Delete point', null, 'Straight', 'Corner', 'Smooth', 'Symmetric']) &&
|
||||
left.length === 2 &&
|
||||
near(left[0].x, 180),
|
||||
JSON.stringify({ keptPoints, pointMenu, left: left.map((p) => [Math.round(p.x), Math.round(p.y)]) }),
|
||||
);
|
||||
|
||||
// The drawing is a picture like any other: what the tool changed reaches the sprite by itself.
|
||||
|
||||
Reference in new issue
Block a user