67 lines
3.0 KiB
TypeScript
67 lines
3.0 KiB
TypeScript
/**
|
|
* Columns and Rows of a placed tilemap in the inspector (#136): the grid grows at the right or bottom
|
|
* edge while the painted cells stay where they are, already while the value is previewed. The
|
|
* preview counts from where the edit started, so dragging back and forth leaves no drift, and the
|
|
* commit is one undo step.
|
|
*/
|
|
import { describe, expect, it } from 'vitest';
|
|
import { CreateAssetCommand } from '../../src/core/commands/assetCommands';
|
|
import { PlaceAssetCommand, SetOverrideCommand } from '../../src/core/commands/sceneObjectCommands';
|
|
import { findObject } from '../../src/core/model/hierarchy';
|
|
import { resolvedHolder } from '../../src/core/model/instance';
|
|
import { createEmptyProject, findScene } from '../../src/core/model/Project';
|
|
import { TILEMAP_COLUMNS_KEY } from '../../src/core/model/tilemap';
|
|
import { previewingHandlers } from '../../src/editor/inspector/previewHandlers';
|
|
import { tilemapSizeValue } from '../../src/editor/inspector/valueSpecs';
|
|
import { EditorState } from '../../src/editor/state';
|
|
|
|
function setup() {
|
|
const state = new EditorState();
|
|
state.loadProject(createEmptyProject('p', 'P'), 1);
|
|
const scene = new CreateAssetCommand('scene', 'Main');
|
|
const map = new CreateAssetCommand('tilemap', 'Ground');
|
|
state.execute(scene);
|
|
state.execute(map);
|
|
const placed = new PlaceAssetCommand(scene.asset.id, map.asset.id, { x: 10, y: 20 });
|
|
state.execute(placed);
|
|
state.execute(new SetOverrideCommand(scene.asset.id, placed.objectId, 'rotation', 90));
|
|
const object = () =>
|
|
findObject(resolvedHolder(state.project, findScene(state.project, scene.asset.id)!), placed.objectId)!;
|
|
const field = previewingHandlers(
|
|
{ state },
|
|
tilemapSizeValue(state, scene.asset.id, placed.objectId, TILEMAP_COLUMNS_KEY),
|
|
);
|
|
return { state, object, field };
|
|
}
|
|
|
|
describe('the Columns field of a placed tilemap', () => {
|
|
it('moves the origin along while previewing, from where the edit started', () => {
|
|
const { object, field } = setup();
|
|
// 20 columns of 48 px by default; turned by 90°, the map's own x axis points down the screen.
|
|
field.onInput(23);
|
|
expect(object().position.x).toBeCloseTo(10, 9);
|
|
expect(object().position.y).toBeCloseTo(20 + 72, 9);
|
|
field.onInput(17);
|
|
field.onInput(21);
|
|
expect(object().position.y).toBeCloseTo(20 + 24, 9);
|
|
});
|
|
|
|
it('commits one undo step that holds the content, and undo returns exactly to the start', () => {
|
|
const { state, object, field } = setup();
|
|
const start = structuredClone(object());
|
|
for (const value of [31, 5, 26]) field.onInput(value);
|
|
field.onChange(26);
|
|
expect(object().overrides[TILEMAP_COLUMNS_KEY]).toBe(26);
|
|
expect(object().position.y).toBeCloseTo(20 + 144, 9);
|
|
state.undo();
|
|
expect(object()).toEqual(start);
|
|
});
|
|
|
|
it('takes a value typed in without a preview as well', () => {
|
|
const { object, field } = setup();
|
|
field.onChange(19);
|
|
expect(object().overrides[TILEMAP_COLUMNS_KEY]).toBe(19);
|
|
expect(object().position.y).toBeCloseTo(20 - 24, 9);
|
|
});
|
|
});
|