Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: refactor events #337

Merged
merged 1 commit into from
Jul 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions packages/board/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
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');
Expand Down Expand Up @@ -185,6 +186,16 @@ export class Board<T extends BoardExtendEventMap = BoardExtendEventMap> {
}
}

#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];
Expand Down
11 changes: 10 additions & 1 deletion packages/board/src/lib/watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
};

#onContextMenu = (e: MouseEvent) => {
if (e.button !== 2) {
return;
}
if (!this.#isInTarget(e)) {
return;
}
Expand All @@ -83,7 +86,7 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
if (!this.#isVaildPoint(point)) {
return;
}
// TODO
this.trigger('contextMenu', { point });
};

#onClick = (e: MouseEvent) => {
Expand Down Expand Up @@ -146,6 +149,12 @@ export class BoardWatcher extends EventEmitter<BoardWatcherEventMap> {
};

#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;
}
Expand Down
50 changes: 49 additions & 1 deletion packages/core/src/config.ts
Original file line number Diff line number Diff line change
@@ -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 };
18 changes: 7 additions & 11 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<E extends CoreEventMap = CoreEventMap> {
#board: Board<E>;
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/lib/cursor.ts
Original file line number Diff line number Diff line change
@@ -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<CoreEventMap>;
Expand Down Expand Up @@ -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') {
Expand Down Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions packages/core/src/middleware/dragger/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { BoardMiddleware, CoreEventMap, Point } from '@idraw/types';
import { coreEventKeys } from '../../config';

const key = 'DRAG';
const keyPrevPoint = Symbol(`${key}_prevPoint`);
Expand All @@ -17,7 +18,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
if (isDragging === true) {
return;
}
eventHub.trigger('cursor', {
eventHub.trigger(coreEventKeys.CURSOR, {
type: 'drag-default'
});
},
Expand All @@ -26,7 +27,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
const { point } = e;
sharer.setSharedStorage(keyPrevPoint, point);
isDragging = true;
eventHub.trigger('cursor', {
eventHub.trigger(coreEventKeys.CURSOR, {
type: 'drag-active'
});
},
Expand All @@ -46,7 +47,7 @@ export const MiddlewareDragger: BoardMiddleware<DraggerSharedStorage, CoreEventM
pointEnd() {
isDragging = false;
sharer.setSharedStorage(keyPrevPoint, null);
eventHub.trigger('cursor', {
eventHub.trigger(coreEventKeys.CURSOR, {
type: 'drag-default'
});
}
Expand Down
9 changes: 4 additions & 5 deletions packages/core/src/middleware/info/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { BoardMiddleware, ViewRectInfo, Element, MiddlewareInfoConfig } from '@idraw/types';
import type { BoardMiddleware, ViewRectInfo, Element, MiddlewareInfoConfig, CoreEventMap } from '@idraw/types';
import { formatNumber, getViewScaleInfoFromSnapshot, getViewSizeInfoFromSnapshot, createUUID, limitAngle, rotatePoint, parseAngleToRadian } from '@idraw/util';
import { keySelectedElementList, keyHoverElement, keyActionType, keyGroupQueue } from '../selector';
import { keySelectedElementList, keyActionType, keyGroupQueue } from '../selector';
import { drawSizeInfoText, drawPositionInfoText, drawAngleInfoText } from './draw-info';
import type { DeepInfoSharedStorage } from './types';
import { defaltStyle } from './config';

const infoFontSize = 10;
const infoLineHeight = 16;

export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, any, MiddlewareInfoConfig> = (opts, config) => {
export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, CoreEventMap, MiddlewareInfoConfig> = (opts, config) => {
const { boardContent, calculator } = opts;
const { overlayContext } = boardContent;
const innerConfig = {
Expand All @@ -28,11 +28,10 @@ export const MiddlewareInfo: BoardMiddleware<DeepInfoSharedStorage, any, Middlew
const { sharedStore } = snapshot;

const selectedElementList = sharedStore[keySelectedElementList];
const hoverElement = sharedStore[keyHoverElement];
const actionType = sharedStore[keyActionType];
const groupQueue = sharedStore[keyGroupQueue] || [];

if (selectedElementList.length === 1 && !hoverElement?.operations?.locked) {
if (selectedElementList.length === 1) {
const elem = selectedElementList[0];
if (elem && ['select', 'drag', 'resize'].includes(actionType as string)) {
const viewScaleInfo = getViewScaleInfoFromSnapshot(snapshot);
Expand Down
14 changes: 7 additions & 7 deletions packages/core/src/middleware/layout-selector/index.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig } from '@idraw/types';
import type { BoardMiddleware, ElementSize, Point, MiddlewareLayoutSelectorConfig, CoreEventMap } from '@idraw/types';
import { calcLayoutSizeController, isViewPointInVertexes, getViewScaleInfoFromSnapshot, isViewPointInElementSize, calcViewElementSize } from '@idraw/util';
import type { LayoutSelectorSharedStorage, ControlType } from './types';
import { keyLayoutActionType, keyLayoutController, keyLayoutControlType, keyLayoutIsHover, keyLayoutIsSelected, controllerSize, defaultStyle } from './config';
import { keyActionType as keyElementActionType, keyHoverElement, middlewareEventSelectClear } from '../selector';
import { keyActionType as keyElementActionType, keyHoverElement } from '../selector';
import { drawLayoutController, drawLayoutHover } from './util';
import { eventChange } from '../../config';
import { coreEventKeys } from '../../config';

export { keyLayoutIsSelected };

export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, any, MiddlewareLayoutSelectorConfig> = (opts, config) => {
export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, CoreEventMap, MiddlewareLayoutSelectorConfig> = (opts, config) => {
const { sharer, boardContent, calculator, viewer, eventHub } = opts;
const { overlayContext } = boardContent;
const innerConfig = {
Expand Down Expand Up @@ -110,7 +110,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
}
if (layoutControlType) {
sharer.setSharedStorage(keyLayoutControlType, layoutControlType);
eventHub.trigger(middlewareEventSelectClear, {});
eventHub.trigger(coreEventKeys.CLEAR_SELECT);
return layoutControlType;
}
}
Expand All @@ -122,7 +122,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
if (isBusy === true) {
return;
}
eventHub.trigger('cursor', {
eventHub.trigger(coreEventKeys.CURSOR, {
type: controlType ? `resize-${controlType}` : controlType,
groupQueue: [],
element: getLayoutSize()
Expand Down Expand Up @@ -309,7 +309,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
const layoutControlType = sharer.getSharedStorage(keyLayoutControlType);
const data = sharer.getActiveStorage('data');
if (data && layoutActionType === 'resize' && layoutControlType) {
eventHub.trigger(eventChange, {
eventHub.trigger(coreEventKeys.CHANGE, {
type: 'changeLayout',
data
});
Expand Down
60 changes: 60 additions & 0 deletions packages/core/src/middleware/pointer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { BoardMiddleware, CoreEventMap } from '@idraw/types';
import type { DeepPointerSharedStorage } from './types';
import { keySelectedElementList } from '../selector';
import { coreEventKeys } from '../../config';

export const MiddlewarePointer: BoardMiddleware<DeepPointerSharedStorage, CoreEventMap> = (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 || []
});
}
};
};
4 changes: 4 additions & 0 deletions packages/core/src/middleware/pointer/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { keySelectedElementList } from '../selector';
import type { DeepSelectorSharedStorage } from '../selector';

export type DeepPointerSharedStorage = Pick<DeepSelectorSharedStorage, typeof keySelectedElementList>;
7 changes: 3 additions & 4 deletions packages/core/src/middleware/ruler/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<DeepRulerSharedStorage, CoreEventMap, MiddlewareRulerConfig> = (opts, config) => {
const { boardContent, viewer, eventHub, calculator } = opts;
Expand Down Expand Up @@ -43,10 +42,10 @@ export const MiddlewareRuler: BoardMiddleware<DeepRulerSharedStorage, CoreEventM
return {
name: '@middleware/ruler',
use() {
eventHub.on(middlewareEventRuler, rulerCallback);
eventHub.on(coreEventKeys.RULER, rulerCallback);
},
disuse() {
eventHub.off(middlewareEventRuler, rulerCallback);
eventHub.off(coreEventKeys.RULER, rulerCallback);
},
beforeDrawFrame: ({ snapshot }) => {
if (show === true) {
Expand Down
5 changes: 2 additions & 3 deletions packages/core/src/middleware/scaler/index.ts
Original file line number Diff line number Diff line change
@@ -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<Record<string, any>, CoreEventMap> = (opts) => {
const { viewer, sharer, eventHub } = opts;
Expand All @@ -27,7 +26,7 @@ export const MiddlewareScaler: BoardMiddleware<Record<string, any>, CoreEventMap
viewer.scroll({ moveX, moveY });
viewer.drawFrame();
const scaleNum = formatNumber(scale);
eventHub.trigger(middlewareEventScale, { scale: scaleNum });
eventHub.trigger(coreEventKeys.SCALE, { scale: scaleNum });
}
};
};
3 changes: 2 additions & 1 deletion packages/core/src/middleware/scroller/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<DeepScrollerSharedStorage, any, MiddlewareScrollerConfig> = (opts, config) => {
const { viewer, boardContent, sharer, eventHub } = opts;
Expand Down Expand Up @@ -98,7 +99,7 @@ export const MiddlewareScroller: BoardMiddleware<DeepScrollerSharedStorage, any,
sharer.setSharedStorage(keyHoverXThumbRect, false);
sharer.setSharedStorage(keyHoverYThumbRect, true);
}
eventHub.trigger('cursor', { type: 'default' });
eventHub.trigger(coreEventKeys.CURSOR, { type: 'default' });
return false;
}

Expand Down
Loading
Loading