1- import { type LGraphNode , LiteGraph } from '@comfyorg/litegraph'
1+ import {
2+ BaseWidget ,
3+ type CanvasPointer ,
4+ type LGraphNode ,
5+ LiteGraph
6+ } from '@comfyorg/litegraph'
27import type {
38 IBaseWidget ,
4- ICustomWidget ,
59 IWidgetOptions
610} from '@comfyorg/litegraph/dist/types/widgets'
711
812import type { InputSpec } from '@/schemas/nodeDef/nodeDefSchemaV2'
13+ import { app } from '@/scripts/app'
914import { calculateImageGrid } from '@/scripts/ui/imagePreview'
1015import { ComfyWidgetConstructorV2 } from '@/scripts/widgets'
1116import { useCanvasStore } from '@/stores/graphStore'
@@ -235,34 +240,61 @@ const renderPreview = (
235240 }
236241}
237242
238- class ImagePreviewWidget implements ICustomWidget {
239- readonly type : 'custom'
240- readonly name : string
241- readonly options : IWidgetOptions < string | object >
242- /** Dummy value to satisfy type requirements. */
243- value : string
244- y : number = 0
245- /** Don't serialize the widget value. */
246- serialize : boolean = false
247-
248- constructor ( name : string , options : IWidgetOptions < string | object > ) {
249- this . type = 'custom'
250- this . name = name
251- this . options = options
252- this . value = ''
243+ class ImagePreviewWidget extends BaseWidget {
244+ constructor (
245+ node : LGraphNode ,
246+ name : string ,
247+ options : IWidgetOptions < string | object >
248+ ) {
249+ const widget : IBaseWidget = {
250+ name,
251+ options,
252+ type : 'custom' ,
253+ /** Dummy value to satisfy type requirements. */
254+ value : '' ,
255+ y : 0
256+ }
257+ super ( widget , node )
258+
259+ // Don't serialize the widget value
260+ this . serialize = false
253261 }
254262
255- draw (
256- ctx : CanvasRenderingContext2D ,
257- node : LGraphNode ,
258- _width : number ,
259- y : number ,
260- _height : number
261- ) : void {
262- renderPreview ( ctx , node , y )
263+ override drawWidget ( ctx : CanvasRenderingContext2D ) : void {
264+ renderPreview ( ctx , this . node , this . y )
263265 }
264266
265- computeLayoutSize ( this : IBaseWidget ) {
267+ override onPointerDown ( pointer : CanvasPointer , node : LGraphNode ) : boolean {
268+ pointer . onDragStart = ( ) => {
269+ const { canvas } = app
270+ const { graph } = canvas
271+ canvas . emitBeforeChange ( )
272+ graph ?. beforeChange ( )
273+ // Ensure that dragging is properly cleaned up, on success or failure.
274+ pointer . finally = ( ) => {
275+ canvas . isDragging = false
276+ graph ?. afterChange ( )
277+ canvas . emitAfterChange ( )
278+ }
279+
280+ canvas . processSelect ( node , pointer . eDown )
281+ canvas . isDragging = true
282+ }
283+
284+ pointer . onDragEnd = ( e ) => {
285+ const { canvas } = app
286+ if ( e . shiftKey || LiteGraph . alwaysSnapToGrid )
287+ canvas . graph ?. snapToGrid ( canvas . selectedItems )
288+
289+ canvas . setDirty ( true , true )
290+ }
291+
292+ return true
293+ }
294+
295+ override onClick ( ) : void { }
296+
297+ override computeLayoutSize ( ) {
266298 return {
267299 minHeight : 220 ,
268300 minWidth : 1
@@ -276,7 +308,7 @@ export const useImagePreviewWidget = () => {
276308 inputSpec : InputSpec
277309 ) => {
278310 return node . addCustomWidget (
279- new ImagePreviewWidget ( inputSpec . name , {
311+ new ImagePreviewWidget ( node , inputSpec . name , {
280312 serialize : false
281313 } )
282314 )
0 commit comments