Skip to content

Commit

Permalink
feat: draw path tool
Browse files Browse the repository at this point in the history
  • Loading branch information
F-star committed Feb 17, 2024
1 parent fe362ff commit b0c8b49
Show file tree
Hide file tree
Showing 51 changed files with 1,324 additions and 381 deletions.
4 changes: 2 additions & 2 deletions packages/core/src/clipboard.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { arrMap, noop, omit } from '@suika/common';

import { AddShapeCommand } from './commands/add_shape';
import { AddGraphCmd } from './commands/add_graphs';
import { Editor } from './editor';
import { Graph } from './graphs';
import { IEditorPaperData } from './type';
Expand Down Expand Up @@ -120,7 +120,7 @@ export class ClipboardManager {

// TODO: duplicated objectName should be renamed
editor.commandManager.pushCommand(
new AddShapeCommand('pasted graphs', editor, pastedGraphs),
new AddGraphCmd('pasted graphs', editor, pastedGraphs),
);
editor.selectedElements.setItems(pastedGraphs);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import { Editor } from '../editor';
import { Graph } from '../graphs';
import { ICommand } from './type';

/**
* add elements
*/
export class AddShapeCommand implements ICommand {
export class AddGraphCmd implements ICommand {
constructor(
public desc: string,
private editor: Editor,
Expand Down
95 changes: 76 additions & 19 deletions packages/core/src/commands/command_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,25 @@ interface Events {
beforeExecCmd(): void;
}

interface ICommandItem {
command: ICommand;
/**
* consider the continue commands marked "isBatched" as one macro command
*/
isBatched?: boolean;
}

/**
* Command Manager
*
* reference: https://mp.weixin.qq.com/s/JBhXeFPTw8O34vOtk05cQg
*/
export class CommandManager {
redoStack: ICommand[] = [];
undoStack: ICommand[] = [];
redoStack: ICommandItem[] = [];
undoStack: ICommandItem[] = [];
private isEnableRedoUndo = true;
private emitter = new EventEmitter<Events>();
private isBatching = false;

constructor(private editor: Editor) {}

Expand All @@ -31,14 +40,33 @@ export class CommandManager {
return;
}
if (this.redoStack.length > 0) {
const command = this.redoStack.pop()!;
console.log(
`%c Redo %c ${command.desc}`,
'background: #f04; color: #ee0',
'',
);
this.undoStack.push(command);
command.redo();
const topCmdItem = this.redoStack.pop()!;
const isBatched = topCmdItem.isBatched;
const cmdItems: ICommandItem[] = [topCmdItem];

if (isBatched) {
// if the command is batched, redo all the commands marked "isBatched"
while (this.redoStack.length > 0 && this.redoStack.at(-1)!.isBatched) {
const currCmdItem = this.redoStack.pop()!;
cmdItems.push(currCmdItem);
}
console.log('------- [redo] batched start -----');
}

for (const cmdItem of cmdItems) {
const command = cmdItem.command;
console.log(
`%c Redo %c ${command.desc}`,
'background: #f04; color: #ee0',
'',
);
this.undoStack.push(cmdItem);
command.redo();
}

if (isBatched) {
console.log('------- [redo] batched end -----');
}

this.editor.sceneGraph.render();
this.emitStatusChange();
Expand All @@ -49,14 +77,33 @@ export class CommandManager {
return;
}
if (this.undoStack.length > 0) {
const command = this.undoStack.pop()!;
console.log(
`%c Undo %c ${command.desc}`,
'background: #40f; color: #eee',
'',
);
this.redoStack.push(command);
command.undo();
const topCmdItem = this.undoStack.pop()!;
const isBatched = topCmdItem.isBatched;
const cmdItems: ICommandItem[] = [topCmdItem];

if (isBatched) {
// if the command is batched, undo all the commands marked "isBatched"
while (this.undoStack.length > 0 && this.undoStack.at(-1)!.isBatched) {
const currCmdItem = this.undoStack.pop()!;
cmdItems.push(currCmdItem);
}
console.log('------- [undo] batched start -----');
}

for (const cmdItem of cmdItems) {
const command = cmdItem.command;
console.log(
`%c Undo %c ${command.desc}`,
'background: #40f; color: #eee',
'',
);
this.redoStack.push(cmdItem);
command.undo();
}

if (isBatched) {
console.log('------- [undo] batched end -----');
}

this.editor.sceneGraph.render();
this.emitStatusChange();
Expand All @@ -68,14 +115,24 @@ export class CommandManager {
disableRedoUndo() {
this.isEnableRedoUndo = false;
}
batchCommandStart() {
this.isBatching = true;
}
batchCommandEnd() {
this.isBatching = false;
}
pushCommand(command: ICommand) {
this.emitter.emit('beforeExecCmd');
console.log(
`%c Exec %c ${command.desc}`,
'background: #222; color: #bada55',
'',
);
this.undoStack.push(command);
const commandItem: ICommandItem = { command };
if (this.isBatching) {
commandItem.isBatched = true;
}
this.undoStack.push(commandItem);
this.redoStack = [];
this.emitStatusChange();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/commands/group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Graph } from '../graphs';
import { Group } from '../group_manager';
import { ICommand } from './type';

export class GroupElements implements ICommand {
export class GroupCmd implements ICommand {
private groupedElSet = new Set<Graph>();
/** prevGraphId -> groupInfo */
private prevGroupedElInfoMap = new Map<
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
export * from './add_shape';
export * from './add_graphs';
export * from './align';
export * from './command_manager';
export * from './group';
export * from './move_elements';
export * from './remove_element';
export * from './move_graphs';
export * from './remove_graphs';
export * from './set_elements_attrs';
export * from './type';
30 changes: 0 additions & 30 deletions packages/core/src/commands/move_elements.ts

This file was deleted.

25 changes: 25 additions & 0 deletions packages/core/src/commands/move_graphs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Graph } from '../graphs';
import { ICommand } from './type';

export class MoveGraphsCommand implements ICommand {
constructor(
public desc: string,
private graphs: Graph[],
private dx: number,
private dy: number,
) {}
redo() {
const { dx, dy } = this;
for (let i = 0, len = this.graphs.length; i < len; i++) {
const element = this.graphs[i];
element.updateAttrs({ x: element.x + dx, y: element.y + dy });
}
}
undo() {
const { dx, dy } = this;
for (let i = 0, len = this.graphs.length; i < len; i++) {
const element = this.graphs[i];
element.updateAttrs({ x: element.x - dx, y: element.y - dy });
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Editor } from '../editor';
import { Graph } from '../graphs';
import { ICommand } from './type';

export class RemoveElement implements ICommand {
export class RemoveGraphsCmd implements ICommand {
private removedIndexes: number[] = [];

constructor(
Expand Down
14 changes: 6 additions & 8 deletions packages/core/src/commands/set_elements_attrs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Graph } from '../graphs';
import { Graph, ISegment } from '../graphs';
import { ITexture } from '../texture';
import { ICommand } from './type';

Expand All @@ -15,12 +15,10 @@ export type ISetElementsAttrsType = Partial<{
objectName: string;
visible: boolean;
lock: boolean;
pathData: ISegment[][];
}>;

/**
* 创建矩形
*/
export class SetElementsAttrs implements ICommand {
export class SetGraphsAttrsCmd implements ICommand {
static readonly type = 'SetElementsAttrs';
constructor(
public desc: string,
Expand All @@ -38,16 +36,16 @@ export class SetElementsAttrs implements ICommand {
const { elements, attrs } = this;
for (let i = 0, len = this.elements.length; i < len; i++) {
if (Array.isArray(attrs)) {
elements[i].setAttrs(attrs[i]);
elements[i].updateAttrs(attrs[i]);
} else {
elements[i].setAttrs(attrs);
elements[i].updateAttrs(attrs);
}
}
}
undo() {
const { elements, prevAttrs } = this;
for (let i = 0, len = this.elements.length; i < len; i++) {
elements[i].setAttrs(prevAttrs[i]);
elements[i].updateAttrs(prevAttrs[i]);
}
}
}
12 changes: 10 additions & 2 deletions packages/core/src/control_handle_manager/control_handle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,18 @@ type HitTest = (
x: number,
y: number,
tol: number,
rect: IRectWithRotation,
rect: IRectWithRotation | null,
) => boolean;

type GetCursorFn = (type: string, selectedBox: IRectWithRotation) => ICursor;
type GetCursorFn = (
type: string,
selectedBox: IRectWithRotation | null,
) => ICursor;

export class ControlHandle {
cx: number;
cy: number;
rotation?: number;
type: string;
graph: Graph;
padding: number;
Expand All @@ -25,13 +29,17 @@ export class ControlHandle {
cx?: number;
cy?: number;
type: string;
rotation?: number;
padding?: number;
graph: Graph;
hitTest?: HitTest;
getCursor: GetCursorFn;
}) {
this.cx = attrs.cx ?? 0;
this.cy = attrs.cy ?? 0;
if (attrs.rotation !== undefined) {
this.rotation = attrs.rotation;
}
this.type = attrs.type;
this.padding = attrs.padding ?? 0;
this.graph = attrs.graph;
Expand Down
Loading

0 comments on commit b0c8b49

Please sign in to comment.