Replace locking/unlocking of canvas with select/pan mode (#1050)

* Add dragging canvas state

* Change icon

* Add playwright test

* tooltip change

* Enable for legacy menu

* Update litegraph

* Hide canvas menu for test
This commit is contained in:
Chenlei Hu
2024-09-30 20:20:49 -04:00
committed by GitHub
parent f75f774ddb
commit 5d957a05b9
8 changed files with 69 additions and 11 deletions

View File

@@ -470,6 +470,8 @@ export class ComfyPage {
'Comfy.NodeBadge.NodeSourceBadgeMode', 'Comfy.NodeBadge.NodeSourceBadgeMode',
NodeBadgeMode.None NodeBadgeMode.None
) )
// Hide canvas menu by default.
await this.setSetting('Comfy.Graph.CanvasMenu', false)
} }
public assetPath(fileName: string) { public assetPath(fileName: string) {

View File

@@ -347,6 +347,32 @@ test.describe('Canvas Interaction', () => {
await expect(comfyPage.canvas).toHaveScreenshot('panned.png') await expect(comfyPage.canvas).toHaveScreenshot('panned.png')
}) })
test('Cursor style changes when panning', async ({ comfyPage }) => {
const getCursorStyle = async () => {
return await comfyPage.page.evaluate(() => {
return (
document.getElementById('graph-canvas')!.style.cursor || 'default'
)
})
}
await comfyPage.page.mouse.move(10, 10)
expect(await getCursorStyle()).toBe('default')
await comfyPage.page.mouse.down()
expect(await getCursorStyle()).toBe('grabbing')
await comfyPage.page.mouse.up()
expect(await getCursorStyle()).toBe('default')
await comfyPage.page.keyboard.down('Space')
expect(await getCursorStyle()).toBe('grab')
await comfyPage.page.mouse.down()
expect(await getCursorStyle()).toBe('grabbing')
await comfyPage.page.mouse.up()
expect(await getCursorStyle()).toBe('grab')
await comfyPage.page.keyboard.up('Space')
expect(await getCursorStyle()).toBe('default')
})
test('Can pan very far and back', async ({ comfyPage }) => { test('Can pan very far and back', async ({ comfyPage }) => {
// intentionally slice the edge of where the clip text encode dom widgets are // intentionally slice the edge of where the clip text encode dom widgets are
await comfyPage.pan({ x: -800, y: -300 }, { x: 1000, y: 10 }) await comfyPage.pan({ x: -800, y: -300 }, { x: 1000, y: 10 })

8
package-lock.json generated
View File

@@ -9,7 +9,7 @@
"version": "1.3.3", "version": "1.3.3",
"dependencies": { "dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1", "@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
"@comfyorg/litegraph": "^0.7.80", "@comfyorg/litegraph": "^0.7.81",
"@primevue/themes": "^4.0.5", "@primevue/themes": "^4.0.5",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"@vueuse/core": "^11.0.0", "@vueuse/core": "^11.0.0",
@@ -1910,9 +1910,9 @@
"dev": true "dev": true
}, },
"node_modules/@comfyorg/litegraph": { "node_modules/@comfyorg/litegraph": {
"version": "0.7.80", "version": "0.7.81",
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.7.80.tgz", "resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.7.81.tgz",
"integrity": "sha512-kn9RByKDa2zYdXtUkfWvY8fV+GkJfdnFXP0JEFT4RdoLRNpuXqsGujogjIz9BWfOlKTN7JE0H6zLv+rscQ7JeQ==", "integrity": "sha512-DuMXOhF1ffEhbgUZoGobu0J3aAyXYXeEp1X+0EDd0hcRNt1/hXcwtFKCkFuJtSOox+aLSAi5EcHreMwln9Zr3A==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@cspotcode/source-map-support": { "node_modules/@cspotcode/source-map-support": {

View File

@@ -63,7 +63,7 @@
}, },
"dependencies": { "dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "^1.2.1", "@atlaskit/pragmatic-drag-and-drop": "^1.2.1",
"@comfyorg/litegraph": "^0.7.80", "@comfyorg/litegraph": "^0.7.81",
"@primevue/themes": "^4.0.5", "@primevue/themes": "^4.0.5",
"@vitejs/plugin-vue": "^5.0.5", "@vitejs/plugin-vue": "^5.0.5",
"@vueuse/core": "^11.0.0", "@vueuse/core": "^11.0.0",

View File

@@ -9,6 +9,7 @@
</template> </template>
</LiteGraphCanvasSplitterOverlay> </LiteGraphCanvasSplitterOverlay>
<TitleEditor /> <TitleEditor />
<GraphCanvasMenu v-if="!betaMenuEnabled && canvasMenuEnabled" />
<canvas ref="canvasRef" id="graph-canvas" tabindex="1" /> <canvas ref="canvasRef" id="graph-canvas" tabindex="1" />
</teleport> </teleport>
<NodeSearchboxPopover /> <NodeSearchboxPopover />
@@ -99,6 +100,22 @@ watchEffect(() => {
}) })
}) })
watchEffect(() => {
if (!canvasStore.canvas) return
if (canvasStore.draggingCanvas) {
canvasStore.canvas.canvas.style.cursor = 'grabbing'
return
}
if (canvasStore.readOnly) {
canvasStore.canvas.canvas.style.cursor = 'grab'
return
}
canvasStore.canvas.canvas.style.cursor = 'default'
})
let dropTargetCleanup = () => {} let dropTargetCleanup = () => {}
onMounted(async () => { onMounted(async () => {

View File

@@ -25,15 +25,17 @@
<Button <Button
severity="secondary" severity="secondary"
v-tooltip.left=" v-tooltip.left="
t('graphCanvasMenu.' + (canvasStore.readOnly ? 'unlock' : 'lock')) t(
'graphCanvasMenu.' + (canvasStore.readOnly ? 'panMode' : 'selectMode')
) + ' (Space)'
" "
@click=" @click="
() => commandStore.getCommandFunction('Comfy.Canvas.ToggleLock')() () => commandStore.getCommandFunction('Comfy.Canvas.ToggleLock')()
" "
> >
<template #icon> <template #icon>
<i-material-symbols:lock-outline v-if="canvasStore.readOnly" /> <i-material-symbols:pan-tool-outline v-if="canvasStore.readOnly" />
<i-material-symbols:lock-open-outline v-else /> <i-simple-line-icons:cursor v-else />
</template> </template>
</Button> </Button>
</ButtonGroup> </ButtonGroup>

View File

@@ -99,8 +99,8 @@ const messages = {
zoomIn: 'Zoom In', zoomIn: 'Zoom In',
zoomOut: 'Zoom Out', zoomOut: 'Zoom Out',
resetView: 'Reset View', resetView: 'Reset View',
lock: 'Lock Graph', selectMode: 'Select Mode',
unlock: 'Unlock Graph' panMode: 'Pan Mode'
} }
}, },
zh: { zh: {

View File

@@ -13,6 +13,7 @@ export const useTitleEditorStore = defineStore('titleEditor', () => {
export const useCanvasStore = defineStore('canvas', () => { export const useCanvasStore = defineStore('canvas', () => {
const canvas = shallowRef<LGraphCanvas | null>(null) const canvas = shallowRef<LGraphCanvas | null>(null)
const readOnly = ref(false) const readOnly = ref(false)
const draggingCanvas = ref(false)
document.addEventListener( document.addEventListener(
'litegraph:canvas', 'litegraph:canvas',
@@ -23,8 +24,18 @@ export const useCanvasStore = defineStore('canvas', () => {
} }
) )
document.addEventListener(
'litegraph:canvas',
(e: CustomEvent<{ subType: string; draggingCanvas: boolean }>) => {
if (e.detail?.subType === 'dragging-canvas') {
draggingCanvas.value = e.detail.draggingCanvas
}
}
)
return { return {
canvas, canvas,
readOnly readOnly,
draggingCanvas
} }
}) })