Skip to content

Commit

Permalink
First iteration of an oject properties tab 🗝️.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmarty committed May 28, 2024
1 parent 3ac9451 commit cb1ab7a
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/components/ColumnListHeader.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const ColumnListHeader = ({ className, children, ...props }) => {
return (
<li
className={clsx(
'bg-slate-500/60 px-1 py-1 text-slate-100 sm:px-2 md:px-3 lg:px-4 xl:px-5',
'bg-slate-500/60 px-1 py-1 text-slate-100 sm:px-2 md:px-3 lg:px-4',
className,
)}
{...props}>
Expand Down
4 changes: 2 additions & 2 deletions src/components/ColumnListItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const ColumnListItem = ({ path, selected, className, children, ...props }) => {
return !path ? (
<li
className={clsx(
'bg-slate-200 px-1 py-1 text-slate-700 sm:px-2 md:px-3 lg:px-4 xl:px-5',
'bg-slate-200 px-1 py-1 text-slate-700 sm:px-2 md:px-3 lg:px-4',
className,
)}
{...props}>
Expand All @@ -19,7 +19,7 @@ const ColumnListItem = ({ path, selected, className, children, ...props }) => {
)}
{...props}>
<Link
className="px-1 py-1 sm:px-2 md:px-3 lg:px-4 xl:px-5"
className="px-1 py-1 sm:px-2 md:px-3 lg:px-4"
to={path}>
{children}
</Link>
Expand Down
43 changes: 43 additions & 0 deletions src/components/RoomObjectProperties.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import ScriptCode from './ScriptCode';

const RoomObjectProperties = ({ object }) => {
if (!object) {
return (
<div className="text-xs">Click the inspect icon next to an object.</div>
);
}

return (
<div className="text-xs">
<h2 className="text-sm">Properties</h2>

<div>
<span>ID: </span>
<span>{object.id}</span>
</div>
<div>
<span>Position: </span>
<span>
{object.x}, {object.y}
</span>
</div>
<div>
<span>Dimension: </span>
<span>
{object.width} x {object.height}
</span>
</div>

{object?.scripts?.length > 0 && <h2 className="pt-4 text-sm">Scripts</h2>}

{object?.scripts?.map(([verb, code]) => (
<div key={verb}>
<h3>{verb}</h3>
<ScriptCode code={code} />
</div>
))}
</div>
);
};

export default RoomObjectProperties;
12 changes: 4 additions & 8 deletions src/components/RoomScripts.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,12 @@ const RoomScripts = ({ excdScript, encdScript }) => {
return (
<div className="flex gap-4 md:gap-5 xl:gap-6">
<div>
<h2>Enter Script</h2>
<div>
<ScriptCode code={encdScript} />
</div>
<h2 className="text-sm">Enter Script</h2>
<ScriptCode code={encdScript} />
</div>
<div>
<h2>Exit Script</h2>
<div>
<ScriptCode code={excdScript} />
</div>
<h2 className="text-sm">Exit Script</h2>
<ScriptCode code={excdScript} />
</div>
</div>
);
Expand Down
3 changes: 2 additions & 1 deletion src/components/RoomTabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { clsx } from 'clsx';
const RoomTabs = ({
currentTab,
setCurrentTab,
allowList = ['Palettes', 'Tilesets', 'Scripts'],
allowList = ['Palettes', 'Tilesets', 'Scripts', 'Object properties'],
}) => {
const tabs = [
{ name: 'Palettes', current: currentTab === 'Palettes' },
{ name: 'Tilesets', current: currentTab === 'Tilesets' },
{ name: 'Scripts', current: currentTab === 'Scripts' },
{ name: 'Object properties', current: currentTab === 'Object properties' },
].filter(({ name }) => allowList.includes(name));

return (
Expand Down
48 changes: 33 additions & 15 deletions src/components/RoomsObjectList.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { clsx } from 'clsx';
import ColumnListHeader from './ColumnListHeader';
import ColumnListItem from './ColumnListItem';
import { MagnifyingGlassCircleIcon as InspectIcon } from '@heroicons/react/16/solid';

const RoomsObjectList = ({
objects,
Expand All @@ -9,6 +10,8 @@ const RoomsObjectList = ({
setHoveredObject,
selectedObjects,
setSelectedObjectState,
inspectedObject,
setInspectedObject,
}) => {
// Objects can be deeply nested (3 levels in room 9).
// This rendering function is recursive.
Expand All @@ -27,6 +30,8 @@ const RoomsObjectList = ({
setHoveredObject={setHoveredObject}
isSelectedObject={selectedObjects[object.id]}
setSelectedObjectState={setSelectedObjectState}
isInspected={inspectedObject === object.id}
setInspectedObject={setInspectedObject}
/>
{childObjects && (
<ol className="bg-slate-200 pl-6">
Expand Down Expand Up @@ -55,22 +60,37 @@ const RoomObject = ({
setHoveredObject,
isSelectedObject,
setSelectedObjectState,
isInspected,
setInspectedObject,
}) => {
// Trim the final @.
const name = object.name.replace(/@+$/, '') || 'Unnamed object';
const namedClass = object.name ? 'first-letter:capitalize' : 'italic';
const id = `object-${object.id}`;

const InspectorButton = () => (
<InspectIcon
strokeWidth="1.5"
className={clsx(
isInspected
? 'text-primary-600'
: 'opacity-0 group-hover:text-slate-400 group-hover:opacity-100',
'size-4 cursor-pointer',
)}
onClick={() => setInspectedObject(object.id)}
/>
);

if (!objectImage?.tiles) {
return (
<ColumnListItem
onMouseOver={() => setHoveredObject(object.id)}
onMouseLeave={() => setHoveredObject(null)}
className={clsx(
'flex whitespace-nowrap pl-6 leading-4 sm:pl-8 md:pl-9 lg:pl-10 xl:pl-11',
'group flex justify-between whitespace-nowrap pl-6 leading-4 sm:pl-8 md:pl-9 lg:pl-10 xl:pl-11',
isHoveredObject && 'bg-slate-300',
)}>
<span className={namedClass}>{name}</span>
<InspectorButton />
</ColumnListItem>
);
}
Expand All @@ -80,23 +100,21 @@ const RoomObject = ({
onMouseOver={() => setHoveredObject(object.id)}
onMouseLeave={() => setHoveredObject(null)}
className={clsx(
'flex gap-1 whitespace-nowrap leading-4 sm:gap-2',
'group flex justify-between gap-1 whitespace-nowrap leading-4 sm:gap-2',
isHoveredObject && 'bg-slate-300',
)}>
<input
type="checkbox"
id={id}
checked={isSelectedObject}
onChange={({ target }) =>
setSelectedObjectState(object.id, target.checked)
}
className="size-4 cursor-pointer rounded border-gray-300 text-primary-600 focus:ring-primary-600"
/>
<label
htmlFor={id}
className={clsx('cursor-pointer', namedClass)}>
<label className={clsx('flex cursor-pointer gap-1 sm:gap-2', namedClass)}>
<input
type="checkbox"
checked={isSelectedObject}
onChange={({ target }) =>
setSelectedObjectState(object.id, target.checked)
}
className="size-4 cursor-pointer rounded border-slate-300 text-primary-600 focus:ring-primary-600"
/>
{name}
</label>
<InspectorButton />
</ColumnListItem>
);
};
Expand Down
2 changes: 1 addition & 1 deletion src/components/ScreenSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const ScreenSelector = ({ rooms, titles }) => {
as="div">
{({ open }) => (
<div className="relative mx-1">
<Label className="block px-1 font-medium leading-6 text-slate-100 sm:px-2 md:px-3 lg:px-4 xl:px-5">
<Label className="block px-1 font-medium leading-6 text-slate-100 sm:px-2 md:px-3 lg:px-4">
<h2>Screen selector</h2>
</Label>
<ListboxButton className="relative w-full cursor-default rounded bg-slate-100 py-1.5 pl-3 pr-10 text-left text-slate-900 shadow-sm ring-1 ring-inset ring-slate-300 focus:outline-none focus:ring-2 focus:ring-primary-600 dark:bg-slate-900 dark:text-slate-100 dark:ring-slate-700">
Expand Down
16 changes: 16 additions & 0 deletions src/containers/RoomsContainer.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PrimaryColumn from '../components/PrimaryColumn';
import Main from '../components/Main';
import ScreenSelector from '../components/ScreenSelector';
import RoomsObjectList from '../components/RoomsObjectList';
import RoomObjectProperties from '../components/RoomObjectProperties';
import RoomsBoxList from '../components/RoomsBoxList';
import Room from '../components/Room';
import RoomTabs from '../components/RoomTabs';
Expand All @@ -20,6 +21,7 @@ const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
const [hoveredBox, setHoveredBox] = useState(null);
const [currentTab, setCurrentTab] = useState('Palettes');
const [room, setRoom] = useState(null);
const [inspectedObject, setInspectedObject] = useState(null);

const currentId = typeof id === 'undefined' ? null : parseInt(id, 10);
const baseTiles = roomgfx?.find(({ metadata }) => metadata.id === 0);
Expand All @@ -38,8 +40,17 @@ const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
selectedObjects[i] = !!(initialState & 0b10000000);
}
setSelectedObjects(selectedObjects);

// Reset the inspected object when the room changes.
setInspectedObject(null);
}, [currentId, globdata, rooms]);

useEffect(() => {
if (inspectedObject !== null) {
setCurrentTab('Object properties');
}
}, [inspectedObject]);

const setSelectedObjectState = (id, state) => {
const newSelectedObjects = [...selectedObjects];
newSelectedObjects[id] = state;
Expand Down Expand Up @@ -90,6 +101,8 @@ const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
setHoveredObject={setHoveredObject}
selectedObjects={selectedObjects}
setSelectedObjectState={setSelectedObjectState}
inspectedObject={inspectedObject}
setInspectedObject={setInspectedObject}
/>
)}
{room?.boxes?.length > 0 && (
Expand Down Expand Up @@ -140,6 +153,9 @@ const RoomsContainer = ({ rooms, titles, roomgfx, globdata }) => {
encdScript={room.encdScript}
/>
)}
{currentTab === 'Object properties' && (
<RoomObjectProperties object={room.objects[inspectedObject]} />
)}
</>
)}
</Main>
Expand Down

0 comments on commit cb1ab7a

Please sign in to comment.