Browse Source

update: 页面编辑工具添加到注释工具栏

wzl 7 months ago
parent
commit
b93ba0b7b9

+ 18 - 22
packages/core/src/editor/content_container.js

@@ -32,11 +32,11 @@ export class ContentContainer {
     })
     this.editPagePtr = editPagePtr
 
-    await this.messageHandler.sendWithPromise('SetFontCallBackForEditPage', {
-      editPagePtr: this.editPagePtr,
-      fontFile: this.pageViewer.fontFile,
-      fontName: 'DroidSansFallbackFull'
-    })
+    // await this.messageHandler.sendWithPromise('SetFontCallBackForEditPage', {
+    //   editPagePtr: this.editPagePtr,
+    //   fontFile: this.pageViewer.fontFile,
+    //   fontName: 'DroidSansFallbackFull'
+    // })
   }
 
   async render () {
@@ -129,15 +129,7 @@ export class ContentContainer {
 
   hide () {
     this.contentContainer.style.display = 'none'
-
-    if (this.textManager) {
-      this.textManager.tool = ''
-      this.textManager.reset()
-    }
-    if (this.imageManager) {
-      this.imageManager.tool = ''
-      this.imageManager.reset()
-    }
+    this.resetTools()
   }
   
   cancel () {
@@ -151,14 +143,7 @@ export class ContentContainer {
     this.contentContainer?.remove()
     this.contentContainer = null
 
-    if (this.textManager) {
-      this.textManager.tool = ''
-      this.textManager.reset()
-    }
-    if (this.imageManager) {
-      this.imageManager.tool = ''
-      this.imageManager.reset()
-    }
+    this.resetTools()
 
     this.destroyed = true
 
@@ -305,4 +290,15 @@ export class ContentContainer {
   removeEditor (index) {
     this.frameEditorList.splice(index, 1)
   }
+
+  resetTools () {
+    if (this.textManager) {
+      this.textManager.tool = ''
+      this.textManager.reset()
+    }
+    if (this.imageManager) {
+      this.imageManager.tool = ''
+      this.imageManager.reset()
+    }
+  }
 }

+ 11 - 5
packages/core/src/index.js

@@ -297,13 +297,19 @@ class ComPDFKitViewer {
     }
   }
 
-  setTool({
+  async setTool({
     tool,
     color
   }) {
+    const oldTool = this.activeTool
     this.activeTool = tool
     this.color = color
-    this.eventBus.dispatch("toolChanged", { tool, color });
+    this.eventBus.dispatch('toolChanged', { tool, color })
+
+    const editorTools = ['editText', 'editImage', 'addText', 'addImage']
+    if (this.toolMode !== 'editor' && editorTools.includes(oldTool) && !editorTools.includes(this.activeTool)) {
+      await this.updateTextPtr()
+    }
   }
 
   initAnnotations(annotations, render = false) {
@@ -2659,9 +2665,9 @@ class ComPDFKitViewer {
   async setToolMode(mode) {
     const oldMode = this.toolMode;
     this.toolMode = mode;
-    if (mode === 'editor' && !this.fontFileInited) {
-      await this.initFontFile()
-    }
+    // if (mode === 'editor' && !this.fontFileInited) {
+    //   await this.initFontFile()
+    // }
     this.eventBus.dispatch("toolModeChanged", mode);
 
     if (oldMode === 'editor' && this.toolMode !== 'editor') {

+ 15 - 3
packages/core/src/pdf_page_view.js

@@ -254,10 +254,22 @@ class PDFPageView {
     }
   }
 
-  handleTool({
+  async handleTool({
     tool,
     color
   }) {
+    if (this.contentContainer) {
+      if (['editText', 'editImage', 'addText', 'addImage'].includes(tool) && this.toolMode === 'annotation') {
+        this.contentContainer.resetTools()
+        this.contentContainer.tool = tool
+        await this.contentContainer.render()
+      } else if (this.mode === 'editor') {
+        this.contentContainer.resetTools()
+      } else {
+        this.contentContainer.destroy()
+      }
+    }
+
     if (this.compdfAnnotationLayer) return
     this.tool = tool
     this.color = color
@@ -550,7 +562,7 @@ class PDFPageView {
               $t: this.$t
             })
           }
-          if (this.mode === 'editor') {
+          if (this.mode === 'editor' || ['editText', 'editImage', 'addText', 'addImage'].includes(this.tool)) {
             await this.contentContainer.render()
           }
 
@@ -1205,7 +1217,7 @@ class PDFPageView {
               $t: this.$t
             })
           }
-          if (this.mode === 'editor') {
+          if (this.mode === 'editor' || ['editText', 'editImage', 'addText', 'addImage'].includes(this.tool)) {
             await this.contentContainer.render()
           }
 

+ 20 - 2
packages/webview/src/components/Annotate/Annotate.vue

@@ -36,6 +36,18 @@
     <Button v-else-if="tool.type === 'link' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'link' }" @click="changeActiveTool('link')" :title="$t('header.link')">
       <Link />
     </Button>
+    <Button v-else-if="tool.type === 'editText' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'editText' }" @click="changeActiveTool('editText')" :title="$t('header.editor')">
+      <EditText />
+    </Button>
+    <Button v-else-if="tool.type === 'editImage' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'editImage' }" @click="changeActiveTool('editImage')" :title="$t('header.editor')">
+      <EditImage />
+    </Button>
+    <Button v-else-if="tool.type === 'addText' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'addText' }" @click="changeActiveTool('addText')" title="Add Text">
+      <AddText />
+    </Button>
+    <Button v-else-if="tool.type === 'addImage' && !tool.hidden" :data-element="tool.dataElement" :class="{ active: activeTool === 'addImage' }" @click="changeActiveTool('addImage')" title="Add Image">
+      <AddImage />
+    </Button>
   </template>
   <div class="divider pc"></div>
   <div v-if="showColors.includes(activeTool)" class="colors-container">
@@ -84,12 +96,18 @@
   })
 
   const markupTool = computed(() => useDocument.getMarkupToolState)
-
   const shapeTool = computed(() => useDocument.getShapeToolState)
-
   const activeToolColor = computed(() => useDocument.getActiveToolColor)
+  const webviewerMode = computed(() => useViewer.getWebviewerMode)
 
   const changeActiveTool = (tool) => {
+    if (['editText', 'editImage', 'addText', 'addImage'].includes(tool)) {
+      if (webviewerMode.value !== 'Standalone') {
+        useViewer.openElement('contentEditorPreventDialog')
+        return
+      }
+    }
+
     useDocument.setToolState(tool)
     
     useViewer.toggleActiveHand(false)

+ 5 - 3
packages/webview/src/components/ContentEditorToolBar/ContentEditorToolBar.vue

@@ -4,7 +4,7 @@
       <AddText />{{ $t('header.addText') }}
     </Button>
     <Button class="operate" :class="{ active: activeTool === 'addImage' }" @click="changeActiveTool('addImage')" title="Add Image">
-      <AddImage />{{ $t('header.addImage') }}<input v-if="isMobileDevice" type="file" id="editorImageInput" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFile">
+      <AddImage />{{ $t('header.addImage') }}<input v-if="isMobileDevice" type="file" ref="editorImageInput" accept=".png, .jpg, .jpeg" style="display: none;" @change="handleFile">
     </Button>
     <!-- <div class="divider pc"></div>
     <Button class="history" :title="$t('header.undo')">
@@ -17,7 +17,7 @@
 </template>
 
 <script setup>
-  import { computed, h } from 'vue'
+  import { computed, h, ref } from 'vue'
   import { useViewerStore } from '@/stores/modules/viewer'
   import { useDocumentStore } from '@/stores/modules/document'
   import MessageError from '@/assets/icons/icon-message-error.svg'
@@ -32,6 +32,8 @@
   const activeTool = computed(() => useDocument.getActiveTool)
   const currentPage = computed(() => useViewer.getCurrentPage)
 
+  const editorImageInput = ref()
+
   const changeActiveTool = (tool) => {
     useDocument.setToolState(tool)
 
@@ -41,7 +43,7 @@
     switchAnnotationEditorMode(0)
 
     if (activeTool.value === 'addImage' && isMobileDevice) {
-      document.getElementById('editorImageInput').click()
+      editorImageInput.value.click()
     }
   }
 

+ 5 - 0
packages/webview/src/components/Icon/EditImage.vue

@@ -0,0 +1,5 @@
+<template>
+  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <path fill-rule="evenodd" clip-rule="evenodd" d="M1.5 2.25H0.75V3V17V17.75H1.5H18.5H19.25V17V10V3V2.25H18.5H1.5ZM2.25 14.752V3.75H17.75V10V15.969L13.0201 12.0678L10.5683 14.5L6.03214 11L2.25 14.752ZM16 7.5C16 8.32843 15.3284 9 14.5 9C13.6716 9 13 8.32843 13 7.5C13 6.67157 13.6716 6 14.5 6C15.3284 6 16 6.67157 16 7.5Z" fill="#43474D"/>
+  </svg>
+</template>

+ 5 - 0
packages/webview/src/components/Icon/EditText.vue

@@ -0,0 +1,5 @@
+<template>
+  <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+    <path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 16.5H2.5V3.5H17.5V10V16.5ZM1 18H2.5H17.5H19V16.5V10V3.5V2H17.5H2.5H1V3.5V16.5V18ZM14 8V5.5H6V8H7.5V7H9.25V13H8.5V14.5H11.5V13H10.75V7H12.5V8H14Z" fill="#43474D"/>
+  </svg>
+</template>

+ 16 - 2
packages/webview/src/components/ToggleRightPanelButton/index.vue

@@ -1,14 +1,22 @@
 <template>
-  <Button :isActive="isActive || contentEditorPanel" v-bind="{ ...item }" :onClick="onClick" :class="{disabled: (isDisabled && isEditorPanelDisabled) || (toolMode !== 'form' && toolMode !== 'editor')}" :title="$t('header.rightPanel')">
+  <Button
+    :isActive="isActive || contentEditorPanel"
+    v-bind="{ ...item }"
+    :onClick="onClick"
+    :class="{disabled: isButtonDisabled}"
+    :title="$t('header.rightPanel')"
+  >
     <PanelRight />
   </Button>
 </template>
 
 <script setup>
+  import { useDocumentStore } from '@/stores/modules/document'
   import { useViewerStore } from '@/stores/modules/viewer'
   import { computed, ref, watch } from 'vue'
   import core from '@/core'
 
+  const useDocument = useDocumentStore()
   const useViewer = useViewerStore()
   const { item } = defineProps(['item'])
 
@@ -18,10 +26,16 @@
   })
   const contentEditorPanel = computed(() => useViewer.isElementOpen('contentEditorPanel'))
   const contentEditorType = computed(() => useViewer.getContentEditorType)
+  const activeTool = computed(() => useDocument.getActiveTool)
 
   let isDisabled = ref(true)
   let isEditorPanelDisabled = ref(true)
 
+  const isButtonDisabled = computed(() => {
+    return (isDisabled.value && isEditorPanelDisabled.value) ||
+    (toolMode.value !== 'form' && toolMode.value !== 'editor' && !['editText', 'editImage', 'addText', 'addImage'].includes(activeTool.value))
+  })
+
   watch(() => contentEditorPanel.value, (newValue, oldValue) => {
     isEditorPanelDisabled.value = !contentEditorPanel.value && !document.querySelector('.frame-container.selected')
   })
@@ -41,7 +55,7 @@
 
       if (toolMode.value === 'form') {
         useViewer.toggleElement(item.element)
-      } else if (toolMode.value === 'editor') {
+      } else if (toolMode.value === 'editor' || ['editText', 'editImage', 'addText', 'addImage'].includes(activeTool.value)) {
         useViewer.toggleElement('contentEditorPanel')
       }
       core.toggleSidebar()

+ 16 - 0
packages/webview/src/stores/modules/viewer.js

@@ -220,6 +220,22 @@ export const useViewerStore = defineStore({
         {
           type: 'annotation',
           tools: [
+            {
+              type: 'editText',
+              dataElement: 'editText'
+            },
+            {
+              type: 'editImage',
+              dataElement: 'editImage'
+            },
+            {
+              type: 'addText',
+              dataElement: 'addText'
+            },
+            {
+              type: 'addImage',
+              dataElement: 'addImage'
+            },
             {
               type: 'note',
               dataElement: 'note'