diff --git a/app/react-components/devtools/tiles.jsx b/app/react-components/devtools/tiles.jsx index a81dbc1..3b9db65 100644 --- a/app/react-components/devtools/tiles.jsx +++ b/app/react-components/devtools/tiles.jsx @@ -11,6 +11,7 @@ export default function Tiles({eventsChannel}) { const wrapperRef = useRef(); const imageRef = useRef(); const imageRect = useRect(imageRef); + const [indices, setIndices] = useState([]); const [selection, setSelection] = useState({x: 0, y: 0, w: 1, h: 1}); const [moveStart, setMoveStart] = useState(); const [layer, setLayer] = useState(0); @@ -35,17 +36,19 @@ export default function Tiles({eventsChannel}) { if (at.x < 0 || at.y < 0 || at.x >= area.x || at.y >= area.y) { return; } - const payload = { - brush, - layer, - stamp: { - at, - data: stamp, - }, - } client.send({ type: 'AdminAction', - payload: {type: 'paint', value: payload}, + payload: { + type: 'paint', + value: { + brush, + layer, + stamp: { + at, + data: stamp, + }, + }, + }, }); } eventsChannel.addListener('click', onClick); @@ -64,6 +67,7 @@ export default function Tiles({eventsChannel}) { const {sourceJson, tileSize} = TileLayers.layer(0); const {w, h} = sourceJson.meta.size; const factor = (imageRect?.width ?? 1) / w; + const wt = w / tileSize.x; return (
@@ -125,8 +129,13 @@ export default function Tiles({eventsChannel}) { const y = Math.floor((c.y - top) / (tileSize.y * factor)); setMoveStart({x, y}); setSelection({x, y, w: 1, h: 1}); + setIndices([y * wt + x]); }} onMouseMove={(event) => { + if (0 === event.buttons) { + setMoveStart(); + return; + } if (!moveStart) { return; } @@ -145,12 +154,24 @@ export default function Tiles({eventsChannel}) { ); const mx = Math.min(sx, x); const my = Math.min(sy, y); - setSelection({x: mx, y: my, w: Math.abs(sx - x) + 1, h: Math.abs(sy - y) + 1}); - }} - onMouseUp={() => { - setMoveStart(); + const sw = Math.abs(sx - x) + 1; + const sh = Math.abs(sy - y) + 1; + const newSelection = { + x: mx, + y: my, + w: sw, + h: sh, + }; + if ( + selection.x === newSelection.x + && selection.y === newSelection.y + && selection.w === newSelection.w + && selection.h === newSelection.h + ) { + return; + } + setSelection(newSelection); const stamp = []; - const {x, y, w: sw, h: sh} = selection; const tw = w / tileSize.x; for (let iy = 0; iy < sh; ++iy) { const row = []; @@ -160,6 +181,13 @@ export default function Tiles({eventsChannel}) { stamp.push(row); } setStamp(stamp); + const indices = []; + for (let sy = 0; sy < selection.h; ++sy) { + for (let sx = 0; sx < selection.w; ++sx) { + indices.push(((selection.y + sy) * wt) + (selection.x + sx)); + } + } + setIndices(indices); }} className={styles.selectionWrapper} ref={wrapperRef} @@ -179,6 +207,25 @@ export default function Tiles({eventsChannel}) { src={TileLayers.layer(0).source.replace('.json', '.png')} />
+
+ + Sel: + {' {'} + {selection.x}{', '} + {selection.y}{', '} + {selection.w}{', '} + {selection.h} + {'}'} + + + Idx: + {' ['} + {indices.join(', ')} + {']'} + +
); } \ No newline at end of file diff --git a/app/react-components/devtools/tiles.module.css b/app/react-components/devtools/tiles.module.css index 8d62aa2..34fa719 100644 --- a/app/react-components/devtools/tiles.module.css +++ b/app/react-components/devtools/tiles.module.css @@ -28,3 +28,16 @@ background-color: #ffffff44; position: absolute; } + +.status { + align-items: end; + display: flex; + font-size: 0.6rem; + gap: 32px; + justify-content: space-between; + margin: 8px; +} + +.selectionStatus { + white-space: nowrap; +}