Skip to content

Commit 6c95712

Browse files
committed
文本编辑状态中,也支持文本样式修改的撤销回退操作
1 parent 1f0bcc7 commit 6c95712

File tree

10 files changed

+348
-100
lines changed

10 files changed

+348
-100
lines changed

src/modules/command/ElementsBaseCommand.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import IStageStore from "@/types/IStageStore";
44
export default class ElementsBaseCommand<T> implements ICommand<T> {
55
payload: T;
66
store: IStageStore;
7+
id: string;
8+
relationId?: string;
79

8-
constructor(payload: T, store: IStageStore) {
10+
constructor(id: string, payload: T, store: IStageStore, relationId?: string) {
911
this.payload = payload;
1012
this.store = store;
13+
this.id = id;
14+
this.relationId = relationId;
1115
}
1216

1317
async undo(): Promise<void> {

src/modules/command/text/TextEditorBaseCommand.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ import { IElementText } from "@/types/IElement";
44
export default class TextEditorBaseCommand<T> implements ICommand<T> {
55
payload: T;
66
element: IElementText;
7+
id: string;
8+
relationId?: string;
79

8-
constructor(payload: T, element: IElementText) {
10+
constructor(id: string, payload: T, element: IElementText, relationId?: string) {
911
this.payload = payload;
1012
this.element = element;
13+
this.id = id;
14+
this.relationId = relationId;
1115
}
1216

1317
async undo(): Promise<void> {

src/modules/elements/Element.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,6 +1336,20 @@ export default class Element implements IElement, ILinkedNodeValue {
13361336
}
13371337
}
13381338

1339+
/**
1340+
* 发送撤销事件
1341+
*/
1342+
protected async emitUndo(): Promise<void> {
1343+
await this.shield.execUndo();
1344+
}
1345+
1346+
/**
1347+
* 发送重做事件
1348+
*/
1349+
protected async emitRedo(): Promise<void> {
1350+
await this.shield.execRedo();
1351+
}
1352+
13391353
/**
13401354
* 将坐标根据描边类型进行转换
13411355
*

src/modules/elements/ElementText.ts

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,26 +106,26 @@ export default class ElementText extends ElementRect implements IElementText {
106106
}
107107

108108
get fontLineHeightFactorInputEnable(): boolean {
109-
return this.status === ElementStatus.finished;
109+
return true;
110110
}
111111

112112
get fontLetterSpacingInputEnable(): boolean {
113113
return true;
114114
}
115115

116116
get paragraphSpacingInputEnable(): boolean {
117-
return this.status === ElementStatus.finished;
117+
return true;
118118
}
119119

120120
get textCaseInputEnable(): boolean {
121-
return this.status === ElementStatus.finished;
121+
return true;
122122
}
123123

124124
get textAlignInputEnable(): boolean {
125-
return this.status === ElementStatus.finished;
125+
return true;
126126
}
127127
get textVerticalAlignInputEnable(): boolean {
128-
return this.status === ElementStatus.finished;
128+
return true;
129129
}
130130

131131
get editingEnable(): boolean {
@@ -543,6 +543,8 @@ export default class ElementText extends ElementRect implements IElementText {
543543
// 撤销
544544
const tailUndoCommand = this._undoRedo.tailUndoCommand;
545545
if (tailUndoCommand) {
546+
const { relationId } = tailUndoCommand;
547+
if (relationId) await this.emitUndo();
546548
await this._undoRedo.undo();
547549
this._editorOperation = TextEditorOperations.UNDO;
548550
if (![TextEditorOperations.MOVE_CURSOR, TextEditorOperations.MOVE_SELECTION].includes(tailUndoCommand.payload.operation)) {
@@ -553,6 +555,8 @@ export default class ElementText extends ElementRect implements IElementText {
553555
// 回退
554556
const tailRedoCommand = this._undoRedo.tailRedoCommand;
555557
if (tailRedoCommand) {
558+
const { relationId } = tailRedoCommand;
559+
if (relationId) await this.emitRedo();
556560
await this._undoRedo.redo();
557561
this._editorOperation = TextEditorOperations.REDO;
558562
if (![TextEditorOperations.MOVE_CURSOR, TextEditorOperations.MOVE_SELECTION].includes(tailRedoCommand.payload.operation)) {
@@ -1733,6 +1737,7 @@ export default class ElementText extends ElementRect implements IElementText {
17331737
tailUndoCommand.payload.rData = this._getTextEditorCommandObject();
17341738
} else {
17351739
const command = new TextEditorUpdatedCommand(
1740+
nanoid(),
17361741
{
17371742
type: TextEeditorCommandTypes.TextUpdated,
17381743
operation: this._editorOperation,
@@ -1771,6 +1776,7 @@ export default class ElementText extends ElementRect implements IElementText {
17711776
tailUndoCommand.payload.rData = this._getTextEditorCommandObject({ dataExclude: true });
17721777
} else {
17731778
const command = new TextEditorUpdatedCommand(
1779+
nanoid(),
17741780
{
17751781
type: TextEeditorCommandTypes.CursorSelectionUpdated,
17761782
operation: this._editorOperation,
@@ -1902,4 +1908,31 @@ export default class ElementText extends ElementRect implements IElementText {
19021908
isModelPolygonOverlap(coords: IPoint[]): boolean {
19031909
return super.isModelPolygonOverlap(coords) || MathUtils.isPolygonsOverlap(this._getTextRotateRenderCoords(), coords);
19041910
}
1911+
1912+
/**
1913+
* 刷新文本编辑器撤销命令对象(刷新当前状态以便回退)
1914+
*/
1915+
refreshUndoCommandObject(): void {
1916+
this._undoCommandObject = this._getTextEditorCommandObject();
1917+
}
1918+
1919+
/**
1920+
* 关联组件撤销命令
1921+
*
1922+
* @param commandId
1923+
*/
1924+
relationUndoCommand(commandId: string): void {
1925+
const editCommand = new TextEditorUpdatedCommand(
1926+
nanoid(),
1927+
{
1928+
type: TextEeditorCommandTypes.CursorSelectionUpdated,
1929+
operation: this._editorOperation,
1930+
updateId: this._textUpdateId,
1931+
uData: this._undoCommandObject,
1932+
},
1933+
this,
1934+
commandId,
1935+
);
1936+
this._undoRedo.add(editCommand);
1937+
}
19051938
}

src/modules/elements/utils/TextElementUtils.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { FontStyle, FontStyleSet, TextFontStyle } from "@/styles/ElementStyles";
22
import { Direction, IPoint } from "@/types";
33
import { TextCursorWidth } from "@/types/constants";
44
import { ElementObject } from "@/types/IElement";
5-
import ITextData, { ITextCursor, ITextLine, ITextNode, ITextSelection } from "@/types/IText";
5+
import ITextData, { ITextCursor, ITextLine, ITextNode, ITextSelection, TextFontStyleUpdateTypes } from "@/types/IText";
66
import CommonUtils from "@/utils/CommonUtils";
77
import LodashUtils from "@/utils/LodashUtils";
88
import { pick, every, isString, isNumber } from "lodash";
@@ -1283,4 +1283,32 @@ export default class TextElementUtils {
12831283
const endY = textLines[textLines.length - 1].y + textLines[textLines.length - 1].height;
12841284
return (endY - startY) / scale;
12851285
}
1286+
1287+
/**
1288+
* 判断是否应该为撤销回退命令关联到当前的文本编辑命令
1289+
1290+
* @param updateType 更新类型
1291+
* @returns 是否为关系型命令
1292+
*/
1293+
static shouldRelationUndoCommand(updateType: TextFontStyleUpdateTypes): boolean {
1294+
return [
1295+
TextFontStyleUpdateTypes.FONT_FAMILY,
1296+
TextFontStyleUpdateTypes.FONT_SIZE,
1297+
TextFontStyleUpdateTypes.FONT_COLOR,
1298+
TextFontStyleUpdateTypes.FONT_COLOR_OPACITY,
1299+
TextFontStyleUpdateTypes.FONT_LETTER_SPACING,
1300+
TextFontStyleUpdateTypes.FONT_STYLER,
1301+
TextFontStyleUpdateTypes.FONT_TEXT_CASE,
1302+
TextFontStyleUpdateTypes.FONT_TEXT_DECORATION,
1303+
TextFontStyleUpdateTypes.FONT_TEXT_DECORATION_COLOR,
1304+
TextFontStyleUpdateTypes.FONT_TEXT_DECORATION_OPACITY,
1305+
TextFontStyleUpdateTypes.FONT_TEXT_DECORATION_THICKNESS,
1306+
TextFontStyleUpdateTypes.FONT_LINE_HEIGHT,
1307+
TextFontStyleUpdateTypes.FONT_LINE_HEIGHT_FACTOR,
1308+
TextFontStyleUpdateTypes.FONT_LINE_HEIGHT_AUTO_FIT,
1309+
TextFontStyleUpdateTypes.FONT_TEXT_ALIGN,
1310+
TextFontStyleUpdateTypes.FONT_TEXT_VERTICAL_ALIGN,
1311+
TextFontStyleUpdateTypes.FONT_PARAGRAPH_SPACING,
1312+
].includes(updateType);
1313+
}
12861314
}

0 commit comments

Comments
 (0)