feat:set control cursor
This commit is contained in:
@@ -34,6 +34,7 @@ import { SeparatorParticle } from './particle/Separator'
|
|||||||
import { PageBreakParticle } from './particle/PageBreak'
|
import { PageBreakParticle } from './particle/PageBreak'
|
||||||
import { Watermark } from './frame/Watermark'
|
import { Watermark } from './frame/Watermark'
|
||||||
import { EditorMode } from '../../dataset/enum/Editor'
|
import { EditorMode } from '../../dataset/enum/Editor'
|
||||||
|
import { Control } from './control/Control'
|
||||||
|
|
||||||
export class Draw {
|
export class Draw {
|
||||||
|
|
||||||
@@ -70,6 +71,7 @@ export class Draw {
|
|||||||
private pageBreakParticle: PageBreakParticle
|
private pageBreakParticle: PageBreakParticle
|
||||||
private superscriptParticle: SuperscriptParticle
|
private superscriptParticle: SuperscriptParticle
|
||||||
private subscriptParticle: SubscriptParticle
|
private subscriptParticle: SubscriptParticle
|
||||||
|
private control: Control
|
||||||
|
|
||||||
private rowList: IRow[]
|
private rowList: IRow[]
|
||||||
private painterStyle: IElementStyle | null
|
private painterStyle: IElementStyle | null
|
||||||
@@ -116,6 +118,7 @@ export class Draw {
|
|||||||
this.pageBreakParticle = new PageBreakParticle(this)
|
this.pageBreakParticle = new PageBreakParticle(this)
|
||||||
this.superscriptParticle = new SuperscriptParticle()
|
this.superscriptParticle = new SuperscriptParticle()
|
||||||
this.subscriptParticle = new SubscriptParticle()
|
this.subscriptParticle = new SubscriptParticle()
|
||||||
|
this.control = new Control(this)
|
||||||
|
|
||||||
new ScrollObserver(this)
|
new ScrollObserver(this)
|
||||||
new SelectionObserver()
|
new SelectionObserver()
|
||||||
@@ -301,6 +304,10 @@ export class Draw {
|
|||||||
return this.hyperlinkParticle
|
return this.hyperlinkParticle
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getControl(): Control {
|
||||||
|
return this.control
|
||||||
|
}
|
||||||
|
|
||||||
public getRowCount(): number {
|
public getRowCount(): number {
|
||||||
return this.rowList.length
|
return this.rowList.length
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
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--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -20,6 +20,7 @@ import { Listener } from '../listener/Listener'
|
|||||||
import { Position } from '../position/Position'
|
import { Position } from '../position/Position'
|
||||||
import { RangeManager } from '../range/RangeManager'
|
import { RangeManager } from '../range/RangeManager'
|
||||||
import { LETTER_REG, NUMBER_LIKE_REG } from '../../dataset/constant/Regular'
|
import { LETTER_REG, NUMBER_LIKE_REG } from '../../dataset/constant/Regular'
|
||||||
|
import { Control } from '../draw/control/Control'
|
||||||
|
|
||||||
export class CanvasEvent {
|
export class CanvasEvent {
|
||||||
|
|
||||||
@@ -38,6 +39,7 @@ export class CanvasEvent {
|
|||||||
private tableTool: TableTool
|
private tableTool: TableTool
|
||||||
private hyperlinkParticle: HyperlinkParticle
|
private hyperlinkParticle: HyperlinkParticle
|
||||||
private listener: Listener
|
private listener: Listener
|
||||||
|
private control: Control
|
||||||
|
|
||||||
constructor(draw: Draw) {
|
constructor(draw: Draw) {
|
||||||
this.isAllowDrag = false
|
this.isAllowDrag = false
|
||||||
@@ -55,6 +57,7 @@ export class CanvasEvent {
|
|||||||
this.tableTool = this.draw.getTableTool()
|
this.tableTool = this.draw.getTableTool()
|
||||||
this.hyperlinkParticle = this.draw.getHyperlinkParticle()
|
this.hyperlinkParticle = this.draw.getHyperlinkParticle()
|
||||||
this.listener = this.draw.getListener()
|
this.listener = this.draw.getListener()
|
||||||
|
this.control = this.draw.getControl()
|
||||||
}
|
}
|
||||||
|
|
||||||
public register() {
|
public register() {
|
||||||
@@ -163,9 +166,14 @@ export class CanvasEvent {
|
|||||||
x: evt.offsetX,
|
x: evt.offsetX,
|
||||||
y: evt.offsetY
|
y: evt.offsetY
|
||||||
})
|
})
|
||||||
|
// 如果是控件-光标需移动到合适位置
|
||||||
|
if (positionResult.isControl) {
|
||||||
|
this.control.moveCursorIndex(positionResult)
|
||||||
|
}
|
||||||
const {
|
const {
|
||||||
index,
|
index,
|
||||||
isDirectHit,
|
isDirectHit,
|
||||||
|
isControl,
|
||||||
isImage,
|
isImage,
|
||||||
isTable,
|
isTable,
|
||||||
trIndex,
|
trIndex,
|
||||||
@@ -178,6 +186,7 @@ export class CanvasEvent {
|
|||||||
// 设置位置上下文
|
// 设置位置上下文
|
||||||
this.position.setPositionContext({
|
this.position.setPositionContext({
|
||||||
isTable: isTable || false,
|
isTable: isTable || false,
|
||||||
|
isControl: isControl || false,
|
||||||
index,
|
index,
|
||||||
trIndex,
|
trIndex,
|
||||||
tdIndex,
|
tdIndex,
|
||||||
|
|||||||
@@ -18,7 +18,8 @@ export class Position {
|
|||||||
this.positionList = []
|
this.positionList = []
|
||||||
this.cursorPosition = null
|
this.cursorPosition = null
|
||||||
this.positionContext = {
|
this.positionContext = {
|
||||||
isTable: false
|
isTable: false,
|
||||||
|
isControl: false
|
||||||
}
|
}
|
||||||
|
|
||||||
this.draw = draw
|
this.draw = draw
|
||||||
@@ -92,14 +93,16 @@ export class Position {
|
|||||||
positionList: td.positionList
|
positionList: td.positionList
|
||||||
})
|
})
|
||||||
if (~tablePosition.index) {
|
if (~tablePosition.index) {
|
||||||
|
const { index: tdValueIndex } = tablePosition
|
||||||
return {
|
return {
|
||||||
index,
|
index,
|
||||||
|
isControl: td.value[tdValueIndex].type === ElementType.CONTROL,
|
||||||
isImage: tablePosition.isImage,
|
isImage: tablePosition.isImage,
|
||||||
isDirectHit: tablePosition.isDirectHit,
|
isDirectHit: tablePosition.isDirectHit,
|
||||||
isTable: true,
|
isTable: true,
|
||||||
tdIndex: d,
|
tdIndex: d,
|
||||||
trIndex: t,
|
trIndex: t,
|
||||||
tdValueIndex: tablePosition.index,
|
tdValueIndex,
|
||||||
tdId: td.id,
|
tdId: td.id,
|
||||||
trId: tr.id,
|
trId: tr.id,
|
||||||
tableId: element.id
|
tableId: element.id
|
||||||
@@ -110,7 +113,11 @@ export class Position {
|
|||||||
}
|
}
|
||||||
// 图片区域均为命中
|
// 图片区域均为命中
|
||||||
if (element.type === ElementType.IMAGE) {
|
if (element.type === ElementType.IMAGE) {
|
||||||
return { index: curPositionIndex, isDirectHit: true, isImage: true }
|
return {
|
||||||
|
index: curPositionIndex,
|
||||||
|
isDirectHit: true,
|
||||||
|
isImage: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// 判断是否在文字中间前后
|
// 判断是否在文字中间前后
|
||||||
if (elementList[index].value !== ZERO) {
|
if (elementList[index].value !== ZERO) {
|
||||||
@@ -119,7 +126,10 @@ export class Position {
|
|||||||
curPositionIndex = j - 1
|
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 tdWidth = td.width!
|
||||||
const tdHeight = td.height!
|
const tdHeight = td.height!
|
||||||
if (!(tdX < x && x < tdX + tdWidth && tdY < y && y < tdY + tdHeight)) {
|
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: firstLetterList[firstLetterList.length - 1]?.index || positionList.length - 1 }
|
||||||
}
|
}
|
||||||
return { index: curPositionIndex }
|
return {
|
||||||
|
index: curPositionIndex,
|
||||||
|
isControl: elementList[curPositionIndex].type === ElementType.CONTROL
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2,5 +2,7 @@ import { IControlOption } from '../../interface/Control'
|
|||||||
|
|
||||||
export const defaultControlOption: Readonly<Required<IControlOption>> = {
|
export const defaultControlOption: Readonly<Required<IControlOption>> = {
|
||||||
placeholderColor: '#9c9b9b',
|
placeholderColor: '#9c9b9b',
|
||||||
bracketColor: '#000000'
|
bracketColor: '#000000',
|
||||||
|
prefix: '{',
|
||||||
|
postfix: '}'
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ export enum ControlType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export enum ControlComponent {
|
export enum ControlComponent {
|
||||||
SUFFIX = 'suffix',
|
PREFIX = 'prefix',
|
||||||
POSTFIX = 'postfix',
|
POSTFIX = 'postfix',
|
||||||
PLACEHOLDER = 'placeholder',
|
PLACEHOLDER = 'placeholder',
|
||||||
VALUE = 'value'
|
VALUE = 'value'
|
||||||
|
|||||||
@@ -24,4 +24,6 @@ export type IControl = IControlBasic & Partial<IControlSelect>
|
|||||||
export interface IControlOption {
|
export interface IControlOption {
|
||||||
placeholderColor?: string;
|
placeholderColor?: string;
|
||||||
bracketColor?: string;
|
bracketColor?: string;
|
||||||
|
prefix?: string;
|
||||||
|
postfix?: string;
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@ import { ITd } from './table/Td'
|
|||||||
|
|
||||||
export interface ICurrentPosition {
|
export interface ICurrentPosition {
|
||||||
index: number;
|
index: number;
|
||||||
|
isControl?: boolean;
|
||||||
isImage?: boolean;
|
isImage?: boolean;
|
||||||
isTable?: boolean;
|
isTable?: boolean;
|
||||||
isDirectHit?: boolean;
|
isDirectHit?: boolean;
|
||||||
@@ -27,6 +28,7 @@ export interface IGetPositionByXYPayload {
|
|||||||
|
|
||||||
export interface IPositionContext {
|
export interface IPositionContext {
|
||||||
isTable: boolean;
|
isTable: boolean;
|
||||||
|
isControl?: boolean;
|
||||||
index?: number;
|
index?: number;
|
||||||
trIndex?: number;
|
trIndex?: number;
|
||||||
tdIndex?: number;
|
tdIndex?: number;
|
||||||
|
|||||||
@@ -75,9 +75,9 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
// 移除父节点
|
// 移除父节点
|
||||||
elementList.splice(i, 1)
|
elementList.splice(i, 1)
|
||||||
// 前后缀个性化设置
|
// 前后缀个性化设置
|
||||||
const thePreSuffixArgs: Pick<IElement, 'color'> = {}
|
const thePrePostfixArgs: Pick<IElement, 'color'> = {}
|
||||||
if (editorOptions && editorOptions.control) {
|
if (editorOptions && editorOptions.control) {
|
||||||
thePreSuffixArgs.color = editorOptions.control.bracketColor
|
thePrePostfixArgs.color = editorOptions.control.bracketColor
|
||||||
}
|
}
|
||||||
// 前缀
|
// 前缀
|
||||||
if (prefix) {
|
if (prefix) {
|
||||||
@@ -89,8 +89,8 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
value,
|
value,
|
||||||
type: el.type,
|
type: el.type,
|
||||||
control: el.control,
|
control: el.control,
|
||||||
controlComponent: ControlComponent.SUFFIX,
|
controlComponent: ControlComponent.PREFIX,
|
||||||
...thePreSuffixArgs
|
...thePrePostfixArgs
|
||||||
})
|
})
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ export function formatElementList(elementList: IElement[], options: IFormatEleme
|
|||||||
type: el.type,
|
type: el.type,
|
||||||
control: el.control,
|
control: el.control,
|
||||||
controlComponent: ControlComponent.POSTFIX,
|
controlComponent: ControlComponent.POSTFIX,
|
||||||
...thePreSuffixArgs
|
...thePrePostfixArgs
|
||||||
})
|
})
|
||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ export function deepClone<T>(obj: T): T {
|
|||||||
if (Array.isArray(obj)) {
|
if (Array.isArray(obj)) {
|
||||||
newObj = obj.map(item => deepClone(item))
|
newObj = obj.map(item => deepClone(item))
|
||||||
} else {
|
} else {
|
||||||
Object.keys(obj).forEach((key) => {
|
Object.keys(obj as any).forEach((key) => {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return newObj[key] = deepClone(obj[key])
|
return newObj[key] = deepClone(obj[key])
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user