|
@@ -0,0 +1,260 @@
|
|
|
+<template>
|
|
|
+ <div class="props">
|
|
|
+ <t-tabs v-model="data.tab">
|
|
|
+ <t-tab-panel :value="1" label="布局容器">
|
|
|
+ <t-space direction="vertical" class="py-16 w-full">
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label style="width: 67px">ID</label>
|
|
|
+ <div style="padding-left: 8px; line-height: 30px">
|
|
|
+ {{ data.fit.id }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12" style="margin-top: -12px">
|
|
|
+ <label style="width: 50px">名称</label>
|
|
|
+ <div style="padding-left: 8px; line-height: 30px">
|
|
|
+ <t-input
|
|
|
+ class="ml-8"
|
|
|
+ v-model="data.fit.name"
|
|
|
+ placeholder="默认0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label>靠左</label>
|
|
|
+ <div class="flex center" style="align-items: center">
|
|
|
+ <t-switch size="small" v-model="data.fit.left" />
|
|
|
+ <t-input-number
|
|
|
+ theme="normal"
|
|
|
+ class="ml-8"
|
|
|
+ @change="onFitChange"
|
|
|
+ v-model="data.fit.leftValue"
|
|
|
+ placeholder="默认0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label>靠右</label>
|
|
|
+ <div class="flex center" style="align-items: center">
|
|
|
+ <t-switch size="small" v-model="data.fit.right" />
|
|
|
+ <t-input-number
|
|
|
+ theme="normal"
|
|
|
+ class="ml-8"
|
|
|
+ @change="onFitChange"
|
|
|
+ v-model="data.fit.rightValue"
|
|
|
+ placeholder="默认0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label>靠上</label>
|
|
|
+ <div class="flex center" style="align-items: center">
|
|
|
+ <t-switch size="small" v-model="data.fit.top" />
|
|
|
+ <t-input-number
|
|
|
+ theme="normal"
|
|
|
+ class="ml-8"
|
|
|
+ @change="onFitChange"
|
|
|
+ v-model="data.fit.topValue"
|
|
|
+ placeholder="默认0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label>靠下</label>
|
|
|
+ <div class="flex center" style="align-items: center">
|
|
|
+ <t-switch size="small" v-model="data.fit.bottom" />
|
|
|
+ <t-input-number
|
|
|
+ theme="normal"
|
|
|
+ class="ml-8"
|
|
|
+ v-model="data.fit.bottomValue"
|
|
|
+ @change="onFitChange"
|
|
|
+ placeholder="默认0"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="form-item px-12">
|
|
|
+ <label>展示图元</label>
|
|
|
+ <div>
|
|
|
+ <t-switch size="small" @change="fitPenVisible" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="px-12">
|
|
|
+ <div class="mb-8">图元列表</div>
|
|
|
+ <div class="grid head">
|
|
|
+ <div class="title">名称</div>
|
|
|
+ <div class="title">图元id</div>
|
|
|
+ <div class="title">操作</div>
|
|
|
+ </div>
|
|
|
+ <div class="body">
|
|
|
+ <div
|
|
|
+ :data-penid="item.value"
|
|
|
+ v-for="(item, i) in data.list"
|
|
|
+ class="grid"
|
|
|
+ :class="data.active.includes(item.value) ? 'active' : ''"
|
|
|
+ >
|
|
|
+ <span class="hover" @click="doActive(item.value)">
|
|
|
+ {{ item.label }}
|
|
|
+ </span>
|
|
|
+ <span class="hover" @click="doActive(item.value)">
|
|
|
+ {{ item.value }}
|
|
|
+ </span>
|
|
|
+ <t-popconfirm content="确认移除吗" @confirm="doRemove(i)">
|
|
|
+ <t-tooltip content="从布局容器中移除此图元">
|
|
|
+ <div class="hover"><delete-icon /></div>
|
|
|
+ </t-tooltip>
|
|
|
+ </t-popconfirm>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </t-space>
|
|
|
+ </t-tab-panel>
|
|
|
+ </t-tabs>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import {
|
|
|
+ reactive,
|
|
|
+ onBeforeMount,
|
|
|
+ ref,
|
|
|
+ watch,
|
|
|
+ onUnmounted,
|
|
|
+ onMounted,
|
|
|
+} from 'vue';
|
|
|
+import { useSelection } from '@/services/selections';
|
|
|
+import { DeleteIcon } from 'tdesign-icons-vue-next';
|
|
|
+
|
|
|
+const data = reactive({
|
|
|
+ fit: undefined,
|
|
|
+ tab: 1,
|
|
|
+ list: [],
|
|
|
+ active: [],
|
|
|
+});
|
|
|
+const { selections } = useSelection();
|
|
|
+
|
|
|
+onBeforeMount(() => {
|
|
|
+ data.fit = selections.fit;
|
|
|
+ getChildrenList();
|
|
|
+});
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ meta2d.on('active', active);
|
|
|
+ meta2d.on('fit', childChange);
|
|
|
+});
|
|
|
+
|
|
|
+onUnmounted(() => {
|
|
|
+ watcher();
|
|
|
+ meta2d.off('active', active);
|
|
|
+ meta2d.off('fit', childChange);
|
|
|
+});
|
|
|
+
|
|
|
+const childChange = () => {
|
|
|
+ getChildrenList();
|
|
|
+};
|
|
|
+
|
|
|
+const watcher = watch(
|
|
|
+ () => selections.fit.id,
|
|
|
+ (id) => {
|
|
|
+ data.fit = selections.fit;
|
|
|
+ getChildrenList();
|
|
|
+ }
|
|
|
+);
|
|
|
+
|
|
|
+const getChildrenList = () => {
|
|
|
+ data.list = [];
|
|
|
+ selections.fit&&selections.fit.children?.forEach((id) => {
|
|
|
+ const pen = meta2d.store.pens[id];
|
|
|
+ if (pen) {
|
|
|
+ data.list.push({
|
|
|
+ label: (pen as any).description || pen.name,
|
|
|
+ value: pen.id,
|
|
|
+ locked: pen.locked,
|
|
|
+ visible: pen.visible,
|
|
|
+ tag: (pen as any).tag,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+const fitPenVisible = (e) => {
|
|
|
+ if (e) {
|
|
|
+ meta2d.store.data.pens.forEach((pen) => {
|
|
|
+ if (!selections.fit.children?.includes(pen.id)) {
|
|
|
+ meta2d.setValue(
|
|
|
+ { id: pen.id, visible: false },
|
|
|
+ { render: false, doEvent: false, history: false }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ meta2d.canvas.hideFit();
|
|
|
+ meta2d.canvas.canvasImage.init();
|
|
|
+ meta2d.canvas.canvasImageBottom.init();
|
|
|
+
|
|
|
+ meta2d.render();
|
|
|
+ } else {
|
|
|
+ meta2d.store.data.pens.forEach((pen) => {
|
|
|
+ if (!selections.fit.children?.includes(pen.id)) {
|
|
|
+ meta2d.setValue(
|
|
|
+ { id: pen.id, visible: true },
|
|
|
+ { render: false, doEvent: false, history: false }
|
|
|
+ );
|
|
|
+ }
|
|
|
+ });
|
|
|
+ meta2d.canvas.showFit();
|
|
|
+ meta2d.canvas.canvasImage.init();
|
|
|
+ meta2d.canvas.canvasImageBottom.init();
|
|
|
+ meta2d.render();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const doActive = (id) => {
|
|
|
+ let pen = meta2d.store.pens[id];
|
|
|
+ meta2d.active([pen], false);
|
|
|
+};
|
|
|
+
|
|
|
+const doRemove = (idx) => {
|
|
|
+ let childId = data.list[idx].value;
|
|
|
+ data.fit.children.splice(idx, 1);
|
|
|
+ meta2d.inactive();
|
|
|
+ meta2d.setVisible(meta2d.store.pens[childId], false);
|
|
|
+ getChildrenList();
|
|
|
+};
|
|
|
+
|
|
|
+const active = () => {
|
|
|
+ data.active = meta2d.store.active.map((pen) => pen.id);
|
|
|
+ const element = document.body.querySelector(
|
|
|
+ `[data-penid="${data.active[0]}"]`
|
|
|
+ );
|
|
|
+ if (element) {
|
|
|
+ element.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+const onFitChange = () => {
|
|
|
+ meta2d.canvas.updateFitRect(data.fit);
|
|
|
+};
|
|
|
+</script>
|
|
|
+<style lang="postcss" scoped>
|
|
|
+.props {
|
|
|
+ .grid {
|
|
|
+ grid-template-columns: 100px 100px auto;
|
|
|
+ padding: 0 12px;
|
|
|
+
|
|
|
+ &.head {
|
|
|
+ background: var(--color-background-input);
|
|
|
+ line-height: 36px;
|
|
|
+ margin-bottom: 6px;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ line-height: 36px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .active {
|
|
|
+ color: var(--color-primary);
|
|
|
+ }
|
|
|
+ .body {
|
|
|
+ max-height: 300px;
|
|
|
+ overflow-y: auto;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|