Skip to content

Commit

Permalink
Merge pull request #344 from idrawjs/dev-v0.4
Browse files Browse the repository at this point in the history
feat: improve layout selector middleware
  • Loading branch information
chenshenhai authored Aug 11, 2024
2 parents 00bc0bb + 2b56320 commit 2ce3d17
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 41 deletions.
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class Core<E extends CoreEventMap = CoreEventMap> {
// this.#opts = opts;
this.#container = container;
const canvas = document.createElement('canvas');
canvas.setAttribute('tabindex', '0');
this.#canvas = canvas;
this.#initContainer();
container.appendChild(canvas);
Expand Down
4 changes: 3 additions & 1 deletion packages/core/src/middleware/layout-selector/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ export const key = 'LAYOUT_SELECT';
export const keyLayoutActionType = Symbol(`${key}_layoutActionType`); // 'resize' | null = null;
export const keyLayoutControlType = Symbol(`${key}_layoutControlType`); // ControlType | null;
export const keyLayoutController = Symbol(`${key}_layoutController`); // ElementSizeController | null = null;
export const keyLayoutIsHover = Symbol(`${key}_layoutIsHover`); // boolean | null
export const keyLayoutIsHoverContent = Symbol(`${key}_layoutIsHoverContent`); // boolean | null
export const keyLayoutIsHoverController = Symbol(`${key}_layoutIsHoverController`); // boolean | null
export const keyLayoutIsSelected = Symbol(`${key}_layoutIsSelected`); // boolean | null
export const keyLayoutIsBusyMoving = Symbol(`${key}_layoutIsSelected`); // boolean | null

// const selectColor = '#b331c9';
// const disabledColor = '#5b5959b5';
Expand Down
108 changes: 75 additions & 33 deletions packages/core/src/middleware/layout-selector/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
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 } from '../selector';
import {
keyLayoutActionType,
keyLayoutController,
keyLayoutControlType,
keyLayoutIsHoverContent,
keyLayoutIsHoverController,
keyLayoutIsSelected,
keyLayoutIsBusyMoving,
controllerSize,
defaultStyle
} from './config';
import {
keyActionType as keyElementActionType
// keyHoverElement
} from '../selector';
import { drawLayoutController, drawLayoutHover } from './util';
import { coreEventKeys } from '../../config';

export { keyLayoutIsSelected };
export { keyLayoutIsSelected, keyLayoutIsBusyMoving };

