Skip to content

Commit

Permalink
Merge branch 'wip/contextmenu' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
chrismaltby committed Apr 29, 2024
2 parents 6cd9bee + e22e7a7 commit 0e48783
Show file tree
Hide file tree
Showing 47 changed files with 2,600 additions and 375 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add ability to override tile data for auto colored backgrounds by providing a matching *.mono.png in your assets/backgrounds folder containing a monochrome version of the background. When provided this file will be used for tiles data and the regular image will be used to extract the color palettes (useful for mixed color mode games when auto palettes isn't creating tile data as you'd like automatically)
- Add ability to edit waveforms in music editor using keyboard with ability to copy/paste [@pau-tomas](https://github.com/pau-tomas)
- Add ability to restore scene's default palettes in "Set Background Palettes" (especially useful when using auto palettes)
- Add ability to set filename when creating a new song in music editor
- Add context menus when right clicking on list items or on scenes/actors/triggers in world view allowing renaming/deleting

### Changed

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
"@types/styled-components": "^5.1.4",
"@vercel/webpack-asset-relocator-loader": "1.7.3",
"about-window": "^1.15.2",
"chokidar": "^3.5.1",
"chokidar": "^3.6.0",
"chroma-js": "^2.4.2",
"classnames": "^2.2.5",
"commander": "^6.2.0",
Expand Down
35 changes: 30 additions & 5 deletions src/app/project/initProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,12 @@ API.events.watch.sprite.changed.subscribe((_, _filename, data) => {
});

API.events.watch.sprite.removed.subscribe((_, filename, plugin) => {
store.dispatch(entitiesActions.removeSprite({ filename, plugin }));
store.dispatch(
entitiesActions.removedAsset({
assetType: "sprites",
asset: { filename, plugin },
})
);
});

// Watch Backgrounds
Expand All @@ -172,7 +177,12 @@ API.events.watch.background.changed.subscribe((_, _filename, data) => {
});

API.events.watch.background.removed.subscribe((_, filename, plugin) => {
store.dispatch(entitiesActions.removeBackground({ filename, plugin }));
store.dispatch(
entitiesActions.removedAsset({
assetType: "backgrounds",
asset: { filename, plugin },
})
);
});

// Watch Music
Expand All @@ -182,7 +192,12 @@ API.events.watch.music.changed.subscribe((_, _filename, data) => {
});

API.events.watch.music.removed.subscribe((_, filename, plugin) => {
store.dispatch(entitiesActions.removeMusic({ filename, plugin }));
store.dispatch(
entitiesActions.removedAsset({
assetType: "music",
asset: { filename, plugin },
})
);
});

// Watch Sounds
Expand All @@ -192,7 +207,12 @@ API.events.watch.sound.changed.subscribe((_, _filename, data) => {
});

API.events.watch.sound.removed.subscribe((_, filename, plugin) => {
store.dispatch(entitiesActions.removeSound({ filename, plugin }));
store.dispatch(
entitiesActions.removedAsset({
assetType: "sounds",
asset: { filename, plugin },
})
);
});

// Watch Fonts
Expand Down Expand Up @@ -232,7 +252,12 @@ API.events.watch.tileset.changed.subscribe((_, _filename, data) => {
});

API.events.watch.tileset.removed.subscribe((_, filename, plugin) => {
store.dispatch(entitiesActions.removeTileset({ filename, plugin }));
store.dispatch(
entitiesActions.removedAsset({
assetType: "tilesets",
asset: { filename, plugin },
})
);
});

// Watch UI
Expand Down
113 changes: 108 additions & 5 deletions src/components/backgrounds/NavigatorBackgrounds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import l10n from "shared/lib/lang/l10n";
import { useAppDispatch, useAppSelector } from "store/hooks";
import { SplitPaneVerticalDivider } from "ui/splitpane/SplitPaneDivider";
import useSplitPane from "ui/hooks/use-split-pane";
import { MenuDivider, MenuItem } from "ui/menu/Menu";
import { stripInvalidPathCharacters } from "shared/lib/helpers/stripInvalidFilenameCharacters";
import projectActions from "store/features/project/projectActions";

interface NavigatorBackgroundsProps {
height: number;
Expand All @@ -22,13 +25,16 @@ interface NavigatorBackgroundsProps {
interface ImageNavigatorItem {
id: string;
name: string;
type: "background" | "tileset";
}

const imageToNavigatorItem = (
background: Background | Tileset
background: Background | Tileset,
type: "background" | "tileset"
): ImageNavigatorItem => ({
id: background.id,
name: background.name || background.filename,
type,
});

const collator = new Intl.Collator(undefined, {
Expand Down Expand Up @@ -66,15 +72,15 @@ export const NavigatorBackgrounds = ({
useEffect(() => {
setBackgroundItems(
allBackgrounds
.map((background) => imageToNavigatorItem(background))
.map((background) => imageToNavigatorItem(background, "background"))
.sort(sortByName)
);
}, [allBackgrounds]);

useEffect(() => {
setTilesetItems(
allTilesets
.map((tileset) => imageToNavigatorItem(tileset))
.map((tileset) => imageToNavigatorItem(tileset, "tileset"))
.sort(sortByName)
);
}, [allTilesets]);
Expand All @@ -97,6 +103,83 @@ export const NavigatorBackgrounds = ({
direction: "vertical",
});

const [renameId, setRenameId] = useState("");

const listenForRenameStart = useCallback(
(e) => {
if (e.key === "Enter") {
setRenameId(selectedId);
}
},
[selectedId]
);

const onRenameBackgroundComplete = useCallback(
(name: string) => {
if (renameId) {
dispatch(
projectActions.renameBackgroundAsset({
backgroundId: renameId,
newFilename: stripInvalidPathCharacters(name),
})
);
}
setRenameId("");
},
[dispatch, renameId]
);

const onRenameTilesetComplete = useCallback(
(name: string) => {
if (renameId) {
dispatch(
projectActions.renameTilesetAsset({
tilesetId: renameId,
newFilename: stripInvalidPathCharacters(name),
})
);
}
setRenameId("");
},
[dispatch, renameId]
);

const onRenameCancel = useCallback(() => {
setRenameId("");
}, []);

const renderContextMenu = useCallback(
(item: ImageNavigatorItem) => {
return [
<MenuItem key="rename" onClick={() => setRenameId(item.id)}>
{l10n("FIELD_RENAME")}
</MenuItem>,
<MenuDivider key="div-delete" />,
<MenuItem
key="delete"
onClick={() =>
dispatch(
item.type === "background"
? projectActions.removeBackgroundAsset({
backgroundId: item.id,
})
: projectActions.removeTilesetAsset({
tilesetId: item.id,
})
)
}
>
{l10n(
item.type === "background"
? "MENU_DELETE_BACKGROUND"
: "MENU_DELETE_TILESET"
)}
</MenuItem>,
];
},
[dispatch]
);

return (
<>
<Pane style={{ height: splitSizes[0] }}>
Expand All @@ -109,8 +192,18 @@ export const NavigatorBackgrounds = ({
items={backgroundItems}
setSelectedId={setSelectedId}
height={splitSizes[0] - 30}
onKeyDown={listenForRenameStart}
>
{({ item }) => <EntityListItem type="background" item={item} />}
{({ item }) => (
<EntityListItem
type="background"
item={item}
rename={renameId === item.id}
onRename={onRenameBackgroundComplete}
onRenameCancel={onRenameCancel}
renderContextMenu={renderContextMenu}
/>
)}
</FlatList>
</Pane>
<SplitPaneVerticalDivider onMouseDown={onDragStart(0)} />
Expand All @@ -124,8 +217,18 @@ export const NavigatorBackgrounds = ({
items={tilesetItems}
setSelectedId={setSelectedId}
height={splitSizes[1] - 30}
onKeyDown={listenForRenameStart}
>
{({ item }) => <EntityListItem type="background" item={item} />}
{({ item }) => (
<EntityListItem
type="background"
item={item}
rename={renameId === item.id}
onRename={onRenameTilesetComplete}
onRenameCancel={onRenameCancel}
renderContextMenu={renderContextMenu}
/>
)}
</FlatList>
</Pane>
</>
Expand Down
67 changes: 65 additions & 2 deletions src/components/music/NavigatorModSongs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ import styled from "styled-components";
import { NoSongsMessage } from "./NoSongsMessage";
import navigationActions from "store/features/navigation/navigationActions";
import { useAppDispatch, useAppSelector } from "store/hooks";
import { stripInvalidPathCharacters } from "shared/lib/helpers/stripInvalidFilenameCharacters";
import { MenuDivider, MenuItem } from "ui/menu/Menu";
import projectActions from "store/features/project/projectActions";

interface NavigatorSongsProps {
height: number;
Expand All @@ -35,7 +38,7 @@ const EmptyState = styled.div`
const songToNavigatorItem = (song: Music, songIndex: number): NavigatorItem => {
return {
id: song.id,
name: song.filename ? song.filename : `Song ${songIndex + 1}`,
name: song.name ? song.name : `Song ${songIndex + 1}`,
};
};

Expand Down Expand Up @@ -77,6 +80,56 @@ export const NavigatorModSongs = ({
[dispatch]
);

const [renameId, setRenameId] = useState("");

const listenForRenameStart = useCallback(
(e) => {
if (e.key === "Enter") {
setRenameId(selectedId);
}
},
[selectedId]
);

const onRenameSongComplete = useCallback(
(name: string) => {
if (renameId) {
dispatch(
projectActions.renameMusicAsset({
musicId: renameId,
newFilename: stripInvalidPathCharacters(name),
})
);
}
setRenameId("");
},
[dispatch, renameId]
);

const onRenameCancel = useCallback(() => {
setRenameId("");
}, []);

const renderContextMenu = useCallback(
(item: NavigatorItem) => {
return [
<MenuItem key="rename" onClick={() => setRenameId(item.id)}>
{l10n("FIELD_RENAME")}
</MenuItem>,
<MenuDivider key="div-delete" />,
<MenuItem
key="delete"
onClick={() =>
dispatch(projectActions.removeMusicAsset({ musicId: item.id }))
}
>
{l10n("MENU_DELETE_SONG")}
</MenuItem>,
];
},
[dispatch]
);

return (
<>
<Pane style={{ height: height }}>
Expand All @@ -89,8 +142,18 @@ export const NavigatorModSongs = ({
items={items}
setSelectedId={setSelectedId}
height={height - 30}
onKeyDown={listenForRenameStart}
>
{({ item }) => <EntityListItem type="song" item={item} />}
{({ item }) => (
<EntityListItem
type="song"
item={item}
rename={renameId === item.id}
onRename={onRenameSongComplete}
onRenameCancel={onRenameCancel}
renderContextMenu={renderContextMenu}
/>
)}
</FlatList>
) : (
<EmptyState>
Expand Down
Loading

0 comments on commit 0e48783

Please sign in to comment.