Files
JoyD/AutoRobot/Windows/Robot/Web/src/components/DockPanel.js

184 lines
4.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { ref, computed, h } from 'vue';
const DockPanel = {
name: 'DockPanel',
props: {
panel: {
type: Object,
required: true
},
position: {
type: String,
required: true
},
index: {
type: Number,
required: true
}
},
emits: ['close', 'float', 'collapse', 'expand', 'move', 'showContextMenu'],
setup(props, { emit }) {
const isDragging = ref(false)
const dragStart = ref({ x: 0, y: 0 })
// 简化样式计算逻辑大部分样式通过CSS类实现
const panelStyle = computed(() => {
const style = {}
// 尺寸样式
if (props.panel.width) {
style.width = `${props.panel.width}px`
}
if (props.panel.height) {
style.height = `${props.panel.height}px`
}
// 折叠状态样式
if (props.panel.isCollapsed) {
if (props.position === 'left' || props.position === 'right') {
style.width = '40px'
} else {
style.height = '40px'
}
}
return style
})
const handleClose = () => {
emit('close', props.panel.id)
}
const handleFloat = () => {
emit('float', props.panel.id)
}
const handleCollapse = () => {
emit('collapse', props.panel.id)
}
const handleExpand = () => {
emit('expand', props.panel.id)
}
const handleDragStart = (e) => {
isDragging.value = true
dragStart.value = { x: e.clientX, y: e.clientY }
e.stopPropagation()
}
const handleDragMove = (e) => {
if (isDragging.value) {
const dx = e.clientX - dragStart.value.x
const dy = e.clientY - dragStart.value.y
emit('move', props.panel.id, { x: dx, y: dy })
dragStart.value = { x: e.clientX, y: e.clientY }
e.preventDefault()
e.stopPropagation()
}
}
const handleDragEnd = () => {
isDragging.value = false
}
const handleContextMenu = (e) => {
e.preventDefault()
emit('showContextMenu', props.panel.id, { x: e.clientX, y: e.clientY })
}
const renderIcon = () => {
if (props.panel.icon) {
return h('div', { class: 'dock-panel-icon' }, props.panel.icon)
}
return null
}
const renderTitle = () => {
if (props.panel.title) {
return h('div', { class: 'dock-panel-title' }, props.panel.title)
}
return null
}
const renderContent = () => {
if (props.panel.content) {
// 检查内容是否是HTML字符串
if (typeof props.panel.content === 'string' && props.panel.content.includes('<')) {
// 对于HTML字符串创建一个div容器并使用innerHTML设置内容
const div = document.createElement('div');
div.innerHTML = props.panel.content;
return h('div', {
class: 'dock-panel-html-content',
innerHTML: props.panel.content
});
} else {
// 对于组件或普通文本,正常处理
return h(props.panel.content, {
panelId: props.panel.id,
...props.panel.props
})
}
}
return h('div', { class: 'dock-panel-empty-content' }, 'Empty Panel')
}
return () => {
// 面板根元素
return h('div', {
class: [
'dock-panel',
`dock-panel-${props.position}`,
{ 'dock-panel-collapsed': props.panel.isCollapsed }
],
style: panelStyle.value,
onMousedown: handleDragStart,
onMousemove: handleDragMove,
onMouseup: handleDragEnd,
onMouseleave: handleDragEnd,
onContextmenu: handleContextMenu
}, [
// 折叠状态下的展开按钮
props.panel.isCollapsed ? (
h('div', {
class: 'dock-panel-expand-btn',
onClick: handleExpand,
title: props.panel.title
}, renderIcon())
) : (
// 非折叠状态
[
// 标题栏
h('div', {
class: 'dock-panel-titlebar'
}, [
renderIcon(),
renderTitle(),
h('div', { class: 'dock-panel-actions' }, [
h('button', {
class: 'dock-panel-btn dock-panel-collapse-btn',
onClick: handleCollapse,
title: 'Collapse'
}, '◀'),
h('button', {
class: 'dock-panel-btn dock-panel-float-btn',
onClick: handleFloat,
title: 'Float'
}, '↗'),
h('button', {
class: 'dock-panel-btn dock-panel-close-btn',
onClick: handleClose,
title: 'Close'
}, '×')
])
]),
// 内容区
h('div', { class: 'dock-panel-content' }, renderContent())
]
)
])
}
}
}
export default DockPanel