Skip to content

Commit

Permalink
マルチトラック:インポートに対応 (#2126)
Browse files Browse the repository at this point in the history
* Change: SET_TRACKを作る

* Add: インポートをマルチトラック対応

* Add: 複数トラックをインポートできるように

* Fix: indexじゃなくてiだった

* Add: 共通化 + undo出来るように

* Change: トラック選択のUIを変更

* Change: mapを使う

* Change: isTracksEmptyを移動

* Change: IMPORT_*_PROJECTをCOMMANDに

* Add: isValidTrackチェックを追加

* Change: QCheckboxを使う

* Change: 見た目を良い感じにする

* デザインちょっと調整

---------

Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
sevenc-nanashi and Hiroshiba authored Jun 30, 2024
1 parent f05d174 commit 7771ae9
Show file tree
Hide file tree
Showing 4 changed files with 321 additions and 193 deletions.
151 changes: 90 additions & 61 deletions src/components/Dialog/ImportSongProjectDialog.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
<template>
<QDialog ref="dialogRef" autoScroll @beforeShow="initializeValues">
<QLayout container view="hHh lpr fFf" class="q-dialog-plugin bg-background">
<QHeader>
<QToolbar>
<QToolbarTitle class="text-display">インポート</QToolbarTitle>
</QToolbar>
</QHeader>
<QPageContainer class="q-px-lg">
<QDialog ref="dialogRef" @beforeShow="initializeValues">
<QCard class="q-py-sm q-px-md dialog-card">
<QCardSection>
<div class="text-h5">インポート</div>
</QCardSection>

<QSeparator />

<QCardSection class="q-py-none">
<details class="q-pt-md">
<summary>対応しているプロジェクトファイル</summary>
<summary>対応しているファイル形式</summary>
<ul>
<li
v-for="[name, extensions] in projectNameToExtensions"
Expand All @@ -25,46 +26,62 @@
:accept="acceptExtensions"
:errorMessage="projectFileErrorMessage"
:error="!!projectFileErrorMessage"
placeholder="外部プロジェクトファイルを選択してください"
placeholder="ファイルを選択してください"
@input="handleFileChange"
/>
<QSelect
v-if="project"
v-model="selectedTrack"
:options="trackOptions"
:disable="projectFileErrorMessage != undefined"
emitValue
mapOptions
label="インポートするトラック"
</QCardSection>
<QCardSection v-if="trackOptions.length > 0">
<QList bordered class="rounded-borders scroll scrollable-area">
<QItem
v-for="(track, index) in trackOptions"
:key="track.value"
tag="label"
:disable="track.disable"
>
<QItemSection avatar>
<QCheckbox
v-model="selectedTrackIndexes"
:val="track.value"
:disable="track.disable"
/>
</QItemSection>
<QItemSection>
<QItemLabel> {{ index + 1 }}:{{ track.name }} </QItemLabel>
<QItemLabel caption>ノート数:{{ track.noteLength }}</QItemLabel>
</QItemSection>
</QItem>
</QList>
</QCardSection>

<QSeparator />

<QCardActions>
<QSpace />
<QBtn
unelevated
align="right"
label="キャンセル"
color="toolbar-button"
textColor="toolbar-button-display"
class="text-no-wrap text-bold q-mr-sm"
@click="handleCancel"
/>
<QBtn
unelevated
align="right"
label="インポート"
color="toolbar-button"
textColor="toolbar-button-display"
class="text-no-wrap text-bold q-mr-sm"
:disabled="
selectedTrackIndexes == null ||
selectedTrackIndexes.length === 0 ||
projectFileErrorMessage != undefined
"
@click="handleImportTrack"
/>
</QPageContainer>
<QFooter>
<QToolbar>
<QSpace />
<QBtn
unelevated
align="right"
label="キャンセル"
color="toolbar-button"
textColor="toolbar-button-display"
class="text-no-wrap text-bold q-mr-sm"
@click="handleCancel"
/>
<QBtn
unelevated
align="right"
label="インポート"
color="toolbar-button"
textColor="toolbar-button-display"
class="text-no-wrap text-bold q-mr-sm"
:disabled="
selectedTrack == null || projectFileErrorMessage != undefined
"
@click="handleImportTrack"
/>
</QToolbar>
</QFooter>
</QLayout>
</QCardActions>
</QCard>
</QDialog>
</template>

Expand Down Expand Up @@ -201,24 +218,22 @@ const trackOptions = computed(() => {
return [];
}
// トラックリストを生成
// "トラックNo: トラック名 / ノート数" の形式で表示
const tracks = getProjectTracks(project.value);
return tracks.map((track, index) => ({
label: `${index + 1}: ${track?.name || "(トラック名なし)"} / ノート数:${
track.noteLength
}`,
name: track?.name,
noteLength: track.noteLength,
value: index,
disable: track.disable,
}));
});
// 選択中のトラック
const selectedTrack = ref<number | null>(null);
const selectedTrackIndexes = ref<number[] | null>(null);
// データ初期化
const initializeValues = () => {
projectFile.value = null;
project.value = null;
selectedTrack.value = null;
selectedTrackIndexes.value = null;
};
// ファイル変更時
Expand All @@ -236,7 +251,7 @@ const handleFileChange = async (event: Event) => {
// 既存のデータおよび選択中のトラックをクリア
project.value = null;
selectedTrack.value = null;
selectedTrackIndexes.value = null;
error.value = null;
const file = input.files[0];
Expand All @@ -259,12 +274,14 @@ const handleFileChange = async (event: Event) => {
}),
};
}
selectedTrack.value = getProjectTracks(project.value).findIndex(
const firstSelectableTrack = getProjectTracks(project.value).findIndex(
(track) => !track.disable,
);
if (selectedTrack.value === -1) {
selectedTrack.value = 0;
if (firstSelectableTrack === -1) {
error.value = "emptyProject";
return;
}
selectedTrackIndexes.value = [firstSelectableTrack];
} catch (e) {
log.error(e);
error.value = "unknown";
Expand All @@ -281,19 +298,19 @@ const handleFileChange = async (event: Event) => {
// トラックインポート実行時
const handleImportTrack = () => {
// ファイルまたは選択中のトラックが未設定の場合はエラー
if (project.value == null || selectedTrack.value == null) {
if (project.value == null || selectedTrackIndexes.value == null) {
throw new Error("project or selected track is not set");
}
// トラックをインポート
if (project.value.type === "vvproj") {
store.dispatch("IMPORT_VOICEVOX_PROJECT", {
store.dispatch("COMMAND_IMPORT_VOICEVOX_PROJECT", {
project: project.value.project,
trackIndex: selectedTrack.value,
trackIndexes: selectedTrackIndexes.value,
});
} else {
store.dispatch("IMPORT_UTAFORMATIX_PROJECT", {
store.dispatch("COMMAND_IMPORT_UTAFORMATIX_PROJECT", {
project: project.value.project,
trackIndex: selectedTrack.value,
trackIndexes: selectedTrackIndexes.value,
});
}
onDialogOK();
Expand All @@ -304,3 +321,15 @@ const handleCancel = () => {
onDialogCancel();
};
</script>

<style scoped lang="scss">
.dialog-card {
width: 700px;
max-width: 80vw;
}
.scrollable-area {
overflow-y: auto;
max-height: calc(100vh - 100px - 295px);
}
</style>
3 changes: 3 additions & 0 deletions src/sing/domain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ const BEAT_TYPES = [2, 4, 8, 16];
const MIN_BPM = 40;
const MAX_SNAP_TYPE = 32;

export const isTracksEmpty = (tracks: Track[]) =>
tracks.length === 0 || (tracks.length === 1 && tracks[0].notes.length === 0);

export const isValidTpqn = (tpqn: number) => {
return (
Number.isInteger(tpqn) &&
Expand Down
Loading

0 comments on commit 7771ae9

Please sign in to comment.