<template>
<ui-section>
<div slot="header" class="header flex-1 layout horizontal center-center">
<ui-checkbox
:hidden="!editor._showTick"
v-value="target.enabled.value"
v-values="target.enabled.values"
:multi-values="_updateEnableMulti(target.enabled)"
></ui-checkbox>
<span
@dragstart="dragstart"
@dragend="dragend"
draggable="true"
>
{{ name }}
</span>
<span class="flex-1"></span>
<ui-button
class="tiny transparent"
:title="T('INSPECTOR.component.help')"
:hidden="!editor.help"
@click="openHelpClick"
>
<i class="fa fa-book"></i>
</ui-button>
<ui-button
ref="dropdown"
class="tiny transparent"
title=""
@click="menuClick"
>
<i class="fa fa-cog"></i>
</ui-button>
</div>
<template v-if="!customDraw">
<template v-for="prop in target">
<component
v-if="prop.attrs.visible !== false"
:is="prop.compType"
:target.sync="prop"
:indent="0"
:multi-values="multi"
></component>
</template>
</template>
</ui-section>
</template>
<script>
export default {
name: 'cc-comp-section',
props: {
name: {
type: String,
required: true,
twoWay: true
},
editor: {
type: Object,
required: true,
twoWay: true
},
target: {
type: Object,
required: true,
twoWay: true
},
index: {
type: Number,
default: 0
},
count: {
type: Number,
default: 0
},
multi: {
type: Boolean,
default: false
}
},
methods: {
T: Editor.T, // 假設全局 Editor.T 可用
dragstart(event) {
event.stopPropagation();
Editor.UI.DragDrop.start(event.dataTransfer, {
buildImage: true,
effect: "copyMove",
type: "component",
items: [{ id: this.target.uuid.value, name: this.name }]
});
},
dragend() {
Editor.UI.DragDrop.end();
},
customDraw() {
return this.editor && this.editor.inspector;
},
menuClick(event) {
event.stopPropagation();
if (this._requestID) {
Editor.Ipc.cancelRequest(this._requestID);
this._requestID = null;
}
this._requestID = Editor.Ipc.sendToPanel(
"scene",
"scene:has-copied-component",
(err, hasCopied) => {
if (err) return;
const dropdownRect = this.$refs.dropdown.$el.getBoundingClientRect();
const nodeUuids = this.target.node.values.map(node => node.uuid) || [];
const compUuids = this.target.uuid.values;
Editor.Ipc.sendToPackage(
"inspector",
"popup-component-inspector-menu",
{
nodeUuids,
compUuids,
hasCopyComp: hasCopied,
multi: this.multi,
compIndex: this.index,
compCount: this.count,
x: dropdownRect.left,
y: dropdownRect.bottom + 5
}
);
},
-1
);
},
openHelpClick(event) {
event.stopPropagation();
let helpUrl = this.editor.help;
if (helpUrl.startsWith("i18n:")) {
helpUrl = Editor.T(helpUrl.replace("i18n:", ""));
}
require("electron").shell.openExternal(helpUrl);
},
_updateEnableMulti(prop) {
if (!prop.values) return false;
const firstValue = prop.values[0];
return !prop.values.every(val => val === firstValue);
}
},
mounted() {
if (this.customDraw() && this.editor.inspector) {
Editor.import(this.editor.inspector).then(InspectorModule => {
if (!InspectorModule || typeof InspectorModule !== 'function') {
console.warn(`Failed to load inspector ${this.editor.inspector} for component "${this.name}"`);
return;
}
const createInspector = () => {
const container = document.createElement('div');
this.$el.appendChild(container);
new InspectorModule({
el: container,
propsData: {
target: this.target,
multi: this.multi
}
});
};
// 處理依賴項
const dependencies = InspectorModule.options?.dependencies;
if (dependencies && dependencies.length > 0) {
Editor.import(dependencies).then(() => {
createInspector();
});
} else {
createInspector();
}
});
}
},
beforeDestroy() {
if (this._requestID) {
Editor.Ipc.cancelRequest(this._requestID);
}
}
};
</script>