151 lines
3.4 KiB
Vue
151 lines
3.4 KiB
Vue
<template>
|
|
<div class="dock-layout" ref="dockLayoutRef">
|
|
<!-- 浮动区域列表 -->
|
|
<Area
|
|
v-for="area in floatingAreas"
|
|
:key="area.id"
|
|
:id="area.id"
|
|
:title="area.title"
|
|
v-model:WindowState="area.WindowState"
|
|
:showTitleBar="area.showTitleBar"
|
|
:width="area.width"
|
|
:height="area.height"
|
|
:left="area.WindowState !== '最大化' ? area.x : undefined"
|
|
:top="area.WindowState !== '最大化' ? area.y : undefined"
|
|
:style="area.WindowState !== '最大化' ? {
|
|
position: 'absolute',
|
|
zIndex: 10
|
|
} : {
|
|
zIndex: 100
|
|
}"
|
|
@close="onCloseFloatingArea(area.id)"
|
|
@update:position="onUpdatePosition(area.id, $event)"
|
|
/>
|
|
|
|
<!-- 主区域 -->
|
|
<Area
|
|
:WindowState="windowState"
|
|
:showTitleBar="false"
|
|
title="主区域"
|
|
:style="{ position: 'relative', zIndex: 1 }"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, defineExpose, nextTick } from 'vue'
|
|
import Area from './Area.vue';
|
|
import Panel from './Panel.vue';
|
|
|
|
// 主区域状态
|
|
const windowState = ref('最大化')
|
|
|
|
// 浮动区域列表
|
|
const floatingAreas = ref([])
|
|
|
|
// 容器引用
|
|
const dockLayoutRef = ref(null)
|
|
|
|
// 区域ID计数器
|
|
let areaIdCounter = 1
|
|
|
|
// 添加新的浮动区域
|
|
const addFloatingArea = () => {
|
|
// 获取父容器尺寸以计算居中位置
|
|
let x = 50 + (areaIdCounter - 2) * 20
|
|
let y = 50 + (areaIdCounter - 2) * 20
|
|
|
|
// 如果容器已渲染,计算居中位置
|
|
if (dockLayoutRef.value) {
|
|
const containerRect = dockLayoutRef.value.getBoundingClientRect()
|
|
const width = 300
|
|
const height = 250
|
|
x = Math.floor((containerRect.width - width) / 2)
|
|
y = Math.floor((containerRect.height - height) / 2)
|
|
}
|
|
|
|
// 创建新的Area组件配置
|
|
const newArea = {
|
|
id: `floating-area-${areaIdCounter++}`,
|
|
title: `浮动区域 ${areaIdCounter - 1}`,
|
|
x: x,
|
|
y: y,
|
|
width: 300,
|
|
height: 250,
|
|
WindowState: '正常',
|
|
showTitleBar: true
|
|
}
|
|
floatingAreas.value.push(newArea)
|
|
}
|
|
|
|
// 更新区域位置
|
|
const onUpdatePosition = (id, position) => {
|
|
const area = floatingAreas.value.find(a => a.id === id)
|
|
if (area) {
|
|
area.x = position.left
|
|
area.y = position.top
|
|
}
|
|
}
|
|
|
|
// 切换折叠状态
|
|
const onToggleCollapse = (id) => {
|
|
const area = floatingAreas.value.find(a => a.id === id)
|
|
if (area) {
|
|
area.collapsed = !area.collapsed
|
|
}
|
|
}
|
|
|
|
// 最大化/还原
|
|
const onMaximize = (id) => {
|
|
const area = floatingAreas.value.find(a => a.id === id)
|
|
if (area) {
|
|
// 简单实现:交换宽高
|
|
const temp = area.width
|
|
area.width = area.height
|
|
area.height = temp
|
|
}
|
|
}
|
|
|
|
// 关闭浮动区域
|
|
const onCloseFloatingArea = (id) => {
|
|
const index = floatingAreas.value.findIndex(a => a.id === id)
|
|
if (index !== -1) {
|
|
floatingAreas.value.splice(index, 1)
|
|
}
|
|
}
|
|
|
|
// 切换工具栏
|
|
const onToggleToolbar = (id) => {
|
|
const area = floatingAreas.value.find(a => a.id === id)
|
|
if (area) {
|
|
area.toolbarExpanded = !area.toolbarExpanded
|
|
}
|
|
}
|
|
|
|
// 暴露方法给父组件
|
|
defineExpose({
|
|
addFloatingArea
|
|
})
|
|
</script>
|
|
|
|
<style scoped>
|
|
.dock-layout {
|
|
position: relative;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: visible;
|
|
}
|
|
|
|
/* 浮动区域样式已直接应用到Area组件 */
|
|
|
|
/* 添加浮动区域按钮样式 */
|
|
.add-floating-btn {
|
|
font-size: 14px;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
}
|
|
|
|
.add-floating-btn:active {
|
|
transform: scale(0.98);
|
|
}
|
|
</style> |