diff --git a/src/components/Base/BaseSlider.stories.ts b/src/components/Base/BaseSlider.stories.ts new file mode 100644 index 0000000000..58c1e7fd0f --- /dev/null +++ b/src/components/Base/BaseSlider.stories.ts @@ -0,0 +1,33 @@ +import type { Meta, StoryObj } from "@storybook/vue3"; + +import { ref } from "vue"; +import BaseSlider from "./BaseSlider.vue"; + +const meta: Meta = { + component: BaseSlider, + args: { + modelValue: 50, + min: 0, + max: 100, + step: 1, + }, + render: (args) => ({ + components: { BaseSlider }, + setup() { + const model = ref(Number(args.modelValue)); + return { args, model }; + }, + template: ``, + }), +}; + +export default meta; +type Story = StoryObj; + +export const Default: Story = {}; + +export const Disabled: Story = { + args: { + disabled: true, + }, +}; diff --git a/src/components/Base/BaseSlider.vue b/src/components/Base/BaseSlider.vue new file mode 100644 index 0000000000..9dcfe4af55 --- /dev/null +++ b/src/components/Base/BaseSlider.vue @@ -0,0 +1,97 @@ + + + + + diff --git a/src/components/Dialog/PresetManageDialog.vue b/src/components/Dialog/PresetManageDialog.vue index 7b93606357..e8edfb865b 100644 --- a/src/components/Dialog/PresetManageDialog.vue +++ b/src/components/Dialog/PresetManageDialog.vue @@ -1,41 +1,144 @@ @@ -43,9 +146,15 @@ import { computed, ref } from "vue"; import Draggable from "vuedraggable"; import { useStore } from "@/store"; - +import BaseListItem from "@/components/Base/BaseListItem.vue"; +import BaseNavigationView from "@/components/Base/BaseNavigationView.vue"; +import BaseScrollArea from "@/components/Base/BaseScrollArea.vue"; +import BaseIconButton from "@/components/Base/BaseIconButton.vue"; +import BaseSlider from "@/components/Base/BaseSlider.vue"; +import CharacterButton from "@/components/CharacterButton.vue"; import { useDefaultPreset } from "@/composables/useDefaultPreset"; import { Preset, PresetKey } from "@/type/preload"; +import { SLIDER_PARAMETERS } from "@/store/utility"; const props = defineProps<{ openDialog: boolean; @@ -87,6 +196,78 @@ const previewPresetList = computed(() => : presetList.value, ); +const morphingTargetEngines = store.getters.MORPHING_SUPPORTED_ENGINES; + +const selectedPresetKey = ref(); +const selectedPreset = computed(() => { + return previewPresetList.value.find( + (preset) => preset.key === selectedPresetKey.value, + ); +}); + +const parameterConfigs = [ + { + label: "話速", + parameterKey: "speedScale", + }, + { + label: "音高", + parameterKey: "pitchScale", + }, + { + label: "抑揚", + parameterKey: "intonationScale", + }, + { + label: "音量", + parameterKey: "volumeScale", + }, + { + label: "開始無音", + parameterKey: "prePhonemeLength", + }, + { + label: "終了無音", + parameterKey: "postPhonemeLength", + }, +]; + +const getParameterConfig = (sliderKey: string) => { + switch (sliderKey) { + case "SPEED": + return parameterConfigs[0]; + case "PITCH": + return parameterConfigs[1]; + case "INTONATION": + return parameterConfigs[2]; + case "VOLUME": + return parameterConfigs[3]; + case "PRE_PHONEME_LENGTH": + return parameterConfigs[4]; + case "POST_PHONEME_LENGTH": + return parameterConfigs[5]; + } +}; + +const getParameterValue = (sliderKey: string) => { + if (!selectedPreset.value) { + throw new Error("selectedPreset is undefined"); + } + + const parameters = Object.entries(selectedPreset.value); + const parameter = parameters.find( + (preset) => preset[0] === getParameterConfig(sliderKey)?.parameterKey, + ); + + const parameterValue = Number(parameter?.[1]); + + if (Number.isNaN(parameterValue)) { + return; + } + + return parameterValue; +}; + const reorderPreset = (featurePresetList: (Preset & { key: PresetKey })[]) => { const newPresetKeys = featurePresetList.map((item) => item.key); previewPresetKeys.value = newPresetKeys; @@ -115,11 +296,105 @@ const deletePreset = async (key: PresetKey) => { }); } }; + +const morphingTargetCharacterInfo = computed(() => + store.getters + .USER_ORDERED_CHARACTER_INFOS("talk") + ?.find( + (character) => + character.metas.speakerUuid === + selectedPreset.value?.morphingInfo?.targetSpeakerId, + ), +); + +const morphingTargetStyleInfo = computed(() => { + const morphingInfo = selectedPreset.value?.morphingInfo; + + if (!morphingInfo) return; + + return morphingTargetCharacterInfo.value?.metas.styles.find( + (style) => + style.engineId === morphingInfo.targetEngineId && + style.styleId === morphingInfo.targetStyleId, + ); +}); diff --git a/src/styles/v2/mixin.scss b/src/styles/v2/mixin.scss index e547874fa0..7c92fcb95f 100644 --- a/src/styles/v2/mixin.scss +++ b/src/styles/v2/mixin.scss @@ -2,6 +2,7 @@ @mixin on-focus { outline-color: #a5d4ad; outline-width: 2px; + outline-offset: 2px; } // 見出し1(h1)用のスタイル