Files
JoyD/AutoRobot/Windows/Robot/Web/src/DockLayout/DockLayout.vue

151 lines
3.4 KiB
Vue
Raw Normal View History

2025-10-31 23:58:26 +08:00
<template>
<div class="dock-layout" ref="dockLayoutRef">
<!-- 浮动区域列表 -->
2025-11-03 17:26:28 +08:00
<Area
v-for="area in floatingAreas"
:key="area.id"
2025-11-03 17:26:28 +08:00
:id="area.id"
:title="area.title"
v-model:WindowState="area.WindowState"
2025-11-03 17:26:28 +08:00
:showTitleBar="area.showTitleBar"
:width="area.width"
:height="area.height"
:left="area.WindowState !== '最大化' ? area.x : undefined"
:top="area.WindowState !== '最大化' ? area.y : undefined"
:style="area.WindowState !== '最大化' ? {
2025-11-03 17:26:28 +08:00
position: 'absolute',
zIndex: 10
} : {
zIndex: 100
}"
2025-11-03 17:26:28 +08:00
@close="onCloseFloatingArea(area.id)"
@update:position="onUpdatePosition(area.id, $event)"
2025-11-03 17:26:28 +08:00
/>
<!-- 主区域 -->
<Area
:WindowState="windowState"
:showTitleBar="false"
title="主区域"
:style="{ position: 'relative', zIndex: 1 }"
/>
</div>
2025-10-31 23:58:26 +08:00
</template>
<script setup>
import { ref, defineExpose, nextTick } from 'vue'
2025-10-31 23:58:26 +08:00
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)
}
2025-11-03 17:26:28 +08:00
// 创建新的Area组件配置
const newArea = {
id: `floating-area-${areaIdCounter++}`,
title: `浮动区域 ${areaIdCounter - 1}`,
x: x,
y: y,
width: 300,
height: 250,
2025-11-03 17:26:28 +08:00
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;
}
2025-11-03 17:26:28 +08:00
/* 浮动区域样式已直接应用到Area组件 */
/* 添加浮动区域按钮样式 */
.add-floating-btn {
font-size: 14px;
cursor: pointer;
user-select: none;
}
.add-floating-btn:active {
transform: scale(0.98);
}
</style>