windows/components/Desktop.vue

96 lines
2.7 KiB
Vue
Raw Normal View History

2025-09-23 16:43:57 +00:00
<script setup lang="ts">
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useWindowsStore } from '../stores/windows';
import { useSettingsStore } from '../stores/settings';
import { useUIStore } from '../stores/ui';
import Window from './Window.vue';
import Taskbar from './Taskbar.vue';
import SnapPreview from './SnapPreview.vue';
import StartMenu from './StartMenu.vue';
import type { SnapType } from '../composables/useDraggable';
const windowsStore = useWindowsStore();
const settingsStore = useSettingsStore();
const uiStore = useUIStore();
const { orderedWindows } = storeToRefs(windowsStore);
const { createWindow, snapWindow } = windowsStore;
const { toggleTheme } = settingsStore;
const { closeStartMenu } = uiStore;
const snapPreview = ref<{ x: number; y: number; width: number; height: number; } | null>(null);
function handleSnapPreview(snapType: SnapType) {
if (!snapType) {
snapPreview.value = null;
return;
}
const taskbarHeight = 48;
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight - taskbarHeight;
switch (snapType) {
case 'left':
snapPreview.value = { x: 0, y: taskbarHeight, width: screenWidth / 2, height: screenHeight };
break;
case 'right':
snapPreview.value = { x: screenWidth / 2, y: taskbarHeight, width: screenWidth / 2, height: screenHeight };
break;
case 'top':
snapPreview.value = { x: 0, y: taskbarHeight, width: screenWidth, height: screenHeight };
break;
}
}
function handleSnapExecute({ windowId, snapType }: { windowId: string; snapType: SnapType }) {
snapPreview.value = null;
if (snapType) {
snapWindow(windowId, snapType);
}
}
function handleDesktopClick() {
closeStartMenu();
}
</script>
<template>
<div class="desktop" @click.self="handleDesktopClick">
<Window
v-for="window in orderedWindows"
:key="window.id"
:window="window"
@snap-preview="handleSnapPreview"
@snap-execute="handleSnapExecute"
/>
<SnapPreview v-if="snapPreview" :preview="snapPreview" />
<StartMenu />
<div class="fixed top-14 left-4 z-[9999] flex flex-col gap-2">
<button @click="() => createWindow('New App')" class="bg-white/20 backdrop-blur-md text-white font-bold py-2 px-4 rounded-lg shadow-lg">
+ Create Window
</button>
<button @click="toggleTheme" class="bg-white/20 backdrop-blur-md text-white font-bold py-2 px-4 rounded-lg shadow-lg">
Toggle Theme
</button>
</div>
<Taskbar />
</div>
</template>
<style scoped>
.desktop {
position: relative;
width: 100vw;
height: 100vh;
background: var(--background-desktop);
overflow: hidden;
padding-top: 48px;
}
</style>