From 5f1cf3ab37aa22180eee45c02486b478dfbc6b99 Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Thu, 7 Dec 2023 20:37:47 +0800 Subject: [PATCH] feat: add control indentation option #345 --- docs/en/guide/schema.md | 1 + docs/guide/schema.md | 1 + src/editor/core/draw/Draw.ts | 34 ++++++++++++++++++++++++++-- src/editor/core/position/Position.ts | 28 +++++++++++++++++++---- src/editor/dataset/enum/Control.ts | 6 +++++ src/editor/index.ts | 9 ++++++-- src/editor/interface/Control.ts | 3 ++- src/editor/interface/Position.ts | 5 ++++ src/editor/utils/element.ts | 6 ++--- 9 files changed, 80 insertions(+), 13 deletions(-) diff --git a/docs/en/guide/schema.md b/docs/en/guide/schema.md index f4ea970..5e4295d 100644 --- a/docs/en/guide/schema.md +++ b/docs/en/guide/schema.md @@ -81,6 +81,7 @@ interface IElement { minWidth?: number; underline?: boolean; extension?: unknown; + indentation?: ControlIndentation; deletable?: boolean; disabled?: boolean; code: string | null; diff --git a/docs/guide/schema.md b/docs/guide/schema.md index 4b67722..177deab 100644 --- a/docs/guide/schema.md +++ b/docs/guide/schema.md @@ -81,6 +81,7 @@ interface IElement { minWidth?: number; underline?: boolean; extension?: unknown; + indentation?: ControlIndentation; deletable?: boolean; disabled?: boolean; code: string | null; diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index a00d215..a3616bc 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -64,7 +64,11 @@ import { Control } from './control/Control' import { zipElementList } from '../../utils/element' import { CheckboxParticle } from './particle/CheckboxParticle' import { DeepRequired, IPadding } from '../../interface/Common' -import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control' +import { + ControlComponent, + ControlIndentation, + ImageDisplay +} from '../../dataset/enum/Control' import { formatElementList } from '../../utils/element' import { WorkerManager } from '../worker/WorkerManager' import { Previewer } from './particle/previewer/Previewer' @@ -1083,7 +1087,10 @@ export class Draw { boundingBoxDescent: 0 } // 实际可用宽度 - const offsetX = element.listId ? listStyleMap.get(element.listId) || 0 : 0 + const offsetX = + curRow.offsetX || + (element.listId && listStyleMap.get(element.listId)) || + 0 const availableWidth = innerWidth - offsetX if ( element.type === ElementType.IMAGE || @@ -1440,6 +1447,29 @@ export class Draw { rowFlex: elementList[i + 1]?.rowFlex, isPageBreak: element.type === ElementType.PAGE_BREAK } + // 控件缩进 + if ( + rowElement.controlComponent !== ControlComponent.PREFIX && + rowElement.control?.indentation === ControlIndentation.VALUE_START + ) { + // 查找到非前缀的第一个元素位置 + const preStartIndex = curRow.elementList.findIndex( + el => + el.controlId === rowElement.controlId && + el.controlComponent !== ControlComponent.PREFIX + ) + if (~preStartIndex) { + const preRowPositionList = this.position.computeRowPosition({ + row: curRow, + innerWidth: this.getInnerWidth() + }) + const valueStartPosition = preRowPositionList[preStartIndex] + if (valueStartPosition) { + row.offsetX = valueStartPosition.coordinate.leftTop[0] + } + } + } + // 列表缩进 if (element.listId) { row.isList = true row.offsetX = listStyleMap.get(element.listId!) diff --git a/src/editor/core/position/Position.ts b/src/editor/core/position/Position.ts index f206862..ee55afe 100644 --- a/src/editor/core/position/Position.ts +++ b/src/editor/core/position/Position.ts @@ -3,7 +3,8 @@ import { ZERO } from '../../dataset/constant/Common' import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control' import { IComputePageRowPositionPayload, - IComputePageRowPositionResult + IComputePageRowPositionResult, + IComputeRowPositionPayload } from '../../interface/Position' import { IEditorOption } from '../../interface/Editor' import { IElement, IElementPosition } from '../../interface/Element' @@ -14,6 +15,7 @@ import { } from '../../interface/Position' import { Draw } from '../draw/Draw' import { EditorMode, EditorZone } from '../../dataset/enum/Editor' +import { deepClone } from '../../utils' export class Position { private cursorPosition: IElementPosition | null @@ -110,10 +112,8 @@ export class Position { } else if (curRow.rowFlex === RowFlex.RIGHT) { x += innerWidth - curRow.width } - // 列表向右移动-留出列表样式位置 - if (curRow.isList) { - x += curRow.offsetX || 0 - } + // 当前行X轴偏移量 + x += curRow.offsetX || 0 // 当前td所在位置 const tablePreX = x const tablePreY = y @@ -244,6 +244,24 @@ export class Position { } } + public computeRowPosition( + payload: IComputeRowPositionPayload + ): IElementPosition[] { + const { row, innerWidth } = payload + const positionList: IElementPosition[] = [] + this.computePageRowPosition({ + positionList, + innerWidth, + rowList: [deepClone(row)], + pageNo: 0, + startX: 0, + startY: 0, + startIndex: 0, + startRowIndex: 0 + }) + return positionList + } + public setCursorPosition(position: IElementPosition | null) { this.cursorPosition = position } diff --git a/src/editor/dataset/enum/Control.ts b/src/editor/dataset/enum/Control.ts index d2b90c4..895814e 100644 --- a/src/editor/dataset/enum/Control.ts +++ b/src/editor/dataset/enum/Control.ts @@ -16,3 +16,9 @@ export enum ImageDisplay { INLINE = 'inline', BLOCK = 'block' } + +// 控件内容缩进方式 +export enum ControlIndentation { + ROW_START = 'rowStart', // 从行起始位置缩进 + VALUE_START = 'valueStart' // 从值起始位置缩进 +} diff --git a/src/editor/index.ts b/src/editor/index.ts index 2e44eba..1d0a97e 100644 --- a/src/editor/index.ts +++ b/src/editor/index.ts @@ -27,7 +27,11 @@ import { IHeader } from './interface/Header' import { IWatermark } from './interface/Watermark' import { defaultHeaderOption } from './dataset/constant/Header' import { defaultWatermarkOption } from './dataset/constant/Watermark' -import { ControlType, ImageDisplay } from './dataset/enum/Control' +import { + ControlIndentation, + ControlType, + ImageDisplay +} from './dataset/enum/Control' import { defaultControlOption } from './dataset/constant/Control' import { IControlOption } from './interface/Control' import { ICheckboxOption } from './interface/Checkbox' @@ -279,7 +283,8 @@ export { TitleLevel, ListType, ListStyle, - WordBreak + WordBreak, + ControlIndentation } // 对外类型 diff --git a/src/editor/interface/Control.ts b/src/editor/interface/Control.ts index 27a0728..8540dfd 100644 --- a/src/editor/interface/Control.ts +++ b/src/editor/interface/Control.ts @@ -1,4 +1,4 @@ -import { ControlType } from '../dataset/enum/Control' +import { ControlType, ControlIndentation } from '../dataset/enum/Control' import { ICheckbox } from './Checkbox' import { IElement } from './Element' import { IRange } from './Range' @@ -36,6 +36,7 @@ export interface IControlBasic { minWidth?: number underline?: boolean extension?: unknown + indentation?: ControlIndentation } export type IControl = IControlBasic & diff --git a/src/editor/interface/Position.ts b/src/editor/interface/Position.ts index 8c0f2d3..06f2558 100644 --- a/src/editor/interface/Position.ts +++ b/src/editor/interface/Position.ts @@ -43,6 +43,11 @@ export interface IPositionContext { tableId?: string } +export interface IComputeRowPositionPayload { + row: IRow + innerWidth: number +} + export interface IComputePageRowPositionPayload { positionList: IElementPosition[] rowList: IRow[] diff --git a/src/editor/utils/element.ts b/src/editor/utils/element.ts index 612fc0e..ac37d01 100644 --- a/src/editor/utils/element.ts +++ b/src/editor/utils/element.ts @@ -264,7 +264,7 @@ export function formatElementList( elementList.splice(i, 0, { ...valueStyleList[valueStyleIndex], controlId, - value, + value: value === '\n' ? ZERO : value, letterSpacing: isLastLetter ? checkboxOption.gap : 0, control: el.control, controlComponent: ControlComponent.VALUE @@ -295,7 +295,7 @@ export function formatElementList( elementList.splice(i, 0, { ...element, controlId, - value, + value: value === '\n' ? ZERO : value, type: element.type || ElementType.TEXT, control: el.control, controlComponent: ControlComponent.VALUE @@ -315,7 +315,7 @@ export function formatElementList( const value = placeholderStrList[p] elementList.splice(i, 0, { controlId, - value, + value: value === '\n' ? ZERO : value, type: el.type, control: el.control, controlComponent: ControlComponent.PLACEHOLDER,