refactor(app): align canvas menu file layout
This commit is contained in:
parent
f37a263279
commit
1d8f4bf8c4
|
|
@ -1,71 +0,0 @@
|
|||
import { useClipboard } from '@vueuse/core'
|
||||
import type { Ref } from 'vue'
|
||||
|
||||
import { nodeToXPath } from '@open-pencil/core/xpath'
|
||||
|
||||
import type { EditorStore } from '@/app/editor/active-store'
|
||||
import { toast } from '@/app/shell/ui'
|
||||
|
||||
export const COPY_AS_PNG_SHORTCUT = 'MOD+SHIFT+C'
|
||||
|
||||
function toArrayBuffer(data: Uint8Array): ArrayBuffer {
|
||||
const bytes = new Uint8Array(data.length)
|
||||
bytes.set(data)
|
||||
return bytes.buffer
|
||||
}
|
||||
|
||||
export function createCanvasMenuActions(store: EditorStore, selectedIds: Ref<Set<string>>) {
|
||||
const { copy } = useClipboard()
|
||||
|
||||
function ids() {
|
||||
return [...selectedIds.value]
|
||||
}
|
||||
|
||||
function execCommand(cmd: 'copy' | 'cut' | 'paste') {
|
||||
try {
|
||||
if (window.document.execCommand(cmd)) return
|
||||
} catch (error) {
|
||||
console.warn(`Clipboard command ${cmd} failed`, error)
|
||||
}
|
||||
|
||||
toast.error('Clipboard access is blocked in this browser context')
|
||||
}
|
||||
|
||||
async function clipboardWrite(text: string | null, label: string) {
|
||||
if (!text) return
|
||||
await copy(text)
|
||||
toast.info(`Copied as ${label}`)
|
||||
}
|
||||
|
||||
async function copyNodeId() {
|
||||
const nodeIds = ids()
|
||||
if (nodeIds.length === 0) return
|
||||
await copy(nodeIds.join(', '))
|
||||
toast.info(`Copied node ID${nodeIds.length > 1 ? 's' : ''}`)
|
||||
}
|
||||
|
||||
async function copyXPath() {
|
||||
const nodeIds = ids()
|
||||
if (nodeIds.length === 0) return
|
||||
const xpaths = nodeIds
|
||||
.map((id) => nodeToXPath(store.graph, id))
|
||||
.filter((xpath): xpath is string => xpath !== null)
|
||||
if (xpaths.length === 0) return
|
||||
await copy(xpaths.join('\n'))
|
||||
toast.info(`Copied XPath${xpaths.length > 1 ? 's' : ''}`)
|
||||
}
|
||||
|
||||
async function copyAsPNG() {
|
||||
if (typeof ClipboardItem === 'undefined') {
|
||||
toast.error('PNG clipboard export is not available in this browser')
|
||||
return
|
||||
}
|
||||
const data = await store.renderExportImage(ids(), 2, 'PNG')
|
||||
if (!data) return
|
||||
const blob = new Blob([toArrayBuffer(data)], { type: 'image/png' })
|
||||
await navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })])
|
||||
toast.info('Copied as PNG')
|
||||
}
|
||||
|
||||
return { ids, execCommand, clipboardWrite, copyNodeId, copyXPath, copyAsPNG }
|
||||
}
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
const COMPONENT_MENU_LABEL_PARTS = ['component', 'instance']
|
||||
|
||||
export function isComponentMenuItem(label: string) {
|
||||
const normalized = label.toLowerCase()
|
||||
return COMPONENT_MENU_LABEL_PARTS.some((part) => normalized.includes(part))
|
||||
}
|
||||
|
||||
export function canvasMenuItemClass(label: string, classes: { item: string; component: string }) {
|
||||
return isComponentMenuItem(label) ? classes.component : classes.item
|
||||
}
|
||||
|
||||
export function canvasMenuShortcutClass(label: string) {
|
||||
return isComponentMenuItem(label) ? 'text-component/60' : 'text-muted'
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ import type { EditorCommandId } from '@open-pencil/vue'
|
|||
import { useEditorStore } from '@/app/editor/active-store'
|
||||
import { appMenuShortcutLabel } from '@/app/shell/menu/shortcut'
|
||||
import { createCanvasMenuActions } from '@/app/editor/canvas/menu/actions'
|
||||
import { useCanvasContextMenu } from '@/app/editor/canvas/context-menu'
|
||||
import { useCanvasContextMenu } from '@/app/editor/canvas/menu/context'
|
||||
import { canvasMenuItemClass, canvasMenuShortcutClass } from '@/app/editor/canvas/menu/model'
|
||||
import { menu, useMenuUI } from '@/components/ui/menu'
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue