eventHandler.ts 3 KB
import type { App } from 'vue'
import type { LightboxModeWebsocketService } from '.'
import type { RenderComponentExposeType } from '@/core/Library/types'
import { useNodeEvent } from '@/core/Library/hook/useNodeEvent'
import { EventTypeEnum } from '@/enums/datasource'
import type { MxCell } from '@/fitCore/types'
import { getAppInstanceId } from '@/utils/draw'

interface MxEvent {
  state: { cell: MxCell }
}

export class EventHandler {
  constructor(public service: LightboxModeWebsocketService) {
    this.initEventListener()
  }

  get nodeUtils() {
    return this.service.nodeUtils
  }

  get getDrawApp() {
    return this.service.App
  }

  initEventListener() {
    this.addClickEventListener()
    this.addDbClickEventListener()
    this.addMouseUpOrDownEventListener()
  }

  addDbClickEventListener() {
    const graphDblClick = this.getDrawApp.editor.graph.dblClick
    const dispathEvent = this.dispathEvent.bind(this)
    this.getDrawApp.editor.graph.dblClick = function (...args) {
      dispathEvent(EventTypeEnum.DOUBLE, { state: { cell: args[1] } })
      graphDblClick.apply(this, args)
    }
  }

  addClickEventListener() {
    const graphDblClick = this.getDrawApp.editor.graph.click
    const dispathEvent = this.dispathEvent.bind(this)
    this.getDrawApp.editor.graph.click = function (...args) {
      dispathEvent(EventTypeEnum.SINGLE, ...args)
      graphDblClick.apply(this, args)
    }
  }

  addMouseUpOrDownEventListener() {
    const graphFireMouseEvent = this.getDrawApp.editor.graph.fireMouseEvent
    this.getDrawApp.editor.graph.fireMouseEvent = (eventName, event, sender) => {
      if (eventName === 'mouseUp')
        this.dispathEvent(EventTypeEnum.UP, event)

      if (eventName === 'mouseDown')
        this.dispathEvent(EventTypeEnum.DOWN, event)

      graphFireMouseEvent.apply(this.getDrawApp.editor.graph, [eventName, event, sender])
    }
  }

  dispathEvent(eventName: EventTypeEnum, event: MxEvent) {
    const { state } = event
    if (!state) return
    const { cell } = state
    if (!cell) return
    const id = cell.getId()

    const node = this.service.dataSource.find(item => item.configurationNodeId === id)

    if (node && node.eventJson) {
      const instanceId = getAppInstanceId(cell)
      const instance = window?.VueInstanceMap?.[instanceId] as App
      if (instance && (instance._instance?.exposed as RenderComponentExposeType)?.onEventTrigger) {
        (instance._instance?.exposed as RenderComponentExposeType)?.onEventTrigger?.(eventName, node)
        return
      }

      const { handlerMouseDown, handlerMouseClick, handlerMouseDoubleClick, handlerMouseUp } = useNodeEvent(node.eventJson, node.dataSourceJson, cell)

      switch (eventName) {
        case EventTypeEnum.DOWN:
          handlerMouseDown()
          break
        case EventTypeEnum.UP:
          handlerMouseUp()
          break
        case EventTypeEnum.SINGLE:
          handlerMouseClick()
          break
        case EventTypeEnum.DOUBLE:
          handlerMouseDoubleClick()
          break
      }
    }
  }
}