From 3f265c835b8f63bcc07b41596ab4dce886e99629 Mon Sep 17 00:00:00 2001 From: Hufe921 Date: Sat, 12 Oct 2024 21:34:55 +0800 Subject: [PATCH] feat: control element support set row flex #839 --- docs/en/guide/schema.md | 1 + docs/guide/schema.md | 1 + src/editor/core/draw/Draw.ts | 24 +++++----- src/editor/core/draw/control/Control.ts | 59 +++++++++++++++++++++++++ src/editor/interface/Control.ts | 10 +++++ 5 files changed, 81 insertions(+), 14 deletions(-) diff --git a/docs/en/guide/schema.md b/docs/en/guide/schema.md index a9cf54185..5ab202aef 100644 --- a/docs/en/guide/schema.md +++ b/docs/en/guide/schema.md @@ -101,6 +101,7 @@ interface IElement { border?: boolean; extension?: unknown; indentation?: ControlIndentation; + rowFlex?: RowFlex deletable?: boolean; disabled?: boolean; code: string | null; diff --git a/docs/guide/schema.md b/docs/guide/schema.md index 3a18f1617..5e76997fc 100644 --- a/docs/guide/schema.md +++ b/docs/guide/schema.md @@ -101,6 +101,7 @@ interface IElement { border?: boolean; extension?: unknown; indentation?: ControlIndentation; + rowFlex?: RowFlex deletable?: boolean; disabled?: boolean; code: string | null; diff --git a/src/editor/core/draw/Draw.ts b/src/editor/core/draw/Draw.ts index 44b314f6a..29598b370 100644 --- a/src/editor/core/draw/Draw.ts +++ b/src/editor/core/draw/Draw.ts @@ -1646,16 +1646,13 @@ export class Draw { controlRealWidth += metrics.width } if (rowElement.controlComponent === ControlComponent.POSTFIX) { - const extraWidth = rowElement.control.minWidth - controlRealWidth - // 消费超出实际最小宽度的长度 - if (extraWidth > 0) { - // 超出行宽时截断 - const rowRemainingWidth = - availableWidth - curRow.width - metrics.width - const left = Math.min(rowRemainingWidth, extraWidth) * scale - rowElement.left = left - curRow.width += left - } + // 设置最小宽度控件属性(字符偏移量) + this.control.setMinWidthControlInfo({ + row: curRow, + rowElement, + availableWidth, + controlRealWidth + }) controlRealWidth = 0 } } @@ -2142,10 +2139,9 @@ export class Draw { offsetY = this.subscriptParticle.getOffsetY(element) } // 占位符不参与颜色计算 - const color = - element.controlComponent === ControlComponent.PLACEHOLDER - ? undefined - : element.color + const color = element.control?.underline + ? this.options.underlineColor + : element.color this.underline.recordFillInfo( ctx, x - offsetX, diff --git a/src/editor/core/draw/control/Control.ts b/src/editor/core/draw/control/Control.ts index fe44dd0ec..3278f1f3b 100644 --- a/src/editor/core/draw/control/Control.ts +++ b/src/editor/core/draw/control/Control.ts @@ -17,6 +17,7 @@ import { IRepaintControlOption, ISetControlExtensionOption, ISetControlProperties, + ISetControlRowFlexOption, ISetControlValueOption } from '../../../interface/Control' import { IEditorData, IEditorOption } from '../../../interface/Editor' @@ -54,6 +55,8 @@ import { LIST_CONTEXT_ATTR, TITLE_CONTEXT_ATTR } from '../../../dataset/constant/Element' +import { IRowElement } from '../../../interface/Row' +import { RowFlex } from '../../../dataset/enum/Row' interface IMoveCursorResult { newIndex: number @@ -1228,4 +1231,60 @@ export class Control { direction }) } + + public setMinWidthControlInfo(option: ISetControlRowFlexOption) { + const { row, rowElement, controlRealWidth, availableWidth } = option + if (!rowElement.control?.minWidth) return + const { scale } = this.options + const controlMinWidth = rowElement.control.minWidth * scale + // 设置首字符偏移量:如果控件内设置对齐方式&&存在设置最小宽度 + let controlFirstElement: IRowElement | null = null + if ( + rowElement.control?.minWidth && + (rowElement.control?.rowFlex === RowFlex.CENTER || + rowElement.control?.rowFlex === RowFlex.RIGHT) + ) { + // 计算当前控件内容宽度是否超出最小宽度设置 + let controlContentWidth = rowElement.metrics.width + let controlElementIndex = row.elementList.length - 1 + while (controlElementIndex >= 0) { + const controlRowElement = row.elementList[controlElementIndex] + controlContentWidth += controlRowElement.metrics.width + // 找到首字符结束循环 + if ( + row.elementList[controlElementIndex - 1]?.controlComponent === + ControlComponent.PREFIX + ) { + controlFirstElement = controlRowElement + break + } + controlElementIndex-- + } + // 计算首字符偏移量 + if (controlFirstElement) { + if (controlContentWidth < controlMinWidth) { + if (rowElement.control.rowFlex === RowFlex.CENTER) { + controlFirstElement.left = + (controlMinWidth - controlContentWidth) / 2 + } else if (rowElement.control.rowFlex === RowFlex.RIGHT) { + // 最小宽度 - 实际宽度 - 后缀元素宽度 + controlFirstElement.left = + controlMinWidth - controlContentWidth - rowElement.metrics.width + } + } + } + } + // 设置后缀偏移量:消费小于实际最小宽度 + const extraWidth = controlMinWidth - controlRealWidth + if (extraWidth > 0) { + const controlFirstElementLeft = controlFirstElement?.left || 0 + // 超出行宽时截断 + const rowRemainingWidth = + availableWidth - row.width - rowElement.metrics.width + const left = Math.min(rowRemainingWidth, extraWidth) + // 后缀偏移量需减去首字符的偏移量,避免重复偏移 + rowElement.left = left - controlFirstElementLeft + row.width += left - controlFirstElementLeft + } + } } diff --git a/src/editor/interface/Control.ts b/src/editor/interface/Control.ts index a1e0c12ff..a00584968 100644 --- a/src/editor/interface/Control.ts +++ b/src/editor/interface/Control.ts @@ -2,10 +2,12 @@ import { LocationPosition } from '../dataset/enum/Common' import { ControlType, ControlIndentation } from '../dataset/enum/Control' import { EditorZone } from '../dataset/enum/Editor' import { MoveDirection } from '../dataset/enum/Observer' +import { RowFlex } from '../dataset/enum/Row' import { IDrawOption } from './Draw' import { IElement } from './Element' import { IPositionContext } from './Position' import { IRange } from './Range' +import { IRow, IRowElement } from './Row' export interface IValueSet { value: string @@ -62,6 +64,7 @@ export interface IControlBasic { border?: boolean extension?: unknown indentation?: ControlIndentation + rowFlex?: RowFlex } export interface IControlStyle { @@ -175,3 +178,10 @@ export interface IInitNextControlOption { export interface ILocationControlOption { position: LocationPosition } + +export interface ISetControlRowFlexOption { + row: IRow + rowElement: IRowElement + availableWidth: number + controlRealWidth: number +}