feat(buttonNavigation): expose readonly selected button and new select function, to allow user to select any button with path animation

This commit is contained in:
2026-01-14 15:34:02 +01:00
parent 03bbc25f4b
commit 0a8017e34e
4 changed files with 22 additions and 14 deletions

View File

@@ -18,7 +18,7 @@ const ACTIONS = {
[action: "Copy" | "Open", verb: string, content: string] [action: "Copy" | "Open", verb: string, content: string]
>; >;
const { selectedButton, selectorPosition } = useButtonNavigation({ const { selected, selectorPosition } = useButtonNavigation({
buttons: { buttons: {
github: [26, 27, 202, 42], github: [26, 27, 202, 42],
email: [26, 59, 202, 42], email: [26, 59, 202, 42],
@@ -48,7 +48,7 @@ const { selectedButton, selectorPosition } = useButtonNavigation({
disabled: computed(() => store.isIntro || store.isOutro), disabled: computed(() => store.isIntro || store.isOutro),
}); });
const actionateButton = async (button: (typeof selectedButton)["value"]) => { const actionateButton = async (button: (typeof selected)["value"]) => {
const [action, verb, content] = ACTIONS[button]; const [action, verb, content] = ACTIONS[button];
if (action === "Copy") { if (action === "Copy") {
try { try {
@@ -102,7 +102,7 @@ const actionateButton = async (button: (typeof selectedButton)["value"]) => {
: 1 : 1
" "
b-label="Quit" b-label="Quit"
:a-label="ACTIONS[selectedButton][0]" :a-label="ACTIONS[selected][0]"
@activate-b="store.animateOutro()" @activate-b="store.animateOutro()"
/> />
</template> </template>

View File

@@ -7,7 +7,7 @@ const { onRender } = useScreen();
const store = useHomeStore(); const store = useHomeStore();
const { assets } = useAssets(); const { assets } = useAssets();
const { selectedButton, selectorPosition } = useButtonNavigation({ const { selected, selectorPosition } = useButtonNavigation({
buttons: { buttons: {
projects: [31, 23, 193, 49], projects: [31, 23, 193, 49],
contact: [31, 71, 97, 49], contact: [31, 71, 97, 49],
@@ -56,14 +56,14 @@ const { selectedButton, selectorPosition } = useButtonNavigation({
disabled: computed(() => store.isIntro || store.isOutro), disabled: computed(() => store.isIntro || store.isOutro),
}); });
const getButtonOffset = (button: (typeof selectedButton)["value"]) => { const getButtonOffset = (button: (typeof selected)["value"]) => {
if (selectedButton.value === button) return store.outro.buttonOffsetY; if (selected.value === button) return store.outro.buttonOffsetY;
return 0; return 0;
}; };
const getOpacity = (button?: (typeof selectedButton)["value"]) => { const getOpacity = (button?: (typeof selected)["value"]) => {
if (store.isIntro) return store.intro.stage1Opacity; if (store.isIntro) return store.intro.stage1Opacity;
if (selectedButton.value === button) return 1; if (selected.value === button) return 1;
if (store.isOutro) return store.outro.stage1Opacity; if (store.isOutro) return store.outro.stage1Opacity;
return 1; return 1;
}; };

View File

@@ -27,7 +27,7 @@ const getParentMenu = (submenu: string): SettingsMenu => {
return match[1] as SettingsMenu; return match[1] as SettingsMenu;
}; };
const { selectedButton: selected, selectorPosition } = useButtonNavigation({ const { select, selected, selectorPosition } = useButtonNavigation({
buttons: { buttons: {
options: [31, 119, 49, 49], options: [31, 119, 49, 49],
optionsLanguage: [31, 71, 49, 49], optionsLanguage: [31, 71, 49, 49],
@@ -52,9 +52,9 @@ const { selectedButton: selected, selectorPosition } = useButtonNavigation({
if (isSubMenu(buttonName)) { if (isSubMenu(buttonName)) {
settingsStore.openSubMenu(buttonName); settingsStore.openSubMenu(buttonName);
} else { } else {
if (buttonName === "options") selected.value = "optionsLanguage"; if (buttonName === "options") select("optionsLanguage");
if (buttonName === "clock") selected.value = "clockAlarm"; if (buttonName === "clock") select("clockAlarm");
if (buttonName === "user") selected.value = "userName"; if (buttonName === "user") select("userName");
if (buttonName === "touchScreen") throw new Error("Not implemented"); if (buttonName === "touchScreen") throw new Error("Not implemented");
} }
}, },
@@ -183,7 +183,7 @@ const viewComponents: Record<string, Component> = {
:y-offset="0" :y-offset="0"
b-label="Go back" b-label="Go back"
a-label="Select" a-label="Select"
@activate-b="selected = getParentMenu(selected)" @activate-b="select(getParentMenu(selected))"
/> />
<CommonButtons <CommonButtons
v-else v-else

View File

@@ -322,8 +322,16 @@ export const useButtonNavigation = <T extends Record<string, Rect>>({
} }
}); });
const select = (targetButton: Entry) => {
if (isAnimating.value || disabled?.value) return;
const path = findPath(graph, selectedButton.value, targetButton);
animateToButton(targetButton, path);
};
return { return {
selectedButton, selected: readonly(selectedButton),
selectorPosition, selectorPosition,
select,
}; };
}; };