Trim needless comments and fix the picker width

Remove comments that only restate the code, keeping the section banners
and the notes that carry a reason, a measured fact or an external
contract.

ButtonOptions.width claimed to be a fixed width but only set minWidth,
so the Graph and Texture pickers grew with the name they showed. It is
now what it promises, with a separate minWidth for the buttons that have
two forms. Narrow buttons shrink their padding, otherwise a 24px icon
button had 8px left for its glyph and truncate dropped it entirely.

__gm.labelsDropped() guards that class: the overflow guard only saw text
that was too wide, never a label truncated to nothing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Opus 5 committed 2026-09-08 15:52:05 +02:00
1 parent f16801aef3
commit 4d84231b9f
115 files changed
+707 -1564

No files matched your search

+5 -11
View File
@@ -18,13 +18,10 @@ import { nextAssetName } from './naming';
import { requireObject, requireScene } from './require';
/**
* Turns the selected objects (with everything parented below them) into a new container
* asset and replaces them in the scene by one placed container – exactly as if that asset
* had been placed there. The container's origin is the centre of the selection's bounding
* box (x/y of the objects' world positions; z = 0), so the template is centred around
* (0, 0, 0). The objects keep their ids and world positions: the selected roots are simply
* re-parented under the container with recomputed local positions. When all roots share a
* parent the container is placed below that parent, otherwise at the top level.
* Turns the selected objects, with everything parented below them, into a container asset placed
* in their stead. The origin is the centre of the selection's bounding box (z = 0), so the template
* is centred around (0, 0, 0); the objects keep their ids and world positions. The container goes
* below the roots' shared parent, or at the top level when they do not share one.
*/
export class CreateContainerCommand implements Command {
readonly label = 'Create container';
@@ -42,7 +39,6 @@ export class CreateContainerCommand implements Command {
const selected = [...new Set(this.objectIds)].map((id) => requireObject(project, this.sceneId, id));
if (selected.length === 0) throw new CommandError('Select at least one object to create a container');
// Centre of the selection in world space – the container's origin.
const worlds = selected.map((o) => worldPosition(scene, o));
const centre: Position = {
x: Math.round((Math.min(...worlds.map((p) => p.x)) + Math.max(...worlds.map((p) => p.x))) / 2),
@@ -50,7 +46,7 @@ export class CreateContainerCommand implements Command {
z: 0,
};
// The subtrees that move into the container, in tree order (parents first).
// Members are collected in tree order, so a parent is always built before its children.
const roots = new Set(
subtreeRoots(
scene,
@@ -64,7 +60,6 @@ export class CreateContainerCommand implements Command {
const rootParents = new Set([...roots].map((id) => findObject(scene, id)!.parentId));
const containerParentId = rootParents.size === 1 ? [...rootParents][0]! : '';
// Template: same structure with private ids, roots relative to the centre.
const asset = buildAsset(
'container',
nextAssetName(project, 'Container'),
@@ -89,7 +84,6 @@ export class CreateContainerCommand implements Command {
});
}
// Scene: the container takes the roots' place, the members become its instance.
this.previous = members.map((o) => ({
id: o.id,
parentId: o.parentId,