Skip to content

Commit

Permalink
refactor: AccentPhrase.vueを新規作成しAudioDetail.vueからアクセント句のコンポーネントを分…
Browse files Browse the repository at this point in the history
…離 Part.2 (VOICEVOX#1569)

Co-authored-by: Hiroshiba <[email protected]>
  • Loading branch information
thiramisu and Hiroshiba authored Sep 23, 2023
1 parent 39701dd commit c188c0c
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 128 deletions.
140 changes: 52 additions & 88 deletions src/components/AccentPhrase.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<template>
<context-menu :menudata="contextMenudata" />
<!-- スライダーここから -->
<!-- アクセント項目のスライダー -->
<template v-if="selectedDetail === 'accent'">
Expand All @@ -20,7 +21,6 @@
>
<audio-parameter
:mora-index="moraIndex"
:accent-phrase-index="index"
:value="mora.pitch"
:ui-locked="uiLocked"
:min="minPitch"
Expand All @@ -46,7 +46,6 @@
<audio-parameter
v-if="mora.consonant && mora.consonantLength != undefined"
:mora-index="moraIndex"
:accent-phrase-index="index"
:value="mora.consonantLength"
:ui-locked="uiLocked"
:min="minMoraLength"
Expand All @@ -61,7 +60,6 @@
<!-- vowel length -->
<audio-parameter
:mora-index="moraIndex"
:accent-phrase-index="index"
:value="mora.vowelLength"
:ui-locked="uiLocked"
:min="minMoraLength"
Expand All @@ -84,7 +82,6 @@
<!-- pause length -->
<audio-parameter
:mora-index="accentPhrase.moras.length"
:accent-phrase-index="index"
:value="accentPhrase.pauseMora.vowelLength"
:ui-locked="uiLocked"
:min="0"
Expand All @@ -102,7 +99,7 @@
<div
class="text-cell"
:class="{
'text-cell-hovered': isHovered(mora.vowel, moraIndex),
'text-cell-highlighted': isEditableMora(mora.vowel, moraIndex),
}"
:style="{
'grid-column': `${moraIndex * 2 + 1} / span 1`,
Expand Down Expand Up @@ -165,9 +162,11 @@
</template>

