124 lines
3.1 KiB
TypeScript
124 lines
3.1 KiB
TypeScript
import type { Arrow } from '../arrow'
|
|
import type { Summary } from '../summary'
|
|
import type { NodeObj } from '../types/index'
|
|
|
|
type NodeOperation =
|
|
| {
|
|
name: 'moveNodeIn' | 'moveDownNode' | 'moveUpNode' | 'copyNode' | 'addChild' | 'insertParent' | 'insertBefore' | 'beginEdit'
|
|
obj: NodeObj
|
|
}
|
|
| {
|
|
name: 'insertSibling'
|
|
type: 'before' | 'after'
|
|
obj: NodeObj
|
|
}
|
|
| {
|
|
name: 'reshapeNode'
|
|
obj: NodeObj
|
|
origin: NodeObj
|
|
}
|
|
| {
|
|
name: 'finishEdit'
|
|
obj: NodeObj
|
|
origin: string
|
|
}
|
|
| {
|
|
name: 'finishEditTable'
|
|
obj: NodeObj
|
|
origin: string
|
|
}
|
|
| {
|
|
name: 'moveNodeAfter' | 'moveNodeBefore' | 'moveNodeIn'
|
|
objs: NodeObj[]
|
|
toObj: NodeObj
|
|
}
|
|
|
|
type MultipleNodeOperation =
|
|
| {
|
|
name: 'removeNodes'
|
|
objs: NodeObj[]
|
|
}
|
|
| {
|
|
name: 'copyNodes'
|
|
objs: NodeObj[]
|
|
}
|
|
|
|
export type SummaryOperation =
|
|
| {
|
|
name: 'createSummary'
|
|
obj: Summary
|
|
}
|
|
| {
|
|
name: 'removeSummary'
|
|
obj: { id: string }
|
|
}
|
|
| {
|
|
name: 'finishEditSummary'
|
|
obj: Summary
|
|
}
|
|
|
|
export type ArrowOperation =
|
|
| {
|
|
name: 'createArrow'
|
|
obj: Arrow
|
|
}
|
|
| {
|
|
name: 'removeArrow'
|
|
obj: { id: string }
|
|
}
|
|
| {
|
|
name: 'finishEditArrowLabel'
|
|
obj: Arrow
|
|
}
|
|
|
|
export type Operation = NodeOperation | MultipleNodeOperation | SummaryOperation | ArrowOperation
|
|
export type OperationType = Operation['name']
|
|
|
|
export type EventMap = {
|
|
operation: (info: Operation) => void
|
|
selectNewNode: (nodeObj: NodeObj) => void
|
|
selectNodes: (nodeObj: NodeObj[]) => void
|
|
unselectNodes: (nodeObj: NodeObj[]) => void
|
|
expandNode: (nodeObj: NodeObj) => void
|
|
linkDiv: () => void
|
|
scale: (scale: number) => void
|
|
move: (data: { dx: number; dy: number }) => void
|
|
/**
|
|
* please use throttling to prevent performance degradation
|
|
*/
|
|
updateArrowDelta: (arrow: Arrow) => void
|
|
showContextMenu: (e: MouseEvent) => void
|
|
showImagePreview: (imageUrl: string, altText?: string) => void
|
|
}
|
|
|
|
export function createBus<T extends Record<string, (...args: any[]) => void> = EventMap>() {
|
|
return {
|
|
handlers: {} as Record<keyof T, ((...arg: any[]) => void)[]>,
|
|
addListener: function <K extends keyof T>(type: K, handler: T[K]) {
|
|
if (this.handlers[type] === undefined) this.handlers[type] = []
|
|
this.handlers[type].push(handler)
|
|
},
|
|
fire: function <K extends keyof T>(type: K, ...payload: Parameters<T[K]>) {
|
|
if (this.handlers[type] instanceof Array) {
|
|
const handlers = this.handlers[type]
|
|
for (let i = 0; i < handlers.length; i++) {
|
|
handlers[i](...payload)
|
|
}
|
|
}
|
|
},
|
|
removeListener: function <K extends keyof T>(type: K, handler: T[K]) {
|
|
if (!this.handlers[type]) return
|
|
const handlers = this.handlers[type]
|
|
if (!handler) {
|
|
handlers.length = 0
|
|
} else if (handlers.length) {
|
|
for (let i = 0; i < handlers.length; i++) {
|
|
if (handlers[i] === handler) {
|
|
this.handlers[type].splice(i, 1)
|
|
}
|
|
}
|
|
}
|
|
},
|
|
}
|
|
}
|