The tile list in the tilemap section is a palette of pictures: each tile shows its lone tile (the four convex corners for floor and wall, the picture itself for none) with its name below, laid out with the image-picker grid (#139)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4c411c1ff3
commit
bfbcbe604c
9 files changed
+331
-28
No files matched your search
@@ -16,6 +16,7 @@ import type { TilemapAsset } from '../../core/model/Asset';
|
||||
import { isLayerVisible } from '../../core/model/tilemap';
|
||||
import { Button, Checkbox, HStack, Theme } from '../../ui';
|
||||
import type { EditorState, TilemapTool } from '../state';
|
||||
import { TilePalette } from '../tile/TilePalette';
|
||||
import { addGap, addNote, addTitle, type InspectorHost } from './host';
|
||||
|
||||
const TOOLS: { tool: TilemapTool; label: string; hint: string }[] = [
|
||||
@@ -42,7 +43,8 @@ export function paintedLayerId(state: EditorState, asset: TilemapAsset): string
|
||||
*/
|
||||
export interface TilemapSectionWidgets {
|
||||
tools: Map<TilemapTool, Button>;
|
||||
tiles: Map<string, Button>;
|
||||
/** Null while the project has no tile. */
|
||||
palette: TilePalette | null;
|
||||
layers: { id: string; name: Button; visible: Checkbox; up: Button; down: Button; remove: Button }[];
|
||||
addLayer: Button;
|
||||
}
|
||||
@@ -58,7 +60,7 @@ export function buildTilemapSection(host: InspectorHost, asset: TilemapAsset): v
|
||||
const paint = state.tilemapPaint;
|
||||
const widgets: TilemapSectionWidgets = {
|
||||
tools: new Map(),
|
||||
tiles: new Map(),
|
||||
palette: null,
|
||||
layers: [],
|
||||
addLayer: new Button('Add layer', {
|
||||
onClick: () => state.execute(new AddTilemapLayerCommand(asset.id)),
|
||||
@@ -79,23 +81,19 @@ export function buildTilemapSection(host: InspectorHost, asset: TilemapAsset): v
|
||||
addNote(host, 'Shift-drag still pans the view.', 'small');
|
||||
|
||||
addTitle(host, 'TILES');
|
||||
const tiles = state.project.assets.filter((a) => a.type === 'tile');
|
||||
const tiles = tileIdsOf(state);
|
||||
if (tiles.length === 0) addNote(host, 'The project has no tile yet.');
|
||||
for (const tile of tiles) {
|
||||
const button = new Button(tile.name, {
|
||||
align: 'left',
|
||||
// Choosing a tile is how one starts painting, so it reaches for the brush by itself.
|
||||
onClick: () =>
|
||||
state.setTilemapPaint({
|
||||
tileId: tile.id,
|
||||
tool: paint.tool === 'select' || paint.tool === 'erase' ? 'brush' : paint.tool,
|
||||
}),
|
||||
});
|
||||
button.toggled = paint.tileId === tile.id;
|
||||
widgets.tiles.set(tile.id, button);
|
||||
host.body.add(button);
|
||||
else {
|
||||
// Choosing a tile is how one starts painting, so it reaches for the brush by itself.
|
||||
widgets.palette = new TilePalette(state, tiles, paint.tileId, (tileId) =>
|
||||
state.setTilemapPaint({
|
||||
tileId,
|
||||
tool: paint.tool === 'select' || paint.tool === 'erase' ? 'brush' : paint.tool,
|
||||
}),
|
||||
);
|
||||
host.body.add(widgets.palette);
|
||||
}
|
||||
if (tiles.length > 0 && !tiles.some((a) => a.id === paint.tileId))
|
||||
if (tiles.length > 0 && !tiles.includes(paint.tileId))
|
||||
addNote(host, 'Choose a tile to paint with.', 'small');
|
||||
|
||||
addTitle(host, 'LAYERS');
|
||||
@@ -140,13 +138,19 @@ export function buildTilemapSection(host: InspectorHost, asset: TilemapAsset): v
|
||||
host.body.add(widgets.addLayer);
|
||||
}
|
||||
|
||||
function tileIdsOf(state: EditorState): string[] {
|
||||
return state.project.assets.filter((a) => a.type === 'tile').map((a) => a.id);
|
||||
}
|
||||
|
||||
/**
|
||||
* What the section is built from, for the inspector's rebuild check: the layers and what is
|
||||
* painted with. The cells themselves are deliberately absent – a stroke must not rebuild the
|
||||
* panel under the pointer that is drawing it.
|
||||
* What the section is built from, for the inspector's rebuild check: the layers, the tiles on offer
|
||||
* and what is painted with. The cells themselves are deliberately absent – a stroke must not
|
||||
* rebuild the panel under the pointer that is drawing it – and so are the tiles' pictures and
|
||||
* names, which the palette repaints by itself.
|
||||
*/
|
||||
export function tilemapSignature(state: EditorState, asset: TilemapAsset): string {
|
||||
const paint = state.tilemapPaint;
|
||||
const layers = asset.layers.map((l) => `${l.id}:${l.name}:${isLayerVisible(l) ? 1 : 0}`).join(',');
|
||||
return `${paint.tool}|${paint.tileId}|${paintedLayerId(state, asset)}|${layers}`;
|
||||
const tiles = tileIdsOf(state).join(',');
|
||||
return `${paint.tool}|${paint.tileId}|${paintedLayerId(state, asset)}|${layers}|${tiles}`;
|
||||
}
|
||||
Reference in new issue
Block a user