Double click group title to edit (#714)

* Double click group title to edit

* Add playwright test

* Update test expectations [skip ci]

---------

Co-authored-by: github-actions <github-actions@github.com>
This commit is contained in:
Chenlei Hu
2024-09-02 18:01:02 -04:00
committed by GitHub
parent 80e4384644
commit 4ad1e67ebf
12 changed files with 228 additions and 13 deletions

View File

@@ -6,6 +6,7 @@
</template>
</LiteGraphCanvasSplitterOverlay>
<NodeTitleEditor />
<GroupTitleEditor />
<canvas ref="canvasRef" id="graph-canvas" tabindex="1" />
</teleport>
<NodeSearchboxPopover v-if="nodeSearchEnabled" />
@@ -14,6 +15,7 @@
<script setup lang="ts">
import NodeTitleEditor from '@/components/graph/NodeTitleEditor.vue'
import GroupTitleEditor from '@/components/graph/GroupTitleEditor.vue'
import SideToolbar from '@/components/sidebar/SideToolbar.vue'
import LiteGraphCanvasSplitterOverlay from '@/components/LiteGraphCanvasSplitterOverlay.vue'
import NodeSearchboxPopover from '@/components/searchbox/NodeSearchBoxPopover.vue'

View File

@@ -0,0 +1,104 @@
<template>
<div v-if="showInput" class="group-title-editor" :style="inputStyle">
<EditableText
:isEditing="showInput"
:modelValue="editedTitle"
@edit="onEdit"
/>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted, CSSProperties } from 'vue'
import { app } from '@/scripts/app'
import { LGraphGroup } from '@comfyorg/litegraph'
import EditableText from '@/components/common/EditableText.vue'
import { useSettingStore } from '@/stores/settingStore'
import type { LiteGraphCanvasEvent } from '@comfyorg/litegraph'
const settingStore = useSettingStore()
const showInput = ref(false)
const editedTitle = ref('')
const inputStyle = ref<CSSProperties>({
position: 'fixed',
left: '0px',
top: '0px',
width: '200px',
height: '20px',
fontSize: '12px'
})
const currentGroup = ref<LGraphGroup | null>(null)
const onEdit = (newValue: string) => {
if (currentGroup.value && newValue.trim() !== '') {
currentGroup.value.title = newValue.trim()
app.graph.setDirtyCanvas(true, true)
}
showInput.value = false
}
const canvasEventHandler = (event: LiteGraphCanvasEvent) => {
if (!settingStore.get('Comfy.Group.DoubleClickTitleToEdit')) {
return
}
if (event.detail.subType === 'group-double-click') {
const group: LGraphGroup = event.detail.group
const [x, y] = group.pos
const [w, h] = group.size
const e: MouseEvent = event.detail.originalEvent
// @ts-expect-error LiteGraphCanvasEvent is not typed
const relativeY = e.canvasY - y
// Only allow editing if the click is on the title bar
if (relativeY > group.titleHeight) {
return
}
currentGroup.value = group
editedTitle.value = group.title
showInput.value = true
const [left, top] = app.canvasPosToClientPos([x, y])
inputStyle.value.left = `${left}px`
inputStyle.value.top = `${top}px`
const width = w * app.canvas.ds.scale
const height = group.titleHeight * app.canvas.ds.scale
inputStyle.value.width = `${width}px`
inputStyle.value.height = `${height}px`
const fontSize = group.font_size * app.canvas.ds.scale
inputStyle.value.fontSize = `${fontSize}px`
}
}
onMounted(() => {
document.addEventListener('litegraph:canvas', canvasEventHandler)
})
onUnmounted(() => {
document.removeEventListener('litegraph:canvas', canvasEventHandler)
})
</script>
<style scoped>
.node-title-editor {
z-index: 9999;
padding: 0.25rem;
}
:deep(.editable-text) {
width: 100%;
height: 100%;
}
:deep(.editable-text input) {
width: 100%;
height: 100%;
/* Override the default font size */
font-size: inherit;
}
</style>

View File

@@ -55,8 +55,7 @@ const extension: ComfyExtension = {
showInput.value = true
const isCollapsed = node.flags?.collapsed
const [x1, y1, x2, y2] = this.getBounding()
const [nodeWidth, nodeHeight] = this.size
const [x1, y1, nodeWidth, nodeHeight] = this.getBounding()
const canvasWidth =
// @ts-expect-error Remove after collapsed_width is exposed in LiteGraph
isCollapsed && node._collapsed_width ? node._collapsed_width : nodeWidth

View File

@@ -100,6 +100,10 @@ const linkReleaseTriggerMode = computed(() => {
})
const canvasEventHandler = (e: LiteGraphCanvasEvent) => {
if (!['empty-release', 'empty-double-click'].includes(e.detail.subType)) {
return
}
const shiftPressed = (e.detail.originalEvent as KeyboardEvent).shiftKey
if (e.detail.subType === 'empty-release') {