123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <template>
- <div
- class="editable-element"
- ref="elementRef"
- :id="`editable-element-${elementInfo.id}`"
- :style="{
- zIndex: elementIndex
- }"
- >
- <component :is="currentElementComponent" :elementInfo="elementInfo" :selectElement="selectElement" :contextmenus="contextmenus" />
- </div>
- </template>
- <script lang="ts" setup>
- import { computed } from "vue"
- import { ElementTypes, ElementSubtypeTypes, type PPTElement } from "@/types/slides"
- import type { ContextmenuItem } from "@/components/Contextmenu/types"
- import useLockElement from "@/hooks/useLockElement"
- import useDeleteElement from "@/hooks/useDeleteElement"
- import useCombineElement from "@/hooks/useCombineElement"
- import useOrderElement from "@/hooks/useOrderElement"
- import useAlignElementToCanvas from "@/hooks/useAlignElementToCanvas"
- import useCopyAndPasteElement from "@/hooks/useCopyAndPasteElement"
- import useSelectElement from "@/hooks/useSelectElement"
- import { ElementOrderCommands, ElementAlignCommands } from "@/types/edit"
- import ImageElement from "@/views/components/element/ImageElement/index.vue"
- import TextElement from "@/views/components/element/TextElement/index.vue"
- import ShapeElement from "@/views/components/element/ShapeElement/index.vue"
- import LineElement from "@/views/components/element/LineElement/index.vue"
- import ChartElement from "@/views/components/element/ChartElement/index.vue"
- import TableElement from "@/views/components/element/TableElement/index.vue"
- import LatexElement from "@/views/components/element/LatexElement/index.vue"
- import VideoElement from "@/views/components/element/VideoElement/index.vue"
- import AudioElement from "@/views/components/element/AudioElement/index.vue"
- import cloudCoachElement from "@/views/components/element/cloudCoachElement"
- import enjoyElement from "@/views/components/element/enjoyElement"
- import listeningPracticeElement from "@/views/components/element/listeningPracticeElement"
- const props = defineProps<{
- elementInfo: PPTElement
- elementIndex: number
- isMultiSelect: boolean
- selectElement: (e: MouseEvent | TouchEvent, element: PPTElement, canMove?: boolean) => void
- openLinkDialog: () => void
- }>()
- const currentElementComponent = computed<unknown>(() => {
- const elementTypeMap = {
- [ElementTypes.IMAGE]: ImageElement,
- [ElementTypes.TEXT]: TextElement,
- [ElementTypes.SHAPE]: ShapeElement,
- [ElementTypes.LINE]: LineElement,
- [ElementTypes.CHART]: ChartElement,
- [ElementTypes.TABLE]: TableElement,
- [ElementTypes.LATEX]: LatexElement,
- [ElementTypes.ELF]: null
- }
- const elementSubtypeMap = {
- [ElementSubtypeTypes.AUDIO]: AudioElement,
- [ElementSubtypeTypes.VIDEO]: VideoElement,
- [ElementSubtypeTypes.SING_PLAY]: cloudCoachElement,
- [ElementSubtypeTypes.ENJOY]: enjoyElement,
- [ElementSubtypeTypes.LISTENING_PRACTICE]: listeningPracticeElement
- }
- return elementTypeMap[props.elementInfo.type] || elementSubtypeMap[props.elementInfo.subtype] || null
- })
- const { orderElement } = useOrderElement()
- const { alignElementToCanvas } = useAlignElementToCanvas()
- const { combineElements, uncombineElements } = useCombineElement()
- const { deleteElement } = useDeleteElement()
- const { lockElement, unlockElement } = useLockElement()
- const { copyElement, pasteElement, cutElement } = useCopyAndPasteElement()
- const { selectAllElements } = useSelectElement()
- const contextmenus = (): ContextmenuItem[] => {
- if (props.elementInfo.lock) {
- return [
- {
- text: "解锁",
- handler: () => unlockElement(props.elementInfo)
- }
- ]
- }
- return [
- {
- text: "剪切",
- subText: "Ctrl + X",
- handler: cutElement
- },
- {
- text: "复制",
- subText: "Ctrl + C",
- handler: copyElement
- },
- {
- text: "粘贴",
- subText: "Ctrl + V",
- handler: pasteElement
- },
- { divider: true },
- {
- text: "水平居中",
- handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL),
- children: [
- { text: "水平垂直居中", handler: () => alignElementToCanvas(ElementAlignCommands.CENTER) },
- { text: "水平居中", handler: () => alignElementToCanvas(ElementAlignCommands.HORIZONTAL) },
- { text: "左对齐", handler: () => alignElementToCanvas(ElementAlignCommands.LEFT) },
- { text: "右对齐", handler: () => alignElementToCanvas(ElementAlignCommands.RIGHT) }
- ]
- },
- {
- text: "垂直居中",
- handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL),
- children: [
- { text: "水平垂直居中", handler: () => alignElementToCanvas(ElementAlignCommands.CENTER) },
- { text: "垂直居中", handler: () => alignElementToCanvas(ElementAlignCommands.VERTICAL) },
- { text: "顶部对齐", handler: () => alignElementToCanvas(ElementAlignCommands.TOP) },
- { text: "底部对齐", handler: () => alignElementToCanvas(ElementAlignCommands.BOTTOM) }
- ]
- },
- { divider: true },
- {
- text: "置于顶层",
- disable: props.isMultiSelect && !props.elementInfo.groupId,
- handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP),
- children: [
- { text: "置于顶层", handler: () => orderElement(props.elementInfo, ElementOrderCommands.TOP) },
- { text: "上移一层", handler: () => orderElement(props.elementInfo, ElementOrderCommands.UP) }
- ]
- },
- {
- text: "置于底层",
- disable: props.isMultiSelect && !props.elementInfo.groupId,
- handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM),
- children: [
- { text: "置于底层", handler: () => orderElement(props.elementInfo, ElementOrderCommands.BOTTOM) },
- { text: "下移一层", handler: () => orderElement(props.elementInfo, ElementOrderCommands.DOWN) }
- ]
- },
- { divider: true },
- {
- text: "设置链接",
- handler: props.openLinkDialog
- },
- {
- text: props.elementInfo.groupId ? "取消组合" : "组合",
- subText: "Ctrl + G",
- handler: props.elementInfo.groupId ? uncombineElements : combineElements,
- hide: !props.isMultiSelect
- },
- {
- text: "全选",
- subText: "Ctrl + A",
- handler: selectAllElements
- },
- {
- text: "锁定",
- subText: "Ctrl + L",
- handler: lockElement
- },
- {
- text: "删除",
- subText: "Delete",
- handler: deleteElement
- }
- ]
- }
- </script>
|