57 lines
1.8 KiB
Vue
57 lines
1.8 KiB
Vue
<template>
|
||
<div
|
||
class="icon-container"
|
||
:style="`grid-column: ${iconInfo.x}/${iconInfo.x + 1};grid-row: ${iconInfo.y}/${iconInfo.y + 1};`"
|
||
draggable="true"
|
||
@dragstart="onDragStart"
|
||
@dragend="onDragEnd"
|
||
>
|
||
{{ iconInfo.name }}
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { IDesktopAppIcon } from '@/core/desktop/types/IDesktopAppIcon.ts'
|
||
import type { IGridTemplateParams } from '@/core/desktop/types/IGridTemplateParams.ts'
|
||
import XSystem from '@/core/XSystem.ts'
|
||
import { DesktopEventEnum } from '@/core/events/EventTypes.ts'
|
||
|
||
const { iconInfo, gridTemplate } = defineProps<{ iconInfo: IDesktopAppIcon, gridTemplate: IGridTemplateParams }>()
|
||
|
||
const onDragStart = (e: DragEvent) => {}
|
||
|
||
const onDragEnd = (e: DragEvent) => {
|
||
const el = e.target as HTMLElement | null
|
||
if (!el) return
|
||
// 鼠标所在位置已存在图标元素
|
||
const pointTarget = document.elementFromPoint(e.clientX, e.clientY)
|
||
if (!pointTarget) return
|
||
if (pointTarget.classList.contains('icon-container')) return
|
||
if (!pointTarget.classList.contains('desktop-container')) return
|
||
|
||
// 获取容器边界
|
||
const rect = el.parentElement!.getBoundingClientRect()
|
||
|
||
// 鼠标相对容器左上角坐标
|
||
const mouseX = e.clientX - rect.left
|
||
const mouseY = e.clientY - rect.top
|
||
|
||
// 计算鼠标所在单元格坐标(向上取整,从1开始)
|
||
const gridX = Math.ceil(mouseX / gridTemplate.cellRealWidth)
|
||
const gridY = Math.ceil(mouseY / gridTemplate.cellRealHeight)
|
||
|
||
iconInfo.x = gridX
|
||
iconInfo.y = gridY
|
||
|
||
XSystem.instance.eventManages.notifyEvent(DesktopEventEnum.onDesktopAppIconPos, iconInfo)
|
||
}
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.icon-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
@apply flex flex-col items-center justify-center bg-gray-200;
|
||
}
|
||
</style>
|