diff --git a/packages/editor/src/layouts/workspace/Stage.vue b/packages/editor/src/layouts/workspace/Stage.vue
index b8fbd124..64e88a01 100644
--- a/packages/editor/src/layouts/workspace/Stage.vue
+++ b/packages/editor/src/layouts/workspace/Stage.vue
@@ -15,7 +15,7 @@
@dragover="dragoverHandler"
>
-
+
@@ -67,6 +67,9 @@ export default defineComponent({
},
setup() {
+ let stage: StageCore | null = null;
+ let runtime: Runtime | null = null;
+
const services = inject('services');
const stageOptions = inject('stageOptions');
@@ -74,6 +77,7 @@ export default defineComponent({
const stageContainer = ref();
const menu = ref>();
+ const isMultiSelect = computed(() => services?.editorService.get('nodes')?.length > 1);
const stageRect = computed(() => services?.uiService.get('stageRect'));
const uiSelectMode = computed(() => services?.uiService.get('uiSelectMode'));
const root = computed(() => services?.editorService.get('root'));
@@ -81,9 +85,6 @@ export default defineComponent({
const zoom = computed(() => services?.uiService.get('zoom') || 1);
const node = computed(() => services?.editorService.get('node'));
- let stage: StageCore | null = null;
- let runtime: Runtime | null = null;
-
const getGuideLineKey = (key: string) => `${key}_${root.value?.id}_${page.value?.id}`;
watchEffect(() => {
@@ -131,6 +132,10 @@ export default defineComponent({
services?.editorService.highlight(el.id);
});
+ stage?.on('multiSelect', (els: HTMLElement[]) => {
+ services?.editorService.multiSelect(els.map((el) => el.id));
+ });
+
stage?.on('update', (ev: UpdateEventData) => {
if (ev.parentEl) {
services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
@@ -206,6 +211,7 @@ export default defineComponent({
menu,
stageRect,
zoom,
+ isMultiSelect,
contextmenuHandler(e: MouseEvent) {
e.preventDefault();
diff --git a/packages/editor/src/layouts/workspace/ViewerMenu.vue b/packages/editor/src/layouts/workspace/ViewerMenu.vue
index 8d469194..54fc2154 100644
--- a/packages/editor/src/layouts/workspace/ViewerMenu.vue
+++ b/packages/editor/src/layouts/workspace/ViewerMenu.vue
@@ -6,8 +6,9 @@
import { computed, defineComponent, inject, markRaw, onMounted, reactive, ref, watch } from 'vue';
import { Bottom, Delete, DocumentCopy, Top } from '@element-plus/icons-vue';
-import { NodeType } from '@tmagic/schema';
-import type StageCore from '@tmagic/stage';
+import { MNode, NodeType } from '@tmagic/schema';
+import StageCore from '@tmagic/stage';
+import { isPage } from '@tmagic/utils';
import ContentMenu from '@editor/components/ContentMenu.vue';
import { LayerOffset, Layout, MenuItem, Services } from '@editor/type';
@@ -16,19 +17,130 @@ import { COPY_STORAGE_KEY } from '@editor/utils/editor';
export default defineComponent({
components: { ContentMenu },
- setup() {
+ props: {
+ isMultiSelect: {
+ type: Boolean,
+ default: false,
+ },
+ },
+
+ setup(props) {
const services = inject('services');
const editorService = services?.editorService;
const menu = ref>();
const canPaste = ref(false);
const canCenter = ref(false);
- const node = computed(() => editorService?.get('node'));
+ const node = computed(() => editorService?.get('node'));
+ const nodes = computed(() => editorService?.get('nodes'));
const parent = computed(() => editorService?.get('parent'));
- const isPage = computed(() => node.value?.type === NodeType.PAGE);
+ const stage = computed(() => editorService?.get('stage'));
const stageContentMenu = inject