From 2420a035bd83e29a36de2b8cc05992f0e252809f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=BA=91=E9=A3=9E?= Date: Sat, 2 Apr 2022 17:12:42 +0800 Subject: [PATCH 1/2] feat:set control cursor --- src/editor/core/draw/Draw.ts | 7 +++ src/editor/core/draw/control/Control.ts | 70 ++++++++++++++++++++++++- src/editor/core/event/CanvasEvent.ts | 9 ++++ src/editor/core/position/Position.ts | 27 +++++++--- src/editor/dataset/constant/Control.ts | 4 +- src/editor/dataset/enum/Control.ts | 2 +- src/editor/interface/Control.ts | 2 + src/editor/interface/Position.ts | 2 + src/editor/utils/element.ts | 2 +- 9 files changed, 115 insertions(+), 10 deletions(-) diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index 736537a..3fa7524 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -34,6 +34,7 @@ import { SeparatorParticle } from './particle/Separator' import { PageBreakParticle } from './particle/PageBreak' import { Watermark } from './frame/Watermark' import { EditorMode } from '../../dataset/enum/Editor' +import { Control } from './control/Control' export class Draw { @@ -70,6 +71,7 @@ export class Draw { private pageBreakParticle: PageBreakParticle private superscriptParticle: SuperscriptParticle private subscriptParticle: SubscriptParticle + private control: Control private rowList: IRow[] private painterStyle: IElementStyle | null @@ -116,6 +118,7 @@ export class Draw { this.pageBreakParticle = new PageBreakParticle(this) this.superscriptParticle = new SuperscriptParticle() this.subscriptParticle = new SubscriptParticle() + this.control = new Control(this) new ScrollObserver(this) new SelectionObserver() @@ -301,6 +304,10 @@ export class Draw { return this.hyperlinkParticle } + public getControl(): Control { + return this.control + } + public getRowCount(): number { return this.rowList.length } diff --git a/src/editor/core/draw/control/Control.ts b/src/editor/core/draw/control/Control.ts index db7fd68..b3b597a 100644 --- a/src/editor/core/draw/control/Control.ts +++ b/src/editor/core/draw/control/Control.ts @@ -1,3 +1,71 @@ +import { ControlComponent } from '../../../dataset/enum/Control' +import { ElementType } from '../../../dataset/enum/Element' +import { IElement } from '../../../interface/Element' +import { ICurrentPosition } from '../../../interface/Position' +import { Draw } from '../Draw' + export class Control { - + + private draw: Draw + + constructor(draw: Draw) { + this.draw = draw + } + + // 调整起始光标位置到控件合适的位置 + public moveCursorIndex(position: ICurrentPosition) { + const { index, trIndex, tdIndex, tdValueIndex } = position + let elementList = this.draw.getOriginalElementList() + let element: IElement + if (position.isTable) { + elementList = elementList[index!].trList![trIndex!].tdList[tdIndex!].value + element = elementList[tdValueIndex!] + } else { + element = elementList[index] + } + if (element.type !== ElementType.CONTROL) return + // VALUE-无需移动 + if (element.controlComponent === ControlComponent.VALUE) return + // POSTFIX-移动到最后一个后缀字符后 + if (element.controlComponent === ControlComponent.POSTFIX) { + let startIndex = index + 1 + while (startIndex < elementList.length) { + const nextElement = elementList[startIndex] + if (nextElement.controlId !== element.controlId) { + position.index = startIndex - 1 + break + } + startIndex++ + } + } else if (element.controlComponent === ControlComponent.PREFIX) { + // PREFIX-移动到最后一个前缀字符后 + let startIndex = index + 1 + while (startIndex < elementList.length) { + const nextElement = elementList[startIndex] + if ( + nextElement.controlId !== element.controlId + || nextElement.controlComponent !== ControlComponent.PREFIX + ) { + position.index = startIndex - 1 + break + } + startIndex++ + } + } else if (element.controlComponent === ControlComponent.PLACEHOLDER) { + // PLACEHOLDER-移动到第一个前缀后 + let startIndex = index - 1 + while (startIndex > 0) { + const preElement = elementList[startIndex] + if ( + preElement.controlId !== element.controlId + || preElement.controlComponent === ControlComponent.PREFIX + ) { + position.index = startIndex + break + } + startIndex-- + } + } + } + } \ No newline at end of file diff --git a/src/editor/core/event/CanvasEvent.ts b/src/editor/core/event/CanvasEvent.ts index dbe45a6..342d0ac 100644 --- a/src/editor/core/event/CanvasEvent.ts +++ b/src/editor/core/event/CanvasEvent.ts @@ -20,6 +20,7 @@ import { Listener } from '../listener/Listener' import { Position } from '../position/Position' import { RangeManager } from '../range/RangeManager' import { LETTER_REG, NUMBER_LIKE_REG } from '../../dataset/constant/Regular' +import { Control } from '../draw/control/Control' export class CanvasEvent { @@ -38,6 +39,7 @@ export class CanvasEvent { private tableTool: TableTool private hyperlinkParticle: HyperlinkParticle private listener: Listener + private control: Control constructor(draw: Draw) { this.isAllowDrag = false @@ -55,6 +57,7 @@ export class CanvasEvent { this.tableTool = this.draw.getTableTool() this.hyperlinkParticle = this.draw.getHyperlinkParticle() this.listener = this.draw.getListener() + this.control = this.draw.getControl() } public register() { @@ -163,9 +166,14 @@ export class CanvasEvent { x: evt.offsetX, y: evt.offsetY }) + // 如果是控件-光标需移动到合适位置 + if (positionResult.isControl) { + this.control.moveCursorIndex(positionResult) + } const { index, isDirectHit, + isControl, isImage, isTable, trIndex, @@ -178,6 +186,7 @@ export class CanvasEvent { // 设置位置上下文 this.position.setPositionContext({ isTable: isTable || false, + isControl: isControl || false, index, trIndex, tdIndex, diff --git a/src/editor/core/position/Position.ts b/src/editor/core/position/Position.ts index 281bceb..cccacf9 100644 --- a/src/editor/core/position/Position.ts +++ b/src/editor/core/position/Position.ts @@ -18,7 +18,8 @@ export class Position { this.positionList = [] this.cursorPosition = null this.positionContext = { - isTable: false + isTable: false, + isControl: false } this.draw = draw @@ -92,14 +93,16 @@ export class Position { positionList: td.positionList }) if (~tablePosition.index) { + const { index: tdValueIndex } = tablePosition return { index, + isControl: td.value[tdValueIndex].type === ElementType.CONTROL, isImage: tablePosition.isImage, isDirectHit: tablePosition.isDirectHit, isTable: true, tdIndex: d, trIndex: t, - tdValueIndex: tablePosition.index, + tdValueIndex, tdId: td.id, trId: tr.id, tableId: element.id @@ -110,7 +113,11 @@ export class Position { } // 图片区域均为命中 if (element.type === ElementType.IMAGE) { - return { index: curPositionIndex, isDirectHit: true, isImage: true } + return { + index: curPositionIndex, + isDirectHit: true, + isImage: true + } } // 判断是否在文字中间前后 if (elementList[index].value !== ZERO) { @@ -119,7 +126,10 @@ export class Position { curPositionIndex = j - 1 } } - return { index: curPositionIndex } + return { + index: curPositionIndex, + isControl: element.type === ElementType.CONTROL, + } } } // 非命中区域 @@ -135,7 +145,9 @@ export class Position { const tdWidth = td.width! const tdHeight = td.height! if (!(tdX < x && x < tdX + tdWidth && tdY < y && y < tdY + tdHeight)) { - return { index: curPositionIndex } + return { + index: curPositionIndex + } } } } @@ -161,7 +173,10 @@ export class Position { // 当前页最后一行 return { index: firstLetterList[firstLetterList.length - 1]?.index || positionList.length - 1 } } - return { index: curPositionIndex } + return { + index: curPositionIndex, + isControl: elementList[curPositionIndex].type === ElementType.CONTROL + } } } \ No newline at end of file diff --git a/src/editor/dataset/constant/Control.ts b/src/editor/dataset/constant/Control.ts index ff2ee47..2190bc3 100644 --- a/src/editor/dataset/constant/Control.ts +++ b/src/editor/dataset/constant/Control.ts @@ -2,5 +2,7 @@ import { IControlOption } from '../../interface/Control' export const defaultControlOption: Readonly> = { placeholderColor: '#9c9b9b', - bracketColor: '#000000' + bracketColor: '#000000', + prefix: '{', + postfix: '}' } \ No newline at end of file diff --git a/src/editor/dataset/enum/Control.ts b/src/editor/dataset/enum/Control.ts index 15ea71a..00670db 100644 --- a/src/editor/dataset/enum/Control.ts +++ b/src/editor/dataset/enum/Control.ts @@ -4,7 +4,7 @@ export enum ControlType { } export enum ControlComponent { - SUFFIX = 'suffix', + PREFIX = 'prefix', POSTFIX = 'postfix', PLACEHOLDER = 'placeholder', VALUE = 'value' diff --git a/src/editor/interface/Control.ts b/src/editor/interface/Control.ts index a380a0d..78f56a0 100644 --- a/src/editor/interface/Control.ts +++ b/src/editor/interface/Control.ts @@ -24,4 +24,6 @@ export type IControl = IControlBasic & Partial export interface IControlOption { placeholderColor?: string; bracketColor?: string; + prefix?: string; + postfix?: string; } \ No newline at end of file diff --git a/src/editor/interface/Position.ts b/src/editor/interface/Position.ts index 2461ce4..a4d9291 100644 --- a/src/editor/interface/Position.ts +++ b/src/editor/interface/Position.ts @@ -4,6 +4,7 @@ import { ITd } from './table/Td' export interface ICurrentPosition { index: number; + isControl?: boolean; isImage?: boolean; isTable?: boolean; isDirectHit?: boolean; @@ -27,6 +28,7 @@ export interface IGetPositionByXYPayload { export interface IPositionContext { isTable: boolean; + isControl: boolean; index?: number; trIndex?: number; tdIndex?: number; diff --git a/src/editor/utils/element.ts b/src/editor/utils/element.ts index d03254b..08e8787 100644 --- a/src/editor/utils/element.ts +++ b/src/editor/utils/element.ts @@ -75,7 +75,7 @@ export function formatElementList(elementList: IElement[], isHandleFirstElement value, type: el.type, control: el.control, - controlComponent: ControlComponent.SUFFIX + controlComponent: ControlComponent.PREFIX }) i++ } From dc7b1c5cbf585c63bcee81d9e5c001476a9f375d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=BB=84=E4=BA=91=E9=A3=9E?= Date: Sat, 2 Apr 2022 17:40:58 +0800 Subject: [PATCH 2/2] fix:ts syntax error --- src/editor/interface/Position.ts | 2 +- src/editor/utils/index.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/editor/interface/Position.ts b/src/editor/interface/Position.ts index a4d9291..4e95072 100644 --- a/src/editor/interface/Position.ts +++ b/src/editor/interface/Position.ts @@ -28,7 +28,7 @@ export interface IGetPositionByXYPayload { export interface IPositionContext { isTable: boolean; - isControl: boolean; + isControl?: boolean; index?: number; trIndex?: number; tdIndex?: number; diff --git a/src/editor/utils/index.ts b/src/editor/utils/index.ts index 18578ae..f571403 100644 --- a/src/editor/utils/index.ts +++ b/src/editor/utils/index.ts @@ -19,7 +19,7 @@ export function deepClone(obj: T): T { if (Array.isArray(obj)) { newObj = obj.map(item => deepClone(item)) } else { - Object.keys(obj).forEach((key) => { + Object.keys(obj as any).forEach((key) => { // @ts-ignore return newObj[key] = deepClone(obj[key]) })