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)
game-maker / gate (push) Successful in 1m41s
game-maker / suite (push) Successful in 6m15s

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
adminandClaude Opus 5 committed 2026-09-18 10:15:51 +02:00
1 parent 4c411c1ff3
commit bfbcbe604c
9 files changed
+331 -28

No files matched your search

+25 -21
View File
@@ -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}`;
}