342 lines
8.9 KiB
Vue
342 lines
8.9 KiB
Vue
<script setup lang="ts">
|
|
import OptionsMenu from "./Options/Menu.vue";
|
|
import OptionsRenderingMode from "./Options/RenderingMode.vue";
|
|
import OptionsLanguage from "./Options/Language.vue";
|
|
import Options2048 from "./Options/2048.vue";
|
|
|
|
import UserMenu from "./User/Menu.vue";
|
|
import UserColor from "./User/Color.vue";
|
|
import UserBirthday from "./User/Birthday.vue";
|
|
import UserUserName from "./User/UserName.vue";
|
|
import UserSnake from "./User/Snake.vue";
|
|
|
|
import ClockMenu from "./Clock/Menu.vue";
|
|
import ClockAchievements from "./Clock/Achievements.vue";
|
|
import ClockDate from "./Clock/Date.vue";
|
|
import ClockTime from "./Clock/Time.vue";
|
|
import TouchScreenMenu from "./TouchScreen/Menu.vue";
|
|
import TouchScreenTapTap from "./TouchScreen/TapTap.vue";
|
|
import Selector from "~/components/Common/ButtonSelector.vue";
|
|
|
|
const app = useAppStore();
|
|
const settingsStore = useSettingsStore();
|
|
const { assets } = useAssets();
|
|
const { onRender } = useScreen();
|
|
|
|
onRender((ctx) => {
|
|
if (settingsStore.submenuBackground.opacity > 0) {
|
|
ctx.globalAlpha = settingsStore.submenuBackground.opacity;
|
|
ctx.translate(0, settingsStore.submenuBackground.offsetY);
|
|
assets.images.home.topScreen.background.draw(ctx, 0, 0);
|
|
}
|
|
});
|
|
|
|
if (app.previousScreen === "home") {
|
|
settingsStore.selectedButton = "options";
|
|
}
|
|
|
|
const isMainMenu = (button: string): button is SettingsMenu =>
|
|
SETTINGS_MENUS.includes(button as SettingsMenu);
|
|
|
|
const isSubMenu = (button: string): button is SettingsSubMenu =>
|
|
SETTINGS_SUB_MENUS.includes(button as SettingsSubMenu);
|
|
|
|
const getParentMenu = (submenu: string): SettingsMenu => {
|
|
const match = submenu.match(/^(options|clock|user|touchScreen)/);
|
|
if (!match?.[1]) throw new Error(`Invalid submenu: '${submenu}'`);
|
|
return match[1] as SettingsMenu;
|
|
};
|
|
|
|
const { select, selected, selectorPosition } = useButtonNavigation({
|
|
buttons: {
|
|
options: [31, 119, 49, 49],
|
|
optionsLanguage: [31, 71, 49, 49],
|
|
options2048: [79, 71, 49, 49],
|
|
optionsRenderingMode: [31, 23, 49, 49],
|
|
|
|
clock: [79, 119, 49, 49],
|
|
clockAchievements: [79, 71, 49, 49],
|
|
clockTime: [127, 71, 49, 49],
|
|
clockDate: [79, 23, 49, 49],
|
|
|
|
user: [127, 119, 49, 49],
|
|
userBirthday: [79, 71, 49, 49],
|
|
userUserName: [127, 71, 49, 49],
|
|
userSnake: [175, 71, 49, 49],
|
|
userColor: [127, 23, 49, 49],
|
|
|
|
touchScreen: [175, 119, 49, 49],
|
|
},
|
|
initialButton: settingsStore.selectedButton,
|
|
onButtonClick: (buttonName) => {
|
|
if (isSubMenu(buttonName)) {
|
|
settingsStore.openSubMenu(buttonName);
|
|
} else {
|
|
if (buttonName === "options") select("optionsLanguage");
|
|
if (buttonName === "clock") select("clockAchievements");
|
|
if (buttonName === "user") select("userUserName");
|
|
if (buttonName === "touchScreen")
|
|
settingsStore.openSubMenu("touchScreenTapTap");
|
|
}
|
|
},
|
|
navigation: {
|
|
options: {
|
|
right: "clock",
|
|
up: "optionsLanguage",
|
|
},
|
|
optionsLanguage: {
|
|
down: "options",
|
|
up: "optionsRenderingMode",
|
|
right: "options2048",
|
|
},
|
|
options2048: {
|
|
down: ["options", false],
|
|
left: "optionsLanguage",
|
|
up: ["optionsRenderingMode", false],
|
|
},
|
|
optionsRenderingMode: {
|
|
right: ["options2048", false],
|
|
down: "optionsLanguage",
|
|
},
|
|
|
|
clock: {
|
|
left: "options",
|
|
right: "user",
|
|
up: "clockAchievements",
|
|
},
|
|
clockAchievements: {
|
|
down: "clock",
|
|
up: "clockDate",
|
|
right: "clockTime",
|
|
},
|
|
clockTime: {
|
|
down: ["clock", false],
|
|
left: "clockAchievements",
|
|
up: ["clockDate", false],
|
|
},
|
|
clockDate: {
|
|
right: ["clockTime", false],
|
|
down: "clockAchievements",
|
|
},
|
|
|
|
user: {
|
|
left: "clock",
|
|
right: "touchScreen",
|
|
up: "userUserName",
|
|
},
|
|
userBirthday: {
|
|
down: ["user", false],
|
|
up: ["userColor", false],
|
|
right: "userUserName",
|
|
},
|
|
userUserName: {
|
|
down: "user",
|
|
left: "userBirthday",
|
|
right: "userSnake",
|
|
up: "userColor",
|
|
},
|
|
userSnake: {
|
|
down: ["user", false],
|
|
left: "userUserName",
|
|
up: ["userColor", false],
|
|
},
|
|
userColor: {
|
|
left: ["userBirthday", false],
|
|
right: ["userSnake", false],
|
|
down: "userUserName",
|
|
},
|
|
|
|
touchScreen: {
|
|
left: "user",
|
|
},
|
|
},
|
|
canClickButton: (buttonName) => {
|
|
if (isSubMenu(buttonName)) {
|
|
const parent = getParentMenu(buttonName);
|
|
return settingsStore.currentMenu === parent && settingsStore.menuExpanded;
|
|
}
|
|
return true;
|
|
},
|
|
disabled: computed(
|
|
() =>
|
|
settingsStore.currentSubMenu !== null ||
|
|
settingsStore.submenuTransition.opacity < 1 ||
|
|
settingsStore.isIntro ||
|
|
settingsStore.isOutro ||
|
|
settingsStore.animatingNotification,
|
|
),
|
|
selectorAnimation: {
|
|
duration: 0.11,
|
|
ease: "none",
|
|
},
|
|
});
|
|
|
|
const isSubmenuSelected = computed(() => isSubMenu(selected.value));
|
|
const selectedSubmenuParent = computed(() =>
|
|
isSubmenuSelected.value ? getParentMenu(selected.value) : null,
|
|
);
|
|
|
|
const selectedSubmenuExtraOffsetY = computed(
|
|
() =>
|
|
settingsStore.submenuTransition.selectorOffsetY -
|
|
settingsStore.submenuTransition.offsetY,
|
|
);
|
|
|
|
provide("menusContext", {
|
|
isSubmenuSelected,
|
|
selectedSubmenuParent,
|
|
selectedSubmenuExtraOffsetY,
|
|
});
|
|
|
|
watch(
|
|
selected,
|
|
(newSelected) => {
|
|
settingsStore.selectedButton = newSelected;
|
|
|
|
if (settingsStore.currentSubMenu === null) {
|
|
if (isMainMenu(newSelected)) {
|
|
settingsStore.openMenu(newSelected, false);
|
|
} else if (isSubMenu(newSelected)) {
|
|
const parentMenu = getParentMenu(newSelected);
|
|
if (parentMenu) {
|
|
settingsStore.openMenu(parentMenu, true);
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
);
|
|
|
|
const viewComponents: Record<string, Component> = {
|
|
optionsRenderingMode: OptionsRenderingMode,
|
|
optionsLanguage: OptionsLanguage,
|
|
options2048: Options2048,
|
|
|
|
clockAchievements: ClockAchievements,
|
|
clockDate: ClockDate,
|
|
clockTime: ClockTime,
|
|
|
|
userColor: UserColor,
|
|
userBirthday: UserBirthday,
|
|
userUserName: UserUserName,
|
|
userSnake: UserSnake,
|
|
|
|
touchScreenTapTap: TouchScreenTapTap,
|
|
};
|
|
|
|
const selectorXOffset = computed(() => {
|
|
const menu = isMainMenu(selected.value)
|
|
? selected.value
|
|
: getParentMenu(selected.value);
|
|
|
|
switch (menu) {
|
|
case "clock":
|
|
return Math.min(0, settingsStore.menuOffsets[1]);
|
|
case "user":
|
|
return Math.min(
|
|
0,
|
|
settingsStore.menuOffsets[1] + settingsStore.menuOffsets[2],
|
|
);
|
|
case "touchScreen":
|
|
return Math.min(
|
|
0,
|
|
settingsStore.menuOffsets[1] +
|
|
settingsStore.menuOffsets[2] +
|
|
settingsStore.menuOffsets[3],
|
|
);
|
|
default:
|
|
return 0;
|
|
}
|
|
});
|
|
|
|
const selectorTransitionOffsetY = computed(() => {
|
|
if (isSubmenuSelected.value || selected.value === "touchScreen") {
|
|
return settingsStore.submenuTransition.selectorOffsetY;
|
|
}
|
|
return settingsStore.submenuTransition.offsetY;
|
|
});
|
|
|
|
const handleActivateB = () => {
|
|
if (
|
|
settingsStore.isIntro ||
|
|
settingsStore.isOutro ||
|
|
settingsStore.submenuTransition.opacity < 1
|
|
)
|
|
return;
|
|
|
|
if (isSubmenuSelected.value) {
|
|
select(getParentMenu(selected.value));
|
|
} else {
|
|
settingsStore.animateOutro();
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<template v-if="!settingsStore.currentSubMenu">
|
|
<TouchScreenMenu
|
|
:x="
|
|
177 +
|
|
settingsStore.menuOffsets[1] +
|
|
settingsStore.menuOffsets[2] +
|
|
settingsStore.menuOffsets[3]
|
|
"
|
|
:y="
|
|
121 +
|
|
settingsStore.menuYOffset +
|
|
(selected === 'touchScreen'
|
|
? settingsStore.submenuTransition.selectorOffsetY
|
|
: settingsStore.submenuTransition.offsetY)
|
|
"
|
|
:opacity="settingsStore.submenuTransition.opacity"
|
|
/>
|
|
<UserMenu
|
|
:x="129 + settingsStore.menuOffsets[1] + settingsStore.menuOffsets[2]"
|
|
:y="
|
|
121 +
|
|
settingsStore.menuYOffset +
|
|
settingsStore.submenuTransition.offsetY
|
|
"
|
|
:opacity="settingsStore.submenuTransition.opacity"
|
|
/>
|
|
<ClockMenu
|
|
:x="81 + settingsStore.menuOffsets[1]"
|
|
:y="
|
|
121 +
|
|
settingsStore.menuYOffset +
|
|
settingsStore.submenuTransition.offsetY
|
|
"
|
|
:opacity="settingsStore.submenuTransition.opacity"
|
|
/>
|
|
<OptionsMenu
|
|
:x="33"
|
|
:y="
|
|
121 +
|
|
settingsStore.menuYOffset +
|
|
settingsStore.submenuTransition.offsetY
|
|
"
|
|
:opacity="settingsStore.submenuTransition.opacity"
|
|
/>
|
|
|
|
<Selector
|
|
:rect="[
|
|
selectorPosition[0] + selectorXOffset,
|
|
selectorPosition[1] +
|
|
settingsStore.menuYOffset +
|
|
selectorTransitionOffsetY,
|
|
selectorPosition[2],
|
|
selectorPosition[3],
|
|
]"
|
|
:opacity="settingsStore.submenuTransition.opacity"
|
|
/>
|
|
|
|
<CommonButtons
|
|
:y-offset="settingsStore.barOffsetY"
|
|
:b-label="isSubmenuSelected ? $t('common.goBack') : $t('common.quit')"
|
|
:a-label="$t('common.select')"
|
|
@activate-b="handleActivateB()"
|
|
/>
|
|
</template>
|
|
<component :is="viewComponents[settingsStore.currentSubMenu]" v-else />
|
|
</template>
|