Mark overrides in gold instead of bold, and up the hierarchy
An inspector label whose value deviates from its base was drawn bold, which is easy to miss next to the regular labels and says nothing in the hierarchy, where a folded subtree could hide a change entirely. The colour now lives as a theme token (`override`, #f2c84b) used by both the inspector labels and the hierarchy rows. Whether a row deviates is decided by `src/core/properties/deviation.ts`: `objectDeviates` compares an object against what it follows -- the container template for content, the asset otherwise -- and `deviationMarks` carries the mark up to every ancestor, so a folded subtree still shows that something inside was changed. `deviationMarks` takes the stored holder, not the resolved one: in the resolved view container content looks like an ordinary object and `instanceTargetOf` would compare against the asset, marking every instance. Covered by 3 unit tests and 5 e2e checks, including one that strips an object's own overrides to prove the row stays gold for a deviating child and restores them byte for byte. Full suite remote on the RTX 4070: 275 checks, all passed.
This commit is contained in:
1 parent
37e1450fca
commit
b87fcdfbad
13 files changed
+197
-14
No files matched your search
@@ -0,0 +1,50 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { CreateContainerCommand } from '../../src/core/commands/containerCommands';
|
||||
import {
|
||||
ClearOverrideCommand,
|
||||
SetOverrideCommand,
|
||||
SetParentCommand,
|
||||
} from '../../src/core/commands/sceneObjectCommands';
|
||||
import { instanceChildId } from '../../src/core/model/instance';
|
||||
import { findAsset } from '../../src/core/model/Project';
|
||||
import type { ContainerAsset } from '../../src/core/model/Asset';
|
||||
import { deviationMarks, objectDeviates } from '../../src/core/properties/deviation';
|
||||
import { makeSpriteScene, place } from '../helpers';
|
||||
|
||||
describe('deviation marks', () => {
|
||||
it('marks an object only once an override really deviates', () => {
|
||||
const f = makeSpriteScene();
|
||||
const id = place(f, f.spriteId, { x: 0, y: 0 });
|
||||
const deviates = () => objectDeviates(f.project, f.sceneOf(), f.object(id));
|
||||
expect(deviates()).toBe(false);
|
||||
// The asset's own value carried as an override is no deviation.
|
||||
f.stack.execute(new SetOverrideCommand(f.sceneId, id, 'width', 100));
|
||||
expect(deviates()).toBe(false);
|
||||
f.stack.execute(new SetOverrideCommand(f.sceneId, id, 'width', 250));
|
||||
expect(deviates()).toBe(true);
|
||||
f.stack.execute(new ClearOverrideCommand(f.sceneId, id, 'width'));
|
||||
expect(deviates()).toBe(false);
|
||||
});
|
||||
|
||||
it('marks the ancestors of a deviating object, so a folded row still shows it', () => {
|
||||
const f = makeSpriteScene();
|
||||
const parent = place(f, f.spriteId, { x: 0, y: 0 });
|
||||
const child = place(f, f.spriteId, { x: 0, y: 0 });
|
||||
f.stack.execute(new SetParentCommand(f.sceneId, child, parent));
|
||||
expect(deviationMarks(f.project, f.sceneOf()).size).toBe(0);
|
||||
f.stack.execute(new SetOverrideCommand(f.sceneId, child, 'width', 250));
|
||||
expect([...deviationMarks(f.project, f.sceneOf())].sort()).toEqual([child, parent].sort());
|
||||
});
|
||||
|
||||
it('marks container content against its template, and the instance above it', () => {
|
||||
const f = makeSpriteScene();
|
||||
const a = place(f, f.spriteId, { x: 0, y: 0 });
|
||||
const create = new CreateContainerCommand(f.sceneId, [a]);
|
||||
f.stack.execute(create);
|
||||
const template = (findAsset(f.project, create.assetId) as ContainerAsset).objects[0]!.id;
|
||||
const content = instanceChildId(create.objectId, template);
|
||||
expect(deviationMarks(f.project, f.sceneOf()).size).toBe(0);
|
||||
f.stack.execute(new SetOverrideCommand(f.sceneId, content, 'width', 250));
|
||||
expect([...deviationMarks(f.project, f.sceneOf())].sort()).toEqual([content, create.objectId].sort());
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user