Skip to content

Commit

Permalink
feat: double click to active path editor
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed Mar 10, 2024
1 parent cd34c0b commit b73daed
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 34 deletions.
22 changes: 14 additions & 8 deletions packages/core/src/path_editor/path_editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ import { getRotatedRectByTwoPoint, isPointEqual } from '@suika/geo';

import { RemoveGraphsCmd } from '../commands';
import { ControlHandle } from '../control_handle_manager';
import { Editor } from '../editor';
import { Ellipse, Graph, Line, Path, Rect } from '../graphs';
import { type Editor } from '../editor';
import { Ellipse, type Graph, Line, Path, Rect } from '../graphs';
import { TextureType } from '../texture';
import { DrawPathTool, PathSelectTool } from '../tools';
import { SelectTool } from '../tools/tool_select';
import { ISelectedIdxInfo, SelectedIdexType } from './type';
import { type ISelectedIdxInfo, type SelectedIdexType } from './type';

interface Events {
toggle: (active: boolean) => void;
Expand Down Expand Up @@ -42,19 +42,25 @@ export class PathEditor {
this._active = true;
this.path = path;

this.editor.sceneGraph.showSelectedGraphsOutline = false;
this.editor.sceneGraph.highlightLayersOnHover = false;
const editor = this.editor;
editor.sceneGraph.showSelectedGraphsOutline = false;
editor.sceneGraph.highlightLayersOnHover = false;

this.unbindHotkeys();
this.bindHotkeys();

this.prevToolKeys = this.editor.toolManager.getEnableTools();
this.editor.toolManager.setEnableHotKeyTools([
this.prevToolKeys = editor.toolManager.getEnableTools();
editor.toolManager.setEnableHotKeyTools([
PathSelectTool.type,
DrawPathTool.type,
]);
const currTool = editor.toolManager.getActiveToolName();
if (currTool !== PathSelectTool.type && currTool !== DrawPathTool.type) {
editor.toolManager.setActiveTool(PathSelectTool.type);
}

this.editor.selectedElements.on('itemsChange', this.onSelectedChange);
editor.selectedElements.on('itemsChange', this.onSelectedChange);
editor.pathEditor.updateControlHandles();
this.eventEmitter.emit('toggle', true);
}
inactive(source?: 'undo') {
Expand Down
16 changes: 10 additions & 6 deletions packages/core/src/scene/scene_graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,20 @@ import {
forEach,
getDevicePixelRatio,
} from '@suika/common';
import { IRect, isRectIntersect } from '@suika/geo';
import { type IPoint, type IRect, isRectIntersect } from '@suika/geo';

import { Editor } from '../editor';
import { type Editor } from '../editor';
import {
Ellipse,
Graph,
GraphAttrs,
type GraphAttrs,
Line,
Path,
Rect,
TextGraph,
} from '../graphs';
import Grid from '../grid';
import { GraphType, IEditorPaperData, IObject } from '../type';
import { GraphType, type IEditorPaperData, type IObject } from '../type';
import { rafThrottle } from '../utils';

const graphCtorMap = {
Expand Down Expand Up @@ -319,7 +319,7 @@ export class SceneGraph {
// ctx.restore();
// }

getTopHitElement(x: number, y: number): Graph | null {
getTopHitElement(point: IPoint): Graph | null {
const padding =
this.editor.setting.get('selectionHitPadding') /
this.editor.zoomManager.getZoom();
Expand All @@ -328,7 +328,11 @@ export class SceneGraph {
// TODO: optimize, use r-tree to reduce time complexity
for (let i = this.children.length - 1; i >= 0; i--) {
const el = this.children[i];
if (el.getVisible() && !el.getLock() && el.hitTest(x, y, padding)) {
if (
el.getVisible() &&
!el.getLock() &&
el.hitTest(point.x, point.y, padding)
) {
topHitElement = el;
break;
}
Expand Down
38 changes: 25 additions & 13 deletions packages/core/src/tools/tool_select/tool_select.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { throttle } from '@suika/common';

import { ICursor, isRotationCursor } from '../../cursor_manager';
import { Editor } from '../../editor';
import { Graph } from '../../graphs';
import { IPoint } from '../../type';
import { IBaseTool, ITool } from '../type';
import { type ICursor, isRotationCursor } from '../../cursor_manager';
import { type Editor } from '../../editor';
import { type Graph, type Path } from '../../graphs';
import { GraphType, type IPoint } from '../../type';
import { type IBaseTool, type ITool } from '../type';
import { SelectMoveTool } from './tool_select_move';
import { SelectResizeTool } from './tool_select_resize';
import { SelectRotationTool } from './tool_select_rotation';
Expand Down Expand Up @@ -50,17 +50,35 @@ export class SelectTool implements ITool {
}
};

// double click to active path editor
private onDblClick = () => {
const point = this.editor.toolManager.getCurrPoint();
const editor = this.editor;
if (editor.hostEventManager.isShiftPressing) return;
const handleInfo = editor.controlHandleManager.getHandleInfoByPoint(point);
if (handleInfo) return;

const topHitElement = editor.sceneGraph.getTopHitElement(point);
if (!topHitElement) return;

if (topHitElement.type === GraphType.Path) {
editor.pathEditor.active(topHitElement as Path);
}
};

onActive() {
this.editor.selectedElements.on(
'hoverItemChange',
this.handleHoverItemChange,
);
this.editor.canvasElement.addEventListener('dblclick', this.onDblClick);
}
onInactive() {
this.editor.selectedElements.off(
'hoverItemChange',
this.handleHoverItemChange,
);
this.editor.canvasElement.removeEventListener('dblclick', this.onDblClick);
this.editor.render();
}

Expand All @@ -84,10 +102,7 @@ export class SelectTool implements ITool {
if (handleInfo) {
this.editor.selectedElements.setHoverItem(null);
} else {
const topHitElement = this.editor.sceneGraph.getTopHitElement(
point.x,
point.y,
);
const topHitElement = this.editor.sceneGraph.getTopHitElement(point);
this.editor.selectedElements.setHoverItem(topHitElement);
}
}, 20);
Expand Down Expand Up @@ -128,10 +143,7 @@ export class SelectTool implements ITool {
const isInsideSelectedBox = this.editor.selectedBox.hitTest(
this.startPoint,
);
const topHitElement = sceneGraph.getTopHitElement(
this.startPoint.x,
this.startPoint.y,
);
const topHitElement = sceneGraph.getTopHitElement(this.startPoint);
if (
topHitElement &&
isShiftPressing &&
Expand Down
11 changes: 4 additions & 7 deletions packages/core/src/tools/tool_select/tool_select_move.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { noop } from '@suika/common';

import { MoveGraphsCommand } from '../../commands/move_graphs';
import { Editor } from '../../editor';
import { IPoint } from '../../type';
import { IBaseTool } from '../type';
import { type Editor } from '../../editor';
import { type IPoint } from '../../type';
import { type IBaseTool } from '../type';

/**
* select tool
Expand Down Expand Up @@ -131,10 +131,7 @@ export class SelectMoveTool implements IBaseTool {
if (!isDragHappened) {
// clear selected elements if click on blank area and not dragging
const point = this.editor.getSceneCursorXY(e);
const topHitElement = this.editor.sceneGraph.getTopHitElement(
point.x,
point.y,
);
const topHitElement = this.editor.sceneGraph.getTopHitElement(point);
if (!topHitElement && !this.editor.hostEventManager.isShiftPressing) {
this.editor.selectedElements.clear();
}
Expand Down

0 comments on commit b73daed

Please sign in to comment.