Mass guide editor changes #18

Merged
Tyler merged 25 commits from guide_editor_changes into main 2026-06-15 15:37:48 +00:00
Showing only changes of commit 014b92675d - Show all commits
+33 -20
View File
@@ -8,6 +8,22 @@ const dialogs = window.StepForgeDialogs || {};
const clone = (value) => JSON.parse(JSON.stringify(value)); const clone = (value) => JSON.parse(JSON.stringify(value));
const BLOCK_KIND_ORDER = { text: 0, code: 1, table: 2 }; const BLOCK_KIND_ORDER = { text: 0, code: 1, table: 2 };
// Which style fields are meaningful for each annotation type, so the
// annotation editor only shows controls that actually affect that type.
const ANNOTATION_FIELDS = {
rect: ['stroke', 'fill', 'strokeWidth'],
oval: ['stroke', 'fill', 'strokeWidth'],
line: ['stroke', 'strokeWidth'],
arrow: ['stroke', 'strokeWidth'],
text: ['text', 'stroke', 'fontSize'],
tooltip: ['text', 'fill', 'stroke', 'strokeWidth', 'fontSize', 'textColor', 'tail'],
number: ['value', 'stroke', 'textColor'],
blur: ['radius'],
highlight: [],
magnify: ['zoom', 'stroke', 'strokeWidth'],
cursor: [],
};
function blockText(block) { function blockText(block) {
for (const key of ['code', 'text', 'body', 'value', 'content']) { for (const key of ['code', 'text', 'body', 'value', 'content']) {
const value = block && block[key]; const value = block && block[key];
@@ -935,31 +951,28 @@ class GuideEditor {
this.emitMeta(); this.emitMeta();
}; };
const annSection = el('div', { className: 'annotation-editor-inner' }, const fields = new Set(ANNOTATION_FIELDS[selected.type] || []);
labeledRow('Type', typeSelect), const strokeLabel = (selected.type === 'text' || selected.type === 'number') ? 'Color' : 'Stroke';
labeledRow('Text', textInput),
labeledRow('Value', valueInput), const rows = [labeledRow('Type', typeSelect)];
labeledRow('Stroke', strokeInput), if (fields.has('text')) rows.push(labeledRow('Text', textInput));
labeledRow('Fill', fillInput), if (fields.has('value')) rows.push(labeledRow('Value', valueInput));
labeledRow('Stroke width', strokeWidthInput), if (fields.has('stroke')) rows.push(labeledRow(strokeLabel, strokeInput));
labeledRow('Font size', fontSizeInput), if (fields.has('fill')) rows.push(labeledRow('Fill', fillInput));
labeledRow('Text color', textColorInput), if (fields.has('strokeWidth')) rows.push(labeledRow('Stroke width', strokeWidthInput));
labeledRow('Zoom', zoomInput), if (fields.has('fontSize')) rows.push(labeledRow('Font size', fontSizeInput));
labeledRow('Radius', radiusInput), if (fields.has('textColor')) rows.push(labeledRow('Text color', textColorInput));
labeledRow('Tail', tailInput), if (fields.has('zoom')) rows.push(labeledRow('Zoom', zoomInput));
el('div.row', {}, if (fields.has('radius')) rows.push(labeledRow('Radius', radiusInput));
el('button', { if (fields.has('tail')) rows.push(labeledRow('Tail', tailInput));
type: 'button', rows.push(
onClick: () => {
this.canvas.deleteSelected();
},
}, 'Delete annotation'),
),
el('div.row', {}, el('div.row', {},
el('button', { type: 'button', title: 'Copy this style to every annotation of the same type in this step', onClick: () => this.applyStyleAcross('step') }, 'Style → step'), el('button', { type: 'button', title: 'Copy this style to every annotation of the same type in this step', onClick: () => this.applyStyleAcross('step') }, 'Style → step'),
el('button', { type: 'button', title: 'Copy this style to every annotation of the same type in the whole guide', onClick: () => this.applyStyleAcross('guide') }, 'Style → guide'), el('button', { type: 'button', title: 'Copy this style to every annotation of the same type in the whole guide', onClick: () => this.applyStyleAcross('guide') }, 'Style → guide'),
), ),
); );
const annSection = el('div', { className: 'annotation-editor-inner' }, ...rows);
this.dom.annotationEditor.append(annSection); this.dom.annotationEditor.append(annSection);
typeSelect.addEventListener('change', () => { typeSelect.addEventListener('change', () => {