export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStorage, CoreEventMap, MiddlewareLayoutSelectorConfig> = (opts, config) => {
const { sharer, boardContent, calculator, viewer, eventHub } = opts;
Expand All @@ -19,30 +32,30 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
const style = { activeColor };

let prevPoint: Point | null = null;
let prevIsHover: boolean | null = null;
let prevIsHoverContent: boolean | null = null;
let prevIsSelected: boolean | null = null;
let isBusy: boolean | null = null;

const clear = () => {
prevPoint = null;
sharer.setSharedStorage(keyLayoutActionType, null);
sharer.setSharedStorage(keyLayoutControlType, null);
sharer.setSharedStorage(keyLayoutController, null);
sharer.setSharedStorage(keyLayoutIsHover, null);
sharer.setSharedStorage(keyLayoutIsHoverContent, null);
sharer.setSharedStorage(keyLayoutIsHoverController, null);
sharer.setSharedStorage(keyLayoutIsSelected, null);
prevIsHover = null;
sharer.setSharedStorage(keyLayoutIsBusyMoving, null);
prevIsHoverContent = null;
prevIsSelected = null;
isBusy = null;
};

const isInElementHover = () => {
const hoverElement = sharer.getSharedStorage(keyHoverElement);
if (hoverElement) {
clear();
return true;
}
return false;
};
// const isInElementHover = () => {
// const hoverElement = sharer.getSharedStorage(keyHoverElement);
// if (hoverElement) {
// clear();
// return true;
// }
// return false;
// };

const isInElementAction = () => {
const elementActionType = sharer.getSharedStorage(keyElementActionType);
Expand Down Expand Up @@ -95,6 +108,7 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
const resetControlType = (e?: { point: Point }) => {
const data = sharer.getActiveStorage('data');
const controller = sharer.getSharedStorage(keyLayoutController);
let controllerType: ControlType | null = null;
if (controller && data?.layout && e?.point) {
// sharer.setSharedStorage(keyLayoutControlType, null);
let layoutControlType: ControlType | null = null;
Expand All @@ -111,15 +125,22 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
if (layoutControlType) {
sharer.setSharedStorage(keyLayoutControlType, layoutControlType);
eventHub.trigger(coreEventKeys.CLEAR_SELECT);
return layoutControlType;
controllerType = layoutControlType;
}
}
}
return null;

if (controllerType) {
sharer.setSharedStorage(keyLayoutIsHoverController, true);
} else {
sharer.setSharedStorage(keyLayoutIsHoverController, false);
}

return controllerType;
};

const updateCursor = (controlType?: ControlType | null) => {
if (isBusy === true) {
if (sharer.getSharedStorage(keyLayoutIsBusyMoving) === true) {
return;
}
eventHub.trigger(coreEventKeys.CURSOR, {
Expand All @@ -131,34 +152,37 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora

return {
name: '@middleware/layout-selector',

use: () => {
clear();
resetController();
},

hover: (e) => {
if (isBusy === true) {
if (sharer.getSharedStorage(keyLayoutIsBusyMoving) === true) {
return;
}
if (isInElementAction()) {
return;
}
if (isInElementHover()) {
return;
}
// if (isInElementHover()) {
// return;
// }

if (isInLayout(e.point)) {
sharer.setSharedStorage(keyLayoutIsHover, true);
sharer.setSharedStorage(keyLayoutIsHoverContent, true);
} else {
sharer.setSharedStorage(keyLayoutIsHover, false);
if (prevIsHover === true) {
sharer.setSharedStorage(keyLayoutIsHoverContent, false);
if (prevIsHoverContent === true) {
viewer.drawFrame();
prevIsHover = false;
prevIsHoverContent = false;
}
}

if (sharer.getSharedStorage(keyLayoutIsSelected) === true) {
const prevLayoutActionType = sharer.getSharedStorage(keyLayoutActionType);
const data = sharer.getActiveStorage('data');

if (data?.layout) {
if (prevLayoutActionType !== 'resize') {
resetController();
Expand All @@ -175,13 +199,20 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
updateCursor(layoutControlType);
}
}
if (sharer.getSharedStorage(keyLayoutIsHoverController) === true) {
return false;
}
return;
}

if (sharer.getSharedStorage(keyLayoutIsHover) && !prevIsHover) {
if (sharer.getSharedStorage(keyLayoutIsHoverContent) && !prevIsHoverContent) {
viewer.drawFrame();
}
prevIsHover = sharer.getSharedStorage(keyLayoutIsHover);
prevIsHoverContent = sharer.getSharedStorage(keyLayoutIsHoverContent);

if (sharer.getSharedStorage(keyLayoutIsHoverController) === true) {
return false;
}
},

pointStart: (e) => {
Expand Down Expand Up @@ -211,20 +242,26 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
viewer.drawFrame();
}
prevIsSelected = sharer.getSharedStorage(keyLayoutIsSelected);

if (sharer.getSharedStorage(keyLayoutIsHoverController) === true) {
return false;
}
},

pointMove: (e) => {
if (!sharer.getSharedStorage(keyLayoutIsSelected)) {
if (isInElementAction()) {
return;
}
}

const layoutActionType = sharer.getSharedStorage(keyLayoutActionType);
const layoutControlType = sharer.getSharedStorage(keyLayoutControlType);
const data = sharer.getActiveStorage('data');

if (layoutActionType === 'resize' && layoutControlType && data?.layout) {
if (prevPoint) {
isBusy = true;
sharer.setSharedStorage(keyLayoutIsBusyMoving, true);
const scale = sharer.getActiveStorage('scale');
const viewMoveX = e.point.x - prevPoint.x;
const viewMoveY = e.point.y - prevPoint.y;
Expand Down Expand Up @@ -295,16 +332,16 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
prevPoint = e.point;
resetController();
viewer.drawFrame();

return false;
}

if (['resize'].includes(layoutActionType as string)) {
return false;
}
},

pointEnd: () => {
isBusy = false;
sharer.setSharedStorage(keyLayoutIsBusyMoving, false);
const layoutActionType = sharer.getSharedStorage(keyLayoutActionType);
const layoutControlType = sharer.getSharedStorage(keyLayoutControlType);
const data = sharer.getActiveStorage('data');
Expand All @@ -314,15 +351,20 @@ export const MiddlewareLayoutSelector: BoardMiddleware<LayoutSelectorSharedStora
data
});
}

if (sharer.getSharedStorage(keyLayoutIsHoverController) === true) {
return false;
}
},

beforeDrawFrame: ({ snapshot }) => {
if (isInElementAction()) {
return;
}

const { sharedStore, activeStore } = snapshot;
const layoutActionType = sharedStore[keyLayoutActionType];
const layoutIsHover = sharedStore[keyLayoutIsHover];
const layoutIsHover = sharedStore[keyLayoutIsHoverContent];
const layoutIsSelected = sharedStore[keyLayoutIsSelected];

if (activeStore.data?.layout) {
Expand Down
14 changes: 12 additions & 2 deletions packages/core/src/middleware/layout-selector/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import type { LayoutSizeController, Element } from '@idraw/types';
import { keyLayoutActionType, keyLayoutControlType, keyLayoutController, keyLayoutIsHover, keyLayoutIsSelected } from './config';
import {
keyLayoutActionType,
keyLayoutControlType,
keyLayoutController,
keyLayoutIsHoverContent,
keyLayoutIsHoverController,
keyLayoutIsSelected,
keyLayoutIsBusyMoving
} from './config';
import { keyActionType as keyElementActionType, keyHoverElement } from '../selector';
import type { ActionType as ElementActionType } from '../selector';

Expand All @@ -13,6 +21,8 @@ export type LayoutSelectorSharedStorage = {
[keyLayoutController]: LayoutSizeController | null;
[keyElementActionType]: ElementActionType | null;
[keyHoverElement]: Element | null;
[keyLayoutIsHover]: boolean | null;
[keyLayoutIsHoverContent]: boolean | null;
[keyLayoutIsHoverController]: boolean | null;
[keyLayoutIsSelected]: boolean | null;
[keyLayoutIsBusyMoving]: boolean | null;
};
6 changes: 5 additions & 1 deletion packages/core/src/middleware/selector/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import {
} from './config';
import { calcReferenceInfo } from './reference';
import { coreEventKeys } from '../../config';
import { keyLayoutIsSelected } from '../layout-selector';
import { keyLayoutIsSelected, keyLayoutIsBusyMoving } from '../layout-selector';
import { createRotateControllerPattern } from './pattern';
import { MIDDLEWARE_INTERNAL_EVENT_SHOW_INFO_ANGLE } from '../info';
// import { drawDebugStoreSelectedElementController } from './draw-debug';
Expand Down Expand Up @@ -281,6 +281,10 @@ export const MiddlewareSelector: BoardMiddleware<

hover: (e: PointWatcherEvent) => {
const layoutIsSelected = sharer.getSharedStorage(keyLayoutIsSelected);
const layoutIsBusyMoving = sharer.getSharedStorage(keyLayoutIsBusyMoving);
if (layoutIsBusyMoving === true) {
return;
}

const resizeType = sharer.getSharedStorage(keyResizeType);
const actionType = sharer.getSharedStorage(keyActionType);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/middleware/selector/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {
keyDebugStartHorizontal,
keyDebugStartVertical
} from './config';
import { keyLayoutIsSelected } from '../layout-selector';
import { keyLayoutIsSelected, keyLayoutIsBusyMoving } from '../layout-selector';

export {
Data,
Expand Down Expand Up @@ -116,4 +116,5 @@ export type DeepSelectorSharedStorage = {

// layout-selector
[keyLayoutIsSelected]: boolean | null;
[keyLayoutIsBusyMoving]: boolean | null;
};
6 changes: 3 additions & 3 deletions packages/idraw/src/mode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import {
MiddlewareInfo,
MiddlewarePointer
} from '@idraw/core';
import { InnerEvent } from './event';
import { IDrawEvent } from './event';

function isValidMode(mode: string | IDrawMode) {
return ['select', 'drag', 'readOnly'].includes(mode);
}

export function runMiddlewares(core: Core<InnerEvent>, store: Store<IDrawStorage>) {
export function runMiddlewares(core: Core<IDrawEvent>, store: Store<IDrawStorage>) {
const { enableRuler, enableScale, enableScroll, enableSelect, enableTextEdit, enableDrag, enableInfo } = store.getSnapshot();
const styles = store.get('middlewareStyles');
if (enableScroll === true) {
Expand Down Expand Up @@ -68,7 +68,7 @@ export function runMiddlewares(core: Core<InnerEvent>, store: Store<IDrawStorage
core.use(MiddlewarePointer);
}

export function changeMode(mode: IDrawMode, core: Core<InnerEvent>, store: Store<IDrawStorage>) {
export function changeMode(mode: IDrawMode, core: Core<IDrawEvent>, store: Store<IDrawStorage>) {
let enableScale: boolean = false;
let enableScroll: boolean = false;
let enableSelect: boolean = false;
Expand Down

0 comments on commit 2ce3d17

Please sign in to comment.