List drawn shapes under Draw, with icon shapes and colour swatches

Each shape drawn by hand gets a row under Draw, as Import's files do: its
colour swatch, its name, and show/hide, fly-to and remove. A shape is named
in its row, and its swatch opens the five colours there, so labelling and
colouring happen after a shape is drawn and can be seen, instead of in a
field filled in beforehand. Area, Line and Pin become icon buttons, named
for screen readers and tooltips, and the colour for the next shape is a row
of swatches instead of a dropdown.

The annotation engine gains per-mark remove, setHidden, restyle and frame,
and onChange so the list follows the board. A hidden mark stays on the board
at alpha 0, a renamed line keeps its length, and fly-to frames a line by its
whole path. Voice marks are not listed.

The Draw, form-field and segmented-control gates drive the new controls;
swatches are checked as chips, not segments.
This commit is contained in:
Said Turksever committed 2026-10-29 12:41:12 +00:00
1 parent 8543b7be43
commit 95ed686da5
23 files changed
+1061 -214

No files matched your search

+19 -6
View File
@@ -69,8 +69,8 @@ test('the Draw control markup carries the ids the tool binds to', () => {
'draw-toggle',
'draw-mode-row',
'draw-label-row',
'draw-label-input',
'draw-color-select',
'draw-colors',
'draw-mark-list',
'draw-clear',
'draw-hint',
];
@@ -81,13 +81,25 @@ test('the Draw control markup carries the ids the tool binds to', () => {
`#${id} missing from index.html`,
);
}
for (const shape of ['area', 'line', 'pin']) {
// Shapes are icons, named for screen readers and tooltips.
for (const [shape, name] of [
['area', 'Area'],
['line', 'Line'],
['pin', 'Pin'],
]) {
assert.match(
html,
new RegExp(`data-shape="${shape}"`),
new RegExp(
`data-shape="${shape}"[^>]*aria-label="${name}"[^>]*title="${name}"`,
),
`shape button ${shape} missing`,
);
}
for (const color of ['primary', 'amber', 'cyan', 'green', 'red'])
assert.match(
html,
new RegExp(`class="draw-color[^"]*" type="button" data-color="${color}"`),
);
for (const id of ids) {
assert.match(
tool(),
@@ -108,14 +120,15 @@ test('the DISPLAY rail styles live in their current owner, not the shim', () =>
);
assert.doesNotMatch(
shim,
/draw-hint|pp-text-input/,
/draw-hint|draw-color/,
'draw styles belong to a component stylesheet',
);
const controls = read('src/ui/styles/controls.css');
for (const rule of [
'#draw-mode-row',
'#draw-label-row',
'.pp-text-input',
'.draw-color',
'.draw-mark-name',
'.draw-clear-btn',
'.draw-hint',
'body.gev-drawing',