<script setup lang="ts">
import { computed, reactive } from "vue";
import { computed, ref } from "vue";
import AudioAccent from "./AudioAccent.vue";
import AudioParameter from "./AudioParameter.vue";
import ContextMenu from "./ContextMenu.vue";
import { MenuItemButton } from "./MenuBar.vue";
import { useStore } from "@/store";
import { AudioKey, MoraDataType } from "@/type/preload";
import { Mora } from "@/openapi/models/Mora";
Expand All @@ -184,12 +183,26 @@ const props =
altKeyFlag: boolean;
}>();
type DetailTypes = "accent" | "pitch" | "length" | "play" | "stop" | "save";
type DetailTypes = "accent" | "pitch" | "length";
const store = useStore();
const uiLocked = computed(() => store.getters.UI_LOCKED);
const contextMenudata = ref<[MenuItemButton]>([
{
type: "button",
label: "削除",
onClick: () => {
store.dispatch("COMMAND_DELETE_ACCENT_PHRASE", {
audioKey: props.audioKey,
accentPhraseIndex: props.index,
});
},
disableWhenUiLocked: true,
},
]);
const pronunciation = computed(() => {
let textString = props.accentPhrase.moras.map((mora) => mora.text).join("");
if (props.accentPhrase.pauseMora) {
Expand All @@ -214,95 +227,55 @@ const handleChangePronounce = (newPronunciation: string) => {
});
};
type hoveredType = "vowel" | "consonant";
type hoveredInfoType = {
accentPhraseIndex: number | undefined;
moraIndex?: number | undefined;
type?: hoveredType;
};
const accentHoveredInfo = reactive<hoveredInfoType>({
accentPhraseIndex: undefined,
});
const pitchHoveredInfo = reactive<hoveredInfoType>({
accentPhraseIndex: undefined,
moraIndex: undefined,
});
const lengthHoveredInfo = reactive<hoveredInfoType>({
accentPhraseIndex: undefined,
moraIndex: undefined,
type: "vowel",
});
const hoveredMoraIndex = ref<number | undefined>(undefined);
const handleHoverText = (isOver: boolean, moraIndex: number) => {
if (props.selectedDetail == "accent") {
if (isOver) {
accentHoveredInfo.accentPhraseIndex = props.index;
} else {
accentHoveredInfo.accentPhraseIndex = undefined;
}
} else if (props.selectedDetail == "pitch") {
if (isOver) {
pitchHoveredInfo.accentPhraseIndex = props.index;
pitchHoveredInfo.moraIndex = moraIndex;
} else {
pitchHoveredInfo.accentPhraseIndex = undefined;
pitchHoveredInfo.moraIndex = undefined;
}
if (props.selectedDetail == "accent" || props.selectedDetail == "pitch") {
hoveredMoraIndex.value = isOver ? moraIndex : undefined;
}
};
const lengthHoveredPhonemeType = ref<"vowel" | "consonant">("vowel");
const handleLengthHoverText = (
isOver: boolean,
phoneme: MoraDataType,
phraseIndex: number,
moraIndex?: number
moraIndex: number
) => {
if (phoneme !== "vowel" && phoneme !== "consonant")
throw new Error("phoneme != hoveredType");
lengthHoveredInfo.type = phoneme;
lengthHoveredPhonemeType.value = phoneme;
// the pause and pitch templates don't emit a mouseOver event
if (isOver) {
lengthHoveredInfo.accentPhraseIndex = phraseIndex;
lengthHoveredInfo.moraIndex = moraIndex;
} else {
lengthHoveredInfo.accentPhraseIndex = undefined;
lengthHoveredInfo.moraIndex = undefined;
}
hoveredMoraIndex.value = isOver ? moraIndex : undefined;
};
const unvoicableVowels = ["U", "I", "i", "u"];
const isHovered = (vowel: string, moraIndex: number) => {
let isHover = false;
if (!uiLocked.value) {
if (props.selectedDetail == "accent") {
if (props.index === accentHoveredInfo.accentPhraseIndex) {
isHover = true;
}
} else if (props.selectedDetail == "pitch") {
if (
props.index === pitchHoveredInfo.accentPhraseIndex &&
moraIndex === pitchHoveredInfo.moraIndex &&
unvoicableVowels.includes(vowel)
) {
isHover = true;
}
}
/**
* 各モーラが、hover中のモーラをそのままクリックした場合に編集範囲に含まれるかどうか。
* 強調表示するかの判定に使われる。
*/
const isEditableMora = (vowel: string, moraIndex: number) => {
if (uiLocked.value) {
return false;
}
return isHover;
if (props.selectedDetail == "accent") {
// クリック時の動作はそのアクセント句の読み変更。
// よって、いずれかのモーラがhoverされているならそのアクセント句を強調表示する。
return hoveredMoraIndex.value !== undefined;
}
if (props.selectedDetail == "pitch") {
// クリック時の動作は無声化/有声化の切り替え。
// よって、hover中のモーラが無声化可能かを判定しそのモーラを強調表示する。
return (
moraIndex === hoveredMoraIndex.value && unvoicableVowels.includes(vowel)
);
}
return false;
};
const getHoveredText = (mora: Mora, moraIndex: number) => {
if (props.selectedDetail != "length") return mora.text;
if (
props.index === lengthHoveredInfo.accentPhraseIndex &&
moraIndex === lengthHoveredInfo.moraIndex
) {
if (lengthHoveredInfo.type == "vowel") {
if (moraIndex === hoveredMoraIndex.value) {
if (lengthHoveredPhonemeType.value == "vowel") {
return mora.vowel.toUpperCase();
} else {
return mora.consonant?.toUpperCase();
Expand Down Expand Up @@ -335,11 +308,11 @@ const minPitch = 3;
const maxMoraLength = 0.3;
const minMoraLength = 0;
const changeMoraData = (
accentPhraseIndex: number,
moraIndex: number,
data: number,
type: MoraDataType
) => {
const accentPhraseIndex = props.index;
if (!props.altKeyFlag) {
if (type == "pitch") {
lastPitches.value[moraIndex] = data;
Expand Down Expand Up @@ -376,7 +349,7 @@ const handleChangeVoicing = (mora: Mora, moraIndex: number) => {
data = lastPitches.value[moraIndex];
}
}
changeMoraData(props.index, moraIndex, data, "voicing");
changeMoraData(moraIndex, data, "voicing");
}
};
</script>
Expand All @@ -399,7 +372,7 @@ const handleChangeVoicing = (mora: Mora, moraIndex: number) => {
transform: translateX(-50%);
z-index: 10;
}
.text-cell-hovered {
.text-cell-highlighted {
font-weight: bold;
cursor: pointer;
}
Expand All @@ -426,15 +399,6 @@ const handleChangeVoicing = (mora: Mora, moraIndex: number) => {
min-width: 20px;
max-width: 20px;
}
.accent-cell {
grid-row: 2 / span 1;
div {
min-width: 20px + 20px;
max-width: 20px + 20px;
display: inline-block;
cursor: pointer;
}
}
.pitch-cell {
grid-row: 1 / span 2;
min-width: 20px;
Expand Down
30 changes: 1 addition & 29 deletions src/components/AudioDetail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@
]"
@click="setPlayAndStartPoint(accentPhraseIndex)"
>
<context-menu :menudata="accentPhraseMenudata(accentPhraseIndex)" />
<accent-phrase
:audio-key="activeAudioKey"
:accent-phrase="accentPhrase"
Expand Down Expand Up @@ -101,8 +100,6 @@ import {
} from "vue";
import ToolTip from "./ToolTip.vue";
import AccentPhrase from "./AccentPhrase.vue";
import ContextMenu from "./ContextMenu.vue";
import { MenuItemButton } from "./MenuBar.vue";
import { useStore } from "@/store";
import {
AudioKey,
Expand Down Expand Up @@ -193,7 +190,7 @@ const hotkeyMap = new Map<HotkeyAction, () => HotkeyReturnType>([
setHotkeyFunctions(hotkeyMap, true);
// detail selector
type DetailTypes = "accent" | "pitch" | "length" | "play" | "stop" | "save";
type DetailTypes = "accent" | "pitch" | "length";
const selectedDetail = ref<DetailTypes>("accent");
// accent phrase
Expand Down Expand Up @@ -248,22 +245,6 @@ const setPlayAndStartPoint = (accentPhraseIndex: number) => {
}
};
// accentPhraseIndexごとにcontext-menuの内容を用意する
const accentPhraseMenudata = computed(() => (accentPhraseIndex: number): [
MenuItemButton
] => {
return [
{
type: "button",
label: "削除",
onClick: async () => {
deleteAccentPhrase(accentPhraseIndex);
},
disableWhenUiLocked: true,
},
];
});
watch(accentPhrases, async () => {
activePoint.value = startPoint.value;
// 連続再生時に、最初に選択されていた場所に戻るためにscrollToActivePointを呼ぶ必要があるが、
Expand All @@ -272,13 +253,6 @@ watch(accentPhrases, async () => {
scrollToActivePoint();
});
const deleteAccentPhrase = (phraseIndex: number) => {
store.dispatch("COMMAND_DELETE_ACCENT_PHRASE", {
audioKey: props.activeAudioKey,
accentPhraseIndex: phraseIndex,
});
};
// audio play
const play = async () => {
try {
Expand Down Expand Up @@ -423,8 +397,6 @@ onUnmounted(() => {
<style scoped lang="scss">
@use '@/styles/colors' as colors;
$pitch-label-height: 24px;
.tip-tweakable-slider-by-scroll {
position: absolute;
right: 4px;
Expand Down
13 changes: 2 additions & 11 deletions src/components/AudioParameter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ import { MoraDataType } from "@/type/preload";
const props = withDefaults(
defineProps<{
value: number;
accentPhraseIndex: number;
moraIndex: number;
uiLocked: boolean;
min?: number;
Expand All @@ -72,7 +71,6 @@ const emit =
defineEmits<{
(
e: "changeValue",
accentPhraseIndex: number,
moraIndex: number,
newValue: number,
type: MoraDataType
Expand All @@ -81,13 +79,12 @@ const emit =
e: "mouseOver",
isOver: boolean,
type: MoraDataType,
accentPhraseIndex: number,
moraIndex: number
): void;
}>();
const changeValue = (newValue: number, type: MoraDataType = props.type) =>
emit("changeValue", props.accentPhraseIndex, props.moraIndex, newValue, type);
emit("changeValue", props.moraIndex, newValue, type);
const previewSlider = previewSliderHelper({
modelValue: () => props.value,
Expand Down Expand Up @@ -120,13 +117,7 @@ const clipPathComputed = computed((): string => {
const handleMouseHover = (isOver: boolean) => {
valueLabel.visible = isOver;
if (props.type == "consonant" || props.type == "vowel") {
emit(
"mouseOver",
isOver,
props.type,
props.accentPhraseIndex,
props.moraIndex
);
emit("mouseOver", isOver, props.type, props.moraIndex);
}
};
Expand Down

0 comments on commit c188c0c

Please sign in to comment.