feat(settings): render title and menu image in notification

This commit is contained in:
2025-11-25 18:13:52 +01:00
parent 9f1e2015c6
commit 2e06600293
8 changed files with 128 additions and 53 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

View File

@@ -9,10 +9,10 @@ import DATE_IMAGE from "/assets/images/settings/top-screen/clock/date.webp";
const props = defineProps<{ const props = defineProps<{
x: number; x: number;
y: number; y: number;
isOpen: boolean;
isAnyOtherMenuOpen: boolean;
}>(); }>();
const settingsStore = useSettingsStore();
const [ const [
menuImage, menuImage,
menuActiveImage, menuActiveImage,
@@ -29,12 +29,17 @@ const [
DATE_IMAGE, DATE_IMAGE,
); );
const animation = useMenuAnimation(toRef(() => props.isOpen)); const isOpen = computed(() => settingsStore.isMenuOpen("clock"));
const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("clock"),
);
const animation = useMenuAnimation(isOpen);
useRender((ctx) => { useRender((ctx) => {
ctx.translate(props.x, props.y); ctx.translate(props.x, props.y);
if (props.isOpen || animation.playing) { if (isOpen.value || animation.playing) {
ctx.drawImage( ctx.drawImage(
timeImage!, timeImage!,
48 - animation.stage2Offset, 48 - animation.stage2Offset,
@@ -48,7 +53,7 @@ useRender((ctx) => {
ctx.drawImage(alarmImage!, 0, -48 + animation.stage1Offset); ctx.drawImage(alarmImage!, 0, -48 + animation.stage1Offset);
ctx.drawImage(menuActiveImage!, 0, 0); ctx.drawImage(menuActiveImage!, 0, 0);
} else if (props.isAnyOtherMenuOpen) { } else if (isAnyOtherMenuOpen.value) {
ctx.drawImage(menuDisabledImage!, 0, 0); ctx.drawImage(menuDisabledImage!, 0, 0);
} else { } else {
ctx.drawImage(menuImage!, 0, 0); ctx.drawImage(menuImage!, 0, 0);

View File

@@ -99,43 +99,22 @@ const { selectedButton: selected, selectorPosition } = useButtonNavigation({
}, },
}); });
const isMenuOpen = (menu: string) => { const settingsStore = useSettingsStore();
const regex = new RegExp(`^${menu}[A-Z]`);
return regex.test(selected.value);
};
const isAnyOtherMenuOpen = (excludeMenu: string) => { watch(
return ["options", "clock", "user"] selected,
.filter((menu) => menu !== excludeMenu) (newSelected) => {
.some((menu) => isMenuOpen(menu)); settingsStore.setActiveMenu(newSelected);
}; },
{ immediate: true },
);
</script> </script>
<template> <template>
<OptionsMenu <OptionsMenu :x="33" :y="121" />
:x="33" <ClockMenu :x="81" :y="121" />
:y="121" <UserMenu :x="129" :y="121" />
:is-open="isMenuOpen('options')" <TouchScreenMenu :x="177" :y="121" :opacity="1" />
:is-any-other-menu-open="isAnyOtherMenuOpen('options')"
/>
<ClockMenu
:x="81"
:y="121"
:is-open="isMenuOpen('clock')"
:is-any-other-menu-open="isAnyOtherMenuOpen('clock')"
/>
<UserMenu
:x="129"
:y="121"
:is-open="isMenuOpen('user')"
:is-any-other-menu-open="isAnyOtherMenuOpen('user')"
/>
<TouchScreenMenu
:x="177"
:y="121"
:opacity="1"
:is-any-other-menu-open="isAnyOtherMenuOpen('touchScreen')"
/>
<Selector :rect="selectorPosition" :opacity="1" /> <Selector :rect="selectorPosition" :opacity="1" />
</template> </template>

View File

@@ -9,10 +9,10 @@ import START_UP_IMAGE from "/assets/images/settings/top-screen/options/start-up.
const props = defineProps<{ const props = defineProps<{
x: number; x: number;
y: number; y: number;
isOpen: boolean;
isAnyOtherMenuOpen: boolean;
}>(); }>();
const settingsStore = useSettingsStore();
const [ const [
menuImage, menuImage,
menuActiveImage, menuActiveImage,
@@ -29,12 +29,17 @@ const [
START_UP_IMAGE, START_UP_IMAGE,
); );
const animation = useMenuAnimation(toRef(() => props.isOpen)); const isOpen = computed(() => settingsStore.isMenuOpen("options"));
const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("options"),
);
const animation = useMenuAnimation(isOpen);
useRender((ctx) => { useRender((ctx) => {
ctx.translate(props.x, props.y); ctx.translate(props.x, props.y);
if (props.isOpen || animation.playing) { if (isOpen.value || animation.playing) {
ctx.drawImage(languageImage!, 0, -48 + animation.stage1Offset); ctx.drawImage(languageImage!, 0, -48 + animation.stage1Offset);
ctx.drawImage( ctx.drawImage(
gbaModeImage!, gbaModeImage!,
@@ -48,7 +53,7 @@ useRender((ctx) => {
); );
ctx.drawImage(menuActiveImage!, 0, 0); ctx.drawImage(menuActiveImage!, 0, 0);
} else if (props.isAnyOtherMenuOpen) { } else if (isAnyOtherMenuOpen.value) {
ctx.drawImage(menuDisabledImage!, 0, 0); ctx.drawImage(menuDisabledImage!, 0, 0);
} else { } else {
ctx.drawImage(menuImage!, 0, 0); ctx.drawImage(menuImage!, 0, 0);

View File

@@ -5,16 +5,21 @@ import MENU_DISABLED_IMAGE from "/assets/images/settings/top-screen/touch_screen
const props = defineProps<{ const props = defineProps<{
x: number; x: number;
y: number; y: number;
isAnyOtherMenuOpen: boolean;
}>(); }>();
const settingsStore = useSettingsStore();
const [menuImage, menuDisabledImage] = useImages( const [menuImage, menuDisabledImage] = useImages(
MENU_IMAGE, MENU_IMAGE,
MENU_DISABLED_IMAGE, MENU_DISABLED_IMAGE,
); );
const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("touchScreen"),
);
useRender((ctx) => { useRender((ctx) => {
if (props.isAnyOtherMenuOpen) { if (isAnyOtherMenuOpen.value) {
ctx.drawImage(menuDisabledImage!, props.x, props.y); ctx.drawImage(menuDisabledImage!, props.x, props.y);
} else { } else {
ctx.drawImage(menuImage!, props.x, props.y); ctx.drawImage(menuImage!, props.x, props.y);

View File

@@ -10,10 +10,10 @@ import USER_NAME_IMAGE from "/assets/images/settings/top-screen/user/user-name.w
const props = defineProps<{ const props = defineProps<{
x: number; x: number;
y: number; y: number;
isOpen: boolean;
isAnyOtherMenuOpen: boolean;
}>(); }>();
const settingsStore = useSettingsStore();
const [ const [
menuImage, menuImage,
menuActiveImage, menuActiveImage,
@@ -32,12 +32,17 @@ const [
USER_NAME_IMAGE, USER_NAME_IMAGE,
); );
const animation = useMenuAnimation(toRef(() => props.isOpen)); const isOpen = computed(() => settingsStore.isMenuOpen("user"));
const isAnyOtherMenuOpen = computed(() =>
settingsStore.isAnyOtherMenuOpen("user"),
);
const animation = useMenuAnimation(isOpen);
useRender((ctx) => { useRender((ctx) => {
ctx.translate(props.x, props.y); ctx.translate(props.x, props.y);
if (props.isOpen || animation.playing) { if (isOpen.value || animation.playing) {
ctx.drawImage( ctx.drawImage(
birthdayImage!, birthdayImage!,
-48 + animation.stage2Offset, -48 + animation.stage2Offset,
@@ -56,7 +61,7 @@ useRender((ctx) => {
); );
ctx.drawImage(menuActiveImage!, 0, 0); ctx.drawImage(menuActiveImage!, 0, 0);
} else if (props.isAnyOtherMenuOpen) { } else if (isAnyOtherMenuOpen.value) {
ctx.drawImage(menuDisabledImage!, 0, 0); ctx.drawImage(menuDisabledImage!, 0, 0);
} else { } else {
ctx.drawImage(menuImage!, 0, 0); ctx.drawImage(menuImage!, 0, 0);

View File

@@ -1,10 +1,66 @@
<script setup lang="ts"> <script setup lang="ts">
import NOTIFICATION_IMAGE from "/assets/images/settings/top-screen/notification.webp";
import TITLE_IMAGE from "/assets/images/settings/top-screen/notification-title.webp"; import TITLE_IMAGE from "/assets/images/settings/top-screen/notification-title.webp";
import OPTIONS_IMAGE from "/assets/images/settings/top-screen/options/options.webp";
import CLOCK_IMAGE from "/assets/images/settings/top-screen/clock/clock.webp";
import USER_IMAGE from "/assets/images/settings/top-screen/user/user.webp";
import TOUCH_SCREEN_IMAGE from "/assets/images/settings/top-screen/touch_screen/touch-screen.webp";
const [titleImage] = useImages(TITLE_IMAGE); const store = useSettingsStore();
const [
notificationImage,
titleImage,
optionsImage,
clockImage,
userImage,
touchScreenImage,
] = useImages(
NOTIFICATION_IMAGE,
TITLE_IMAGE,
OPTIONS_IMAGE,
CLOCK_IMAGE,
USER_IMAGE,
TOUCH_SCREEN_IMAGE,
);
const activeMenu = computed(() => {
if (!store.activeMenu) return null;
if (/^options[A-Z]/.test(store.activeMenu)) {
return { text: "Options", image: optionsImage };
}
if (/^clock[A-Z]/.test(store.activeMenu)) {
return { text: "Clock", image: clockImage };
}
if (/^user[A-Z]/.test(store.activeMenu)) {
return { text: "User", image: userImage };
}
if (/^touchScreen[A-Z]/.test(store.activeMenu)) {
return { text: "Touch Screen", image: touchScreenImage };
}
return null;
});
useRender((ctx) => { useRender((ctx) => {
ctx.drawImage(titleImage!, 0, 144); ctx.translate(0, activeMenu.value ? 144 - 16 : 144);
ctx.drawImage(titleImage!, 0, 0);
if (activeMenu.value) {
ctx.translate(0, 16);
ctx.drawImage(notificationImage!, 0, 0);
ctx.drawImage(activeMenu.value.image!, 2, 2);
ctx.font = "10px NDS10";
ctx.fillStyle = "#282828";
ctx.fillText(activeMenu.value.text, 52, 13);
ctx.fillStyle = "#fbfbfb";
ctx.fillText("TODO", 52, 36);
}
}); });
defineOptions({ defineOptions({

View File

@@ -1,3 +1,23 @@
export const useSettingsStore = defineStore("settings", { export const useSettingsStore = defineStore("settings", {
state: () => ({}), state: () => ({
activeMenu: null as string | null,
}),
getters: {
isMenuOpen: (state) => (menu: string) => {
if (!state.activeMenu) return false;
return new RegExp(`^${menu}[A-Z]`).test(state.activeMenu);
},
isAnyOtherMenuOpen: (state) => (excludeMenu: string) => {
if (!state.activeMenu) return false;
const menus = ["options", "clock", "user", "touchScreen"];
return menus
.filter((m) => m !== excludeMenu)
.some((m) => new RegExp(`^${m}[A-Z]`).test(state.activeMenu!));
},
},
actions: {
setActiveMenu(menu: string | null) {
this.activeMenu = menu;
},
},
}); });