From fbb35eb6f7e311f6854c6084a37be70269467a4c Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Sat, 20 Jul 2024 12:34:23 +0800 Subject: [PATCH] refactor: refactor events --- packages/board/src/index.ts | 11 ++ packages/board/src/lib/watcher.ts | 11 +- packages/core/src/config.ts | 50 +++++- packages/core/src/index.ts | 18 +-- packages/core/src/lib/cursor.ts | 5 +- packages/core/src/middleware/dragger/index.ts | 7 +- packages/core/src/middleware/info/index.ts | 9 +- .../src/middleware/layout-selector/index.ts | 14 +- packages/core/src/middleware/pointer/index.ts | 60 +++++++ packages/core/src/middleware/pointer/types.ts | 4 + packages/core/src/middleware/ruler/index.ts | 7 +- packages/core/src/middleware/scaler/index.ts | 5 +- .../core/src/middleware/scroller/index.ts | 3 +- .../core/src/middleware/selector/config.ts | 8 - .../core/src/middleware/selector/index.ts | 149 +++++++++++------- .../core/src/middleware/text-editor/index.ts | 16 +- packages/idraw/src/event.ts | 64 +------- packages/idraw/src/idraw.ts | 27 ++-- packages/idraw/src/index.ts | 13 +- packages/idraw/src/mode.ts | 11 +- packages/types/src/lib/board.ts | 5 +- packages/types/src/lib/core.ts | 60 +++++-- packages/types/src/lib/util.ts | 2 +- 23 files changed, 350 insertions(+), 209 deletions(-) create mode 100644 packages/core/src/middleware/pointer/index.ts create mode 100644 packages/core/src/middleware/pointer/types.ts diff --git a/packages/board/src/index.ts b/packages/board/src/index.ts index 5dd0ddd..cba4da8 100644 --- a/packages/board/src/index.ts +++ b/packages/board/src/index.ts @@ -129,6 +129,7 @@ export class Board { this.#watcher.on('scrollY', this.#handleScrollY.bind(this)); this.#watcher.on('resize', this.#handleResize.bind(this)); this.#watcher.on('doubleClick', this.#handleDoubleClick.bind(this)); + this.#watcher.on('contextMenu', this.#handleContextMenu.bind(this)); this.#renderer.on('load', () => { this.#eventHub.trigger('loadResource'); @@ -185,6 +186,16 @@ export class Board { } } + #handleContextMenu(e: BoardWatcherEventMap['contextMenu']) { + for (let i = 0; i < this.#activeMiddlewareObjs.length; i++) { + const obj = this.#activeMiddlewareObjs[i]; + const result = obj?.contextMenu?.(e); + if (result === false) { + return; + } + } + } + #handleWheel(e: BoardWatcherEventMap['wheel']) { for (let i = 0; i < this.#activeMiddlewareObjs.length; i++) { const obj = this.#activeMiddlewareObjs[i]; diff --git a/packages/board/src/lib/watcher.ts b/packages/board/src/lib/watcher.ts index 1f8d1d9..a88587f 100644 --- a/packages/board/src/lib/watcher.ts +++ b/packages/board/src/lib/watcher.ts @@ -75,6 +75,9 @@ export class BoardWatcher extends EventEmitter { }; #onContextMenu = (e: MouseEvent) => { + if (e.button !== 2) { + return; + } if (!this.#isInTarget(e)) { return; } @@ -83,7 +86,7 @@ export class BoardWatcher extends EventEmitter { if (!this.#isVaildPoint(point)) { return; } - // TODO + this.trigger('contextMenu', { point }); }; #onClick = (e: MouseEvent) => { @@ -146,6 +149,12 @@ export class BoardWatcher extends EventEmitter { }; #onPointStart = (e: MouseEvent) => { + // mouse-left-click: button = 0 + // mouse-right-click: button = 2 + // mouse-scroll button = 1 + if (e.button !== 0) { + return; + } if (!this.#isInTarget(e)) { return; } diff --git a/packages/core/src/config.ts b/packages/core/src/config.ts index 88ca53d..a152150 100644 --- a/packages/core/src/config.ts +++ b/packages/core/src/config.ts @@ -1 +1,49 @@ -export const eventChange = 'change'; +export const EVENT_KEY_CHANGE = 'change'; +export const EVENT_KEY_CURSOR = 'cursor'; +export const EVENT_KEY_RULER = 'ruler'; +export const EVENT_KEY_SCALE = 'scale'; +export const EVENT_KEY_SELECT = 'select'; +export const EVENT_KEY_CLEAR_SELECT = 'clearSelect'; +export const EVENT_KEY_TEXT_EDIT = 'textEdit'; +export const EVENT_KEY_TEXT_CHANGE = 'textChange'; +export const EVENT_KEY_CONTEXT_MENU = 'contextMenu'; +export const EVENT_KEY_SELECT_IN_GROUP = 'selectInGroup'; +export const EVENT_KEY_SNAP_TO_GRID = 'snapToGrid'; + +export type CoreEventKeys = { + CURSOR: typeof EVENT_KEY_CURSOR; + CHANGE: typeof EVENT_KEY_CHANGE; + RULER: typeof EVENT_KEY_RULER; + SCALE: typeof EVENT_KEY_SCALE; + SELECT: typeof EVENT_KEY_SELECT; + CLEAR_SELECT: typeof EVENT_KEY_CLEAR_SELECT; + TEXT_EDIT: typeof EVENT_KEY_TEXT_EDIT; + TEXT_CHANGE: typeof EVENT_KEY_TEXT_CHANGE; + CONTEXT_MENU: typeof EVENT_KEY_CONTEXT_MENU; + SELECT_IN_GROUP: typeof EVENT_KEY_SELECT_IN_GROUP; + SNAP_TO_GRID: typeof EVENT_KEY_SELECT_IN_GROUP; +}; + +const innerEventKeys: CoreEventKeys = { + CURSOR: EVENT_KEY_CURSOR, + CHANGE: EVENT_KEY_CHANGE, + RULER: EVENT_KEY_RULER, + SCALE: EVENT_KEY_SCALE, + SELECT: EVENT_KEY_SELECT, + CLEAR_SELECT: EVENT_KEY_CLEAR_SELECT, + TEXT_EDIT: EVENT_KEY_TEXT_EDIT, + TEXT_CHANGE: EVENT_KEY_TEXT_CHANGE, + CONTEXT_MENU: EVENT_KEY_CONTEXT_MENU, + SELECT_IN_GROUP: EVENT_KEY_SELECT_IN_GROUP, + SNAP_TO_GRID: EVENT_KEY_SELECT_IN_GROUP +}; + +const coreEventKeys = {} as CoreEventKeys; +Object.keys(innerEventKeys).forEach((keyName: string) => { + Object.defineProperty(coreEventKeys, keyName, { + value: innerEventKeys[keyName as keyof CoreEventKeys], + writable: false + }); +}); + +export { coreEventKeys }; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 27677ab..5a72133 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -2,23 +2,19 @@ import type { Data, PointSize, CoreOptions, BoardMiddleware, ViewSizeInfo, CoreE import { Board } from '@idraw/board'; import { createBoardContent, validateElements } from '@idraw/util'; import { Cursor } from './lib/cursor'; -export { eventChange } from './config'; +export { coreEventKeys } from './config'; +export type { CoreEventKeys } from './config'; // export { MiddlewareSelector } from './middleware/selector'; -export { - MiddlewareSelector, - middlewareEventSelect, - middlewareEventSelectClear, - middlewareEventSelectInGroup, - middlewareEventSnapToGrid -} from './middleware/selector'; +export { MiddlewareSelector } from './middleware/selector'; export { MiddlewareScroller } from './middleware/scroller'; -export { MiddlewareScaler, middlewareEventScale } from './middleware/scaler'; -export { MiddlewareRuler, middlewareEventRuler } from './middleware/ruler'; -export { MiddlewareTextEditor, middlewareEventTextEdit, middlewareEventTextChange } from './middleware/text-editor'; +export { MiddlewareScaler } from './middleware/scaler'; +export { MiddlewareRuler } from './middleware/ruler'; +export { MiddlewareTextEditor } from './middleware/text-editor'; export { MiddlewareDragger } from './middleware/dragger'; export { MiddlewareInfo } from './middleware/info'; export { MiddlewareLayoutSelector } from './middleware/layout-selector'; +export { MiddlewarePointer } from './middleware/pointer'; export class Core { #board: Board; diff --git a/packages/core/src/lib/cursor.ts b/packages/core/src/lib/cursor.ts index a938944..b337d16 100644 --- a/packages/core/src/lib/cursor.ts +++ b/packages/core/src/lib/cursor.ts @@ -1,6 +1,7 @@ import type { UtilEventEmitter, CoreEventMap } from '@idraw/types'; import { limitAngle, loadImage, parseAngleToRadian } from '@idraw/util'; import { CURSOR, CURSOR_RESIZE, CURSOR_DRAG_DEFAULT, CURSOR_DRAG_ACTIVE, CURSOR_RESIZE_ROTATE } from './cursor-image'; +import { coreEventKeys } from '../config'; export class Cursor { #eventHub: UtilEventEmitter; @@ -29,7 +30,7 @@ export class Cursor { #init() { const eventHub = this.#eventHub; this.#resetCursor('default'); - eventHub.on('cursor', (e) => { + eventHub.on(coreEventKeys.CURSOR, (e) => { if (e.type === 'over-element' || !e.type) { this.#resetCursor('auto'); } else if (e.type === 'resize-rotate') { @@ -78,7 +79,7 @@ export class Cursor { } } - #setCursorResize(e: CoreEventMap['cursor']) { + #setCursorResize(e: CoreEventMap[typeof coreEventKeys.CURSOR]) { let totalAngle = 0; if (e.type === 'resize-top') { totalAngle += 0; diff --git a/packages/core/src/middleware/dragger/index.ts b/packages/core/src/middleware/dragger/index.ts index 7506e33..104c233 100644 --- a/packages/core/src/middleware/dragger/index.ts +++ b/packages/core/src/middleware/dragger/index.ts @@ -1,4 +1,5 @@ import type { BoardMiddleware, CoreEventMap, Point } from '@idraw/types'; +import { coreEventKeys } from '../../config'; const key = 'DRAG'; const keyPrevPoint = Symbol(`${key}_prevPoint`); @@ -17,7 +18,7 @@ export const MiddlewareDragger: BoardMiddleware = (opts, config) => { +export const MiddlewareInfo: BoardMiddleware = (opts, config) => { const { boardContent, calculator } = opts; const { overlayContext } = boardContent; const innerConfig = { @@ -28,11 +28,10 @@ export const MiddlewareInfo: BoardMiddleware = (opts, config) => { +export const MiddlewareLayoutSelector: BoardMiddleware = (opts, config) => { const { sharer, boardContent, calculator, viewer, eventHub } = opts; const { overlayContext } = boardContent; const innerConfig = { @@ -110,7 +110,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware = (opts) => { + const { boardContent, eventHub, sharer } = opts; + const canvas = boardContent.boardContext.canvas; + const container = opts.container || document.body; + const id = `idraw-middleware-pointer-${Math.random().toString(26).substring(2)}`; + + const getCanvasRect = () => { + const clientRect = canvas.getBoundingClientRect() as DOMRect; + const { left, top, width, height } = clientRect; + return { left, top, width, height }; + }; + + const contextMenuPointer = document.createElement('div'); + contextMenuPointer.setAttribute('id', id); + contextMenuPointer.style.position = 'fixed'; + contextMenuPointer.style.top = '0'; + contextMenuPointer.style.bottom = 'unset'; + contextMenuPointer.style.left = '0'; + contextMenuPointer.style.right = 'unset'; + + // // TODO + // contextMenuPointer.style.width = '10px'; + // contextMenuPointer.style.height = '10px'; + // contextMenuPointer.style.background = 'red'; + + container.appendChild(contextMenuPointer); + + return { + name: '@middleware/pointer', + use() { + // TODO + }, + disuse() { + // TODO + }, + pointStart(e) { + // TODO + }, + pointEnd() { + // TODO + }, + contextMenu(e) { + const { point } = e; + const { left, top } = getCanvasRect(); + contextMenuPointer.style.left = `${left + point.x}px`; + contextMenuPointer.style.top = `${top + point.y}px`; + + const selectedElements = sharer.getSharedStorage(keySelectedElementList); + eventHub.trigger(coreEventKeys.CONTEXT_MENU, { + pointerContainer: contextMenuPointer, + selectedElements: selectedElements || [] + }); + } + }; +}; diff --git a/packages/core/src/middleware/pointer/types.ts b/packages/core/src/middleware/pointer/types.ts new file mode 100644 index 0000000..ab8b9c8 --- /dev/null +++ b/packages/core/src/middleware/pointer/types.ts @@ -0,0 +1,4 @@ +import { keySelectedElementList } from '../selector'; +import type { DeepSelectorSharedStorage } from '../selector'; + +export type DeepPointerSharedStorage = Pick; diff --git a/packages/core/src/middleware/ruler/index.ts b/packages/core/src/middleware/ruler/index.ts index 5179efe..7bc0ba1 100644 --- a/packages/core/src/middleware/ruler/index.ts +++ b/packages/core/src/middleware/ruler/index.ts @@ -3,8 +3,7 @@ import { getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot } from '@idra import { drawRulerBackground, drawXRuler, drawYRuler, calcXRulerScaleList, calcYRulerScaleList, drawGrid, drawScrollerSelectedArea } from './util'; import type { DeepRulerSharedStorage } from './types'; import { defaultStyle } from './config'; - -export const middlewareEventRuler = '@middleware/show-ruler'; +import { coreEventKeys } from '../../config'; export const MiddlewareRuler: BoardMiddleware = (opts, config) => { const { boardContent, viewer, eventHub, calculator } = opts; @@ -43,10 +42,10 @@ export const MiddlewareRuler: BoardMiddleware { if (show === true) { diff --git a/packages/core/src/middleware/scaler/index.ts b/packages/core/src/middleware/scaler/index.ts index 85008f7..f0dac37 100644 --- a/packages/core/src/middleware/scaler/index.ts +++ b/packages/core/src/middleware/scaler/index.ts @@ -1,7 +1,6 @@ import type { BoardMiddleware, CoreEventMap } from '@idraw/types'; import { formatNumber } from '@idraw/util'; - -export const middlewareEventScale = '@middleware/scale'; +import { coreEventKeys } from '../../config'; export const MiddlewareScaler: BoardMiddleware, CoreEventMap> = (opts) => { const { viewer, sharer, eventHub } = opts; @@ -27,7 +26,7 @@ export const MiddlewareScaler: BoardMiddleware, CoreEventMap viewer.scroll({ moveX, moveY }); viewer.drawFrame(); const scaleNum = formatNumber(scale); - eventHub.trigger(middlewareEventScale, { scale: scaleNum }); + eventHub.trigger(coreEventKeys.SCALE, { scale: scaleNum }); } }; }; diff --git a/packages/core/src/middleware/scroller/index.ts b/packages/core/src/middleware/scroller/index.ts index 1f92198..b297df7 100644 --- a/packages/core/src/middleware/scroller/index.ts +++ b/packages/core/src/middleware/scroller/index.ts @@ -3,6 +3,7 @@ import { drawScroller, isPointInScrollThumb } from './util'; // import type { ScrollbarThumbType } from './util'; import { keyXThumbRect, keyYThumbRect, keyPrevPoint, keyActivePoint, keyActiveThumbType, keyHoverXThumbRect, keyHoverYThumbRect, defaultStyle } from './config'; import type { DeepScrollerSharedStorage } from './types'; +import { coreEventKeys } from '../../config'; export const MiddlewareScroller: BoardMiddleware = (opts, config) => { const { viewer, boardContent, sharer, eventHub } = opts; @@ -98,7 +99,7 @@ export const MiddlewareScroller: BoardMiddleware = (opts, config) => { const innerConfig = { ...defaultStyle, @@ -162,7 +154,7 @@ export const MiddlewareSelector: BoardMiddleware elem.uuid) }); + eventHub.trigger(coreEventKeys.SELECT, { uuids: list.map((elem) => elem.uuid), positions: [] }); } }; @@ -199,7 +191,7 @@ export const MiddlewareSelector: BoardMiddleware { + const selectCallback = ({ uuids = [], positions }: CoreEventMap[typeof coreEventKeys.SELECT]) => { let elements: Element[] = []; const actionType = sharer.getSharedStorage(keyActionType); const data = sharer.getActiveStorage('data'); @@ -244,17 +236,17 @@ export const MiddlewareSelector: BoardMiddleware { @@ -269,7 +261,7 @@ export const MiddlewareSelector: BoardMiddleware, groupQueue: sharer.getSharedStorage(keyGroupQueue) || [], position: getElementPositionFromList(target.elements[0]?.uuid, sharer.getActiveStorage('data')?.elements || []), viewScaleInfo: sharer.getActiveViewScaleInfo() @@ -753,6 +747,53 @@ export const MiddlewareSelector: BoardMiddleware { + const groupQueue = sharer.getSharedStorage(keyGroupQueue); + + if (groupQueue?.length > 0) { + if ( + isPointInViewActiveGroup(e.point, { + ctx: overlayContext, + viewScaleInfo: sharer.getActiveViewScaleInfo(), + viewSizeInfo: sharer.getActiveViewSizeInfo(), + groupQueue + }) + ) { + const target = getPointTarget(e.point, pointTargetBaseOptions()); + if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked !== true) { + clear(); + updateSelectedElementList([target.elements[0]], { triggerEvent: true }); + viewer.drawFrame(); + } else if (!target?.elements?.length) { + clear(); + } + } + + return; + } + + // not in group + const listAreaSize = calcSelectedElementsArea(getActiveElements(), { + viewScaleInfo: sharer.getActiveViewScaleInfo(), + viewSizeInfo: sharer.getActiveViewSizeInfo(), + calculator + }); + const target = getPointTarget(e.point, { + ...pointTargetBaseOptions(), + areaSize: listAreaSize, + groupQueue: [] + }); + + if (target?.elements?.length === 1 && target.elements[0]?.operations?.locked !== true) { + clear(); + updateSelectedElementList([target.elements[0]], { triggerEvent: true }); + viewer.drawFrame(); + return; + } else if (!target?.elements?.length) { + clear(); + } + }, + beforeDrawFrame({ snapshot }) { const { activeStore, sharedStore } = snapshot; const { scale, offsetLeft, offsetTop, offsetRight, offsetBottom, width, height, contextHeight, contextWidth, devicePixelRatio } = activeStore; @@ -784,13 +825,13 @@ export const MiddlewareSelector: BoardMiddleware 0) { // in group drawGroupQueueVertexesWrappers(overlayContext, groupQueueVertexesList, drawBaseOpts); if (hoverElement && actionType !== 'drag') { - if (isLocked) { + if (isHoverLocked) { drawLockedVertexesWrapper(overlayContext, hoverElementVertexes, { ...drawBaseOpts, controller: calcElementSizeController(hoverElement, { @@ -804,7 +845,7 @@ export const MiddlewareSelector: BoardMiddleware; @@ -20,7 +19,7 @@ type TextChangeEvent = { position: ElementPosition; }; -type ExtendEventMap = Record & Record; +type ExtendEventMap = Record & Record; const defaultElementDetail = getDefaultElementDetailConfig(); @@ -35,7 +34,8 @@ export const MiddlewareTextEditor: BoardMiddleware | null = null; let activePosition: ElementPosition = []; - + const id = `idraw-middleware-text-editor-${Math.random().toString(26).substring(2)}`; + mask.setAttribute('id', id); canvasWrapper.appendChild(textarea); canvasWrapper.style.position = 'absolute'; @@ -211,7 +211,7 @@ export const MiddlewareTextEditor: BoardMiddleware { if (activeElem && activePosition) { - eventHub.trigger(middlewareEventTextChange, { + eventHub.trigger(coreEventKeys.TEXT_CHANGE, { element: { uuid: activeElem.uuid, detail: { @@ -263,10 +263,10 @@ export const MiddlewareTextEditor: BoardMiddleware { - Object.defineProperty(eventKeys, keyName, { - value: innerEventKeys[keyName as keyof IDrawEventKeys], - writable: false - }); -}); - -export { eventKeys }; +export const eventKeys = coreEventKeys; // TODO diff --git a/packages/idraw/src/idraw.ts b/packages/idraw/src/idraw.ts index 7c5e4d1..cc4cf4a 100644 --- a/packages/idraw/src/idraw.ts +++ b/packages/idraw/src/idraw.ts @@ -1,4 +1,4 @@ -import { Core, middlewareEventSelectInGroup, middlewareEventSnapToGrid } from '@idraw/core'; +import { Core, coreEventKeys } from '@idraw/core'; import type { PointSize, IDrawOptions, @@ -14,7 +14,6 @@ import type { ElementPosition, IDrawStorage } from '@idraw/types'; -import type { IDrawEvent } from './event'; import { createElement, insertElementToListByPosition, @@ -31,7 +30,7 @@ import { import { defaultSettings, getDefaultStorage, defaultMode, parseStyles } from './config'; import { exportImageFileBlobURL } from './file'; import type { ExportImageFileBaseOptions, ExportImageFileResult } from './file'; -import { eventKeys } from './event'; +import type { IDrawEvent } from './event'; import { changeMode, runMiddlewares } from './mode'; export class iDraw { @@ -70,11 +69,11 @@ export class iDraw { runMiddlewares(this.#core, store); this.#core.refresh(); } else if (feat === 'selectInGroup') { - this.#core.trigger(middlewareEventSelectInGroup, { + this.#core.trigger(coreEventKeys.SELECT_IN_GROUP, { enable: !!status }); } else if (feat === 'snapToGrid') { - this.#core.trigger(middlewareEventSnapToGrid, { + this.#core.trigger(coreEventKeys.SNAP_TO_GRID, { enable: !!status }); } @@ -110,7 +109,7 @@ export class iDraw { setData(data: Data) { const core = this.#core; core.setData(data); - core.trigger(eventKeys.change, { data, type: 'setData' }); + core.trigger(coreEventKeys.CHANGE, { data, type: 'setData' }); } getData(opts?: { compact?: boolean }): Data | null { @@ -162,7 +161,7 @@ export class iDraw { } trigger(name: T, e?: IDrawEvent[T]) { - this.#core.trigger(name, e); + this.#core.trigger(name, e as IDrawEvent[T]); } selectElement(uuid: string) { @@ -170,7 +169,7 @@ export class iDraw { } selectElements(uuids: string[]) { - this.trigger(eventKeys.select, { uuids }); + this.trigger(coreEventKeys.SELECT, { uuids }); } selectElementByPosition(position: ElementPosition) { @@ -178,11 +177,11 @@ export class iDraw { } selectElementsByPositions(positions: ElementPosition[]) { - this.trigger(eventKeys.select, { positions }); + this.trigger(coreEventKeys.SELECT, { positions }); } cancelElements() { - this.trigger(eventKeys.clearSelect, { uuids: [] }); + this.trigger(coreEventKeys.CLEAR_SELECT, { uuids: [] }); } createElement( @@ -211,7 +210,7 @@ export class iDraw { updateElementInList(element.uuid, element, data.elements); core.setData(data); core.refresh(); - core.trigger(eventKeys.change, { data, type: 'updateElement' }); + core.trigger(coreEventKeys.CHANGE, { data, type: 'updateElement' }); } addElement( @@ -230,7 +229,7 @@ export class iDraw { } core.setData(data); core.refresh(); - core.trigger(eventKeys.change, { data, type: 'addElement' }); + core.trigger(coreEventKeys.CHANGE, { data, type: 'addElement' }); return data; } @@ -240,7 +239,7 @@ export class iDraw { deleteElementInList(uuid, data.elements); core.setData(data); core.refresh(); - core.trigger(eventKeys.change, { data, type: 'deleteElement' }); + core.trigger(coreEventKeys.CHANGE, { data, type: 'deleteElement' }); } moveElement(uuid: string, to: ElementPosition) { @@ -251,7 +250,7 @@ export class iDraw { data.elements = list; core.setData(data); core.refresh(); - core.trigger(eventKeys.change, { data, type: 'moveElement' }); + core.trigger(coreEventKeys.CHANGE, { data, type: 'moveElement' }); } async getImageBlobURL(opts?: ExportImageFileBaseOptions): Promise { diff --git a/packages/idraw/src/index.ts b/packages/idraw/src/index.ts index 4e3bd51..016320f 100644 --- a/packages/idraw/src/index.ts +++ b/packages/idraw/src/index.ts @@ -1,16 +1,5 @@ export type * from '@idraw/types'; -export { - Core, - MiddlewareSelector, - middlewareEventSelect, - middlewareEventSelectClear, - MiddlewareScroller, - MiddlewareScaler, - middlewareEventScale, - MiddlewareRuler, - middlewareEventRuler, - MiddlewareTextEditor -} from '@idraw/core'; +export { Core, MiddlewareSelector, MiddlewareScroller, MiddlewareScaler, MiddlewareRuler, MiddlewareTextEditor, coreEventKeys } from '@idraw/core'; export { Sharer, Calculator } from '@idraw/board'; export { Renderer } from '@idraw/renderer'; export { diff --git a/packages/idraw/src/mode.ts b/packages/idraw/src/mode.ts index afe11d8..46a9420 100644 --- a/packages/idraw/src/mode.ts +++ b/packages/idraw/src/mode.ts @@ -9,15 +9,16 @@ import { MiddlewareRuler, MiddlewareTextEditor, MiddlewareDragger, - MiddlewareInfo + MiddlewareInfo, + MiddlewarePointer } from '@idraw/core'; -import { IDrawEvent } from './event'; +import { InnerEvent } from './event'; function isValidMode(mode: string | IDrawMode) { return ['select', 'drag', 'readOnly'].includes(mode); } -export function runMiddlewares(core: Core, store: Store) { +export function runMiddlewares(core: Core, store: Store) { const { enableRuler, enableScale, enableScroll, enableSelect, enableTextEdit, enableDrag, enableInfo } = store.getSnapshot(); const styles = store.get('middlewareStyles'); if (enableScroll === true) { @@ -63,9 +64,11 @@ export function runMiddlewares(core: Core, store: Store, store: Store) { +export function changeMode(mode: IDrawMode, core: Core, store: Store) { let enableScale: boolean = false; let enableScroll: boolean = false; let enableSelect: boolean = false; diff --git a/packages/types/src/lib/board.ts b/packages/types/src/lib/board.ts index 009f0a4..26d1f8b 100644 --- a/packages/types/src/lib/board.ts +++ b/packages/types/src/lib/board.ts @@ -49,6 +49,7 @@ export interface BoardWatcherEventMap = any> pointEnd: BoardWatcherPointEvent; pointLeave: BoardWatcherPointEvent; doubleClick: BoardWatcherPointEvent; + contextMenu: BoardWatcherPointEvent; wheel: BoardWatherWheelEvent; wheelScale: BoardWatherWheelScaleEvent; scrollX: BoardWatherScrollXEvent; @@ -70,12 +71,10 @@ export interface BoardMiddlewareObject = any pointEnd?: (e: BoardWatcherEventMap['pointEnd']) => void | boolean; pointLeave?: (e: BoardWatcherEventMap['pointLeave']) => void | boolean; doubleClick?: (e: BoardWatcherEventMap['doubleClick']) => void | boolean; - // wheelX?: (e: BoardWatcherEventMap['wheelX']) => void | boolean; - // wheelY?: (e: BoardWatcherEventMap['wheelY']) => void | boolean; + contextMenu?: (e: BoardWatcherEventMap['contextMenu']) => void | boolean; wheel?: (e: BoardWatcherEventMap['wheel']) => void | boolean; wheelScale?: (e: BoardWatcherEventMap['wheelScale']) => void | boolean; - // scale?: (e: BoardWatcherEventMap['scale']) => void | boolean; scrollX?: (e: BoardWatcherEventMap['scrollX']) => void | boolean; scrollY?: (e: BoardWatcherEventMap['scrollY']) => void | boolean; resize?: (e: BoardWatcherEventMap['resize']) => void | boolean; diff --git a/packages/types/src/lib/core.ts b/packages/types/src/lib/core.ts index c5b80f8..60c2a24 100644 --- a/packages/types/src/lib/core.ts +++ b/packages/types/src/lib/core.ts @@ -1,4 +1,5 @@ -import type { Element, ElementType } from './element'; +import type { Element, ElementSize, ElementType, ElementPosition } from './element'; +import type { ViewScaleInfo } from './view'; import type { Data } from './data'; import type { ViewContext2D } from './context2d'; import type { BoardBaseEventMap } from './board'; @@ -24,18 +25,29 @@ export type CursorType = | 'default'; export interface CoreEventCursor { - type: CursorType | string | null; + type?: CursorType | string | null; groupQueue?: Element<'group'>[]; - element?: Element; + element?: Element | ElementSize | null; } -export interface CoreEventSelect { - uuids: string[]; - positions?: Array>; -} +// export interface CoreEventSelect { +// uuids: string[]; +// positions?: Array>; +// } export interface CoreEventChange { - type: string; data: Data; + type: + | 'updateElement' + | 'deleteElement' + | 'moveElement' + | 'addElement' + | 'dragElement' + | 'resizeElement' + | 'setData' + | 'undo' + | 'redo' + | 'changeLayout' // TODO + | 'other'; selectedElements?: Element[] | null; hoverElement?: Element | null; } @@ -43,8 +55,38 @@ export interface CoreEventScale { scale: number; } +type CoreEventTextEdit = { + element: Element<'text'>; + position: ElementPosition; + groupQueue: Element<'group'>[]; + viewScaleInfo: ViewScaleInfo; +}; + +type CoreEventTextChange = { + element: { + uuid: string; + detail: { + text: string; + }; + }; + position: ElementPosition; +}; + +type CoreEventContextMenu = { + pointerContainer: HTMLDivElement; + selectedElements: Element[]; +}; + export type CoreEventMap = BoardBaseEventMap & { cursor: CoreEventCursor; change: CoreEventChange; - [key: string]: any; + ruler: { show: boolean; showGrid: boolean }; + scale: { scale: number }; + select: { uuids?: string[]; positions?: ElementPosition[] }; + clearSelect: { uuids?: string[] } | void; + textEdit: CoreEventTextEdit; + textChange: CoreEventTextChange; + contextMenu: CoreEventContextMenu; + selectInGroup: { enable: boolean }; + snapToGrid: { enable: boolean }; }; diff --git a/packages/types/src/lib/util.ts b/packages/types/src/lib/util.ts index 6641248..dedc027 100644 --- a/packages/types/src/lib/util.ts +++ b/packages/types/src/lib/util.ts @@ -1,7 +1,7 @@ export interface UtilEventEmitter> { on(eventKey: K, callback: (e: T[K]) => void): void; off(eventKey: K, callback: (e: T[K]) => void): void; - trigger(eventKey: K, e: T[K]): void; + trigger(eventKey: K, e?: T[K]): void; has(name: K | string): boolean; }