mirror of
https://github.com/xmanrui/OpenClaw-bot-review.git
synced 2026-07-30 03:12:14 +00:00
- Add layout editor with floor/wall paint, erase, furniture place/move/rotate/delete tools - Add editor state management (undo/redo, selection, drag, ghost preview) - Add EditorToolbar and EditActionBar UI components - Add layout persistence API (GET/POST to ~/.openclaw/pixel-office/layout.json) - Add notification sound system (Web Audio API ascending chime on agent completion) - Add sub-agent visualization via session JSONL parsing - Fix agent activity API to read from agents.list config and correct session paths - Add agent name labels above character sprites in canvas renderer - Add i18n translations for editor features (zh/en)
110 lines
2.5 KiB
TypeScript
110 lines
2.5 KiB
TypeScript
import { EditTool, TileType } from '../types'
|
|
import type { TileType as TileTypeVal, OfficeLayout, FloorColor } from '../types'
|
|
import { UNDO_STACK_MAX_SIZE, DEFAULT_FLOOR_COLOR, DEFAULT_WALL_COLOR } from '../constants'
|
|
|
|
export class EditorState {
|
|
isEditMode = false
|
|
activeTool: EditTool = EditTool.SELECT
|
|
selectedTileType: TileTypeVal = TileType.FLOOR_1
|
|
selectedFurnitureType: string = 'desk'
|
|
|
|
floorColor: FloorColor = { ...DEFAULT_FLOOR_COLOR }
|
|
wallColor: FloorColor = { ...DEFAULT_WALL_COLOR }
|
|
|
|
// Tracks toggle direction during wall drag
|
|
wallDragAdding: boolean | null = null
|
|
|
|
// Picked furniture color (copied by pick tool)
|
|
pickedFurnitureColor: FloorColor | null = null
|
|
|
|
// Ghost preview position
|
|
ghostCol = -1
|
|
ghostRow = -1
|
|
ghostValid = false
|
|
|
|
// Selection
|
|
selectedFurnitureUid: string | null = null
|
|
|
|
// Mouse drag state
|
|
isDragging = false
|
|
|
|
// Undo / Redo stacks
|
|
undoStack: OfficeLayout[] = []
|
|
redoStack: OfficeLayout[] = []
|
|
|
|
isDirty = false
|
|
|
|
// Drag-to-move state
|
|
dragUid: string | null = null
|
|
dragStartCol = 0
|
|
dragStartRow = 0
|
|
dragOffsetCol = 0
|
|
dragOffsetRow = 0
|
|
isDragMoving = false
|
|
|
|
pushUndo(layout: OfficeLayout): void {
|
|
this.undoStack.push(layout)
|
|
if (this.undoStack.length > UNDO_STACK_MAX_SIZE) {
|
|
this.undoStack.shift()
|
|
}
|
|
}
|
|
|
|
popUndo(): OfficeLayout | null {
|
|
return this.undoStack.pop() || null
|
|
}
|
|
|
|
pushRedo(layout: OfficeLayout): void {
|
|
this.redoStack.push(layout)
|
|
if (this.redoStack.length > UNDO_STACK_MAX_SIZE) {
|
|
this.redoStack.shift()
|
|
}
|
|
}
|
|
|
|
popRedo(): OfficeLayout | null {
|
|
return this.redoStack.pop() || null
|
|
}
|
|
|
|
clearRedo(): void {
|
|
this.redoStack = []
|
|
}
|
|
|
|
clearSelection(): void {
|
|
this.selectedFurnitureUid = null
|
|
}
|
|
|
|
clearGhost(): void {
|
|
this.ghostCol = -1
|
|
this.ghostRow = -1
|
|
this.ghostValid = false
|
|
}
|
|
|
|
startDrag(uid: string, startCol: number, startRow: number, offsetCol: number, offsetRow: number): void {
|
|
this.dragUid = uid
|
|
this.dragStartCol = startCol
|
|
this.dragStartRow = startRow
|
|
this.dragOffsetCol = offsetCol
|
|
this.dragOffsetRow = offsetRow
|
|
this.isDragMoving = false
|
|
}
|
|
|
|
clearDrag(): void {
|
|
this.dragUid = null
|
|
this.isDragMoving = false
|
|
}
|
|
|
|
reset(): void {
|
|
this.activeTool = EditTool.SELECT
|
|
this.selectedFurnitureUid = null
|
|
this.ghostCol = -1
|
|
this.ghostRow = -1
|
|
this.ghostValid = false
|
|
this.isDragging = false
|
|
this.wallDragAdding = null
|
|
this.undoStack = []
|
|
this.redoStack = []
|
|
this.isDirty = false
|
|
this.dragUid = null
|
|
this.isDragMoving = false
|
|
}
|
|
}
|