feat:table cell vertical align
This commit is contained in:
@@ -130,3 +130,19 @@
|
|||||||
.ce-contextmenu-merge-cancel-cell {
|
.ce-contextmenu-merge-cancel-cell {
|
||||||
background-image: url(../../../assets/images/merge-cancel-cell.svg);
|
background-image: url(../../../assets/images/merge-cancel-cell.svg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-vertical-align {
|
||||||
|
background-image: url(../../../assets/images/vertical-align.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-vertical-align-top {
|
||||||
|
background-image: url(../../../assets/images/vertical-align-top.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-vertical-align-middle {
|
||||||
|
background-image: url(../../../assets/images/vertical-align-middle.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ce-contextmenu-vertical-align-bottom {
|
||||||
|
background-image: url(../../../assets/images/vertical-align-bottom.svg);
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M7 9h1V3H7zm.5 3L5 9h5zM2 13h11v1H2z" fill="#3D4757" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 152 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg"><path d="M8 12H7v3h1zm-.5-3l2.5 3H5zM7 3h1V0H7zm.5 3L5 3h5zM2 7h11v1H2z" fill="#3D4757" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 198 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><path d="M8 8H7v6h1zm-.5-3L10 8H5zM2 3h11v1H2z" fill="#3D4757" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 153 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 13h12v1H2zm0-3h8v1H2zm0-3h12v1H2zm0-6h12v1H2zm0 3h8v1H2z" fill="#3d4757" fill-rule="evenodd"/></svg>
|
||||||
|
After Width: | Height: | Size: 195 B |
@@ -1,4 +1,4 @@
|
|||||||
import { IElement, ImageDisplay, INavigateInfo } from '../..'
|
import { IElement, ImageDisplay, INavigateInfo, VerticalAlign } from '../..'
|
||||||
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
import { EditorMode, PageMode, PaperDirection } from '../../dataset/enum/Editor'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
@@ -47,6 +47,7 @@ export class Command {
|
|||||||
private static deleteTable: CommandAdapt['deleteTable']
|
private static deleteTable: CommandAdapt['deleteTable']
|
||||||
private static mergeTableCell: CommandAdapt['mergeTableCell']
|
private static mergeTableCell: CommandAdapt['mergeTableCell']
|
||||||
private static cancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
private static cancelMergeTableCell: CommandAdapt['cancelMergeTableCell']
|
||||||
|
private static tableTdVerticalAlign: CommandAdapt['tableTdVerticalAlign']
|
||||||
private static image: CommandAdapt['image']
|
private static image: CommandAdapt['image']
|
||||||
private static hyperlink: CommandAdapt['hyperlink']
|
private static hyperlink: CommandAdapt['hyperlink']
|
||||||
private static deleteHyperlink: CommandAdapt['deleteHyperlink']
|
private static deleteHyperlink: CommandAdapt['deleteHyperlink']
|
||||||
@@ -120,6 +121,7 @@ export class Command {
|
|||||||
Command.deleteTable = adapt.deleteTable.bind(adapt)
|
Command.deleteTable = adapt.deleteTable.bind(adapt)
|
||||||
Command.mergeTableCell = adapt.mergeTableCell.bind(adapt)
|
Command.mergeTableCell = adapt.mergeTableCell.bind(adapt)
|
||||||
Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
Command.cancelMergeTableCell = adapt.cancelMergeTableCell.bind(adapt)
|
||||||
|
Command.tableTdVerticalAlign = adapt.tableTdVerticalAlign.bind(adapt)
|
||||||
Command.image = adapt.image.bind(adapt)
|
Command.image = adapt.image.bind(adapt)
|
||||||
Command.hyperlink = adapt.hyperlink.bind(adapt)
|
Command.hyperlink = adapt.hyperlink.bind(adapt)
|
||||||
Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt)
|
Command.deleteHyperlink = adapt.deleteHyperlink.bind(adapt)
|
||||||
@@ -311,6 +313,10 @@ export class Command {
|
|||||||
return Command.cancelMergeTableCell()
|
return Command.cancelMergeTableCell()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public executeTableTdVerticalAlign(payload: VerticalAlign) {
|
||||||
|
return Command.tableTdVerticalAlign(payload)
|
||||||
|
}
|
||||||
|
|
||||||
public executeHyperlink(payload: IElement) {
|
public executeHyperlink(payload: IElement) {
|
||||||
return Command.hyperlink(payload)
|
return Command.hyperlink(payload)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { EditorContext, EditorMode, PageMode, PaperDirection } from '../../datas
|
|||||||
import { ElementType } from '../../dataset/enum/Element'
|
import { ElementType } from '../../dataset/enum/Element'
|
||||||
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
import { ElementStyleKey } from '../../dataset/enum/ElementStyle'
|
||||||
import { RowFlex } from '../../dataset/enum/Row'
|
import { RowFlex } from '../../dataset/enum/Row'
|
||||||
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
import { IDrawImagePayload, IPainterOptions } from '../../interface/Draw'
|
||||||
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
import { IEditorOption, IEditorResult } from '../../interface/Editor'
|
||||||
import { IElement, IElementStyle } from '../../interface/Element'
|
import { IElement, IElementStyle } from '../../interface/Element'
|
||||||
@@ -997,6 +998,30 @@ export class CommandAdapt {
|
|||||||
this.tableTool.render(element, position[index!])
|
this.tableTool.render(element, position[index!])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public tableTdVerticalAlign(payload: VerticalAlign) {
|
||||||
|
const isReadonly = this.draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, trIndex, tdIndex } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTd = element?.trList?.[trIndex!]?.tdList?.[tdIndex!]
|
||||||
|
if (
|
||||||
|
!curTd
|
||||||
|
|| curTd.verticalAlign === payload
|
||||||
|
|| (!curTd.verticalAlign && payload === VerticalAlign.TOP)
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 重设垂直对齐方式
|
||||||
|
curTd.verticalAlign = payload
|
||||||
|
const { endIndex } = this.range.getRange()
|
||||||
|
this.draw.render({
|
||||||
|
curIndex: endIndex
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
public hyperlink(payload: IElement) {
|
public hyperlink(payload: IElement) {
|
||||||
const isReadonly = this.draw.isReadonly()
|
const isReadonly = this.draw.isReadonly()
|
||||||
if (isReadonly) return
|
if (isReadonly) return
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { VerticalAlign } from '../../../dataset/enum/VerticalAlign'
|
||||||
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
|
import { IRegisterContextMenu } from '../../../interface/contextmenu/ContextMenu'
|
||||||
import { Command } from '../../command/Command'
|
import { Command } from '../../command/Command'
|
||||||
|
|
||||||
@@ -5,6 +6,39 @@ export const tableMenus: IRegisterContextMenu[] = [
|
|||||||
{
|
{
|
||||||
isDivider: true
|
isDivider: true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.verticalAlign',
|
||||||
|
icon: 'vertical-align',
|
||||||
|
when: (payload) => {
|
||||||
|
return !payload.isReadonly && payload.isInTable
|
||||||
|
},
|
||||||
|
childMenus: [
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.verticalAlignTop',
|
||||||
|
icon: 'vertical-align-top',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableTdVerticalAlign(VerticalAlign.TOP)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.verticalAlignMiddle',
|
||||||
|
icon: 'vertical-align-middle',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableTdVerticalAlign(VerticalAlign.MIDDLE)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
i18nPath: 'contextmenu.table.verticalAlignBottom',
|
||||||
|
icon: 'vertical-align-bottom',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeTableTdVerticalAlign(VerticalAlign.BOTTOM)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
i18nPath: 'contextmenu.table.insertRowCol',
|
i18nPath: 'contextmenu.table.insertRowCol',
|
||||||
icon: 'insert-row-col',
|
icon: 'insert-row-col',
|
||||||
|
|||||||
@@ -35,7 +35,11 @@
|
|||||||
"deleteCol": "Delete 1 col",
|
"deleteCol": "Delete 1 col",
|
||||||
"deleteTable": "Delete table",
|
"deleteTable": "Delete table",
|
||||||
"mergeCell": "Merge cell",
|
"mergeCell": "Merge cell",
|
||||||
"mergeCancelCell": "Cancel merge cell"
|
"mergeCancelCell": "Cancel merge cell",
|
||||||
|
"verticalAlign": "Vertical align",
|
||||||
|
"verticalAlignTop": "top",
|
||||||
|
"verticalAlignMiddle": "middle",
|
||||||
|
"verticalAlignBottom": "bottom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -35,7 +35,11 @@
|
|||||||
"deleteCol": "删除1列",
|
"deleteCol": "删除1列",
|
||||||
"deleteTable": "删除整个表格",
|
"deleteTable": "删除整个表格",
|
||||||
"mergeCell": "合并单元格",
|
"mergeCell": "合并单元格",
|
||||||
"mergeCancelCell": "取消合并"
|
"mergeCancelCell": "取消合并",
|
||||||
|
"verticalAlign": "垂直对齐",
|
||||||
|
"verticalAlignTop": "顶端对齐",
|
||||||
|
"verticalAlignMiddle": "垂直居中",
|
||||||
|
"verticalAlignBottom": "底端对齐"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datePicker": {
|
"datePicker": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { ElementType, RowFlex } from '../..'
|
import { ElementType, RowFlex, VerticalAlign } from '../..'
|
||||||
import { ZERO } from '../../dataset/constant/Common'
|
import { ZERO } from '../../dataset/constant/Common'
|
||||||
import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control'
|
import { ControlComponent, ImageDisplay } from '../../dataset/enum/Control'
|
||||||
import { IComputePageRowPositionPayload, IComputePageRowPositionResult } from '../../interface/Position'
|
import { IComputePageRowPositionPayload, IComputePageRowPositionResult } from '../../interface/Position'
|
||||||
@@ -112,15 +112,34 @@ export class Position {
|
|||||||
for (let d = 0; d < tr.tdList!.length; d++) {
|
for (let d = 0; d < tr.tdList!.length; d++) {
|
||||||
const td = tr.tdList[d]
|
const td = tr.tdList[d]
|
||||||
td.positionList = []
|
td.positionList = []
|
||||||
|
const rowList = td.rowList!
|
||||||
const drawRowResult = this.computePageRowPosition({
|
const drawRowResult = this.computePageRowPosition({
|
||||||
positionList: td.positionList,
|
positionList: td.positionList,
|
||||||
rowList: td.rowList!,
|
rowList,
|
||||||
pageNo,
|
pageNo,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
startX: (td.x! + tdPadding) * scale + tablePreX,
|
startX: (td.x! + tdPadding) * scale + tablePreX,
|
||||||
startY: td.y! * scale + tablePreY,
|
startY: td.y! * scale + tablePreY,
|
||||||
innerWidth: (td.width! - tdGap) * scale
|
innerWidth: (td.width! - tdGap) * scale
|
||||||
})
|
})
|
||||||
|
// 垂直对齐方式
|
||||||
|
if (
|
||||||
|
td.verticalAlign === VerticalAlign.MIDDLE
|
||||||
|
|| td.verticalAlign == VerticalAlign.BOTTOM
|
||||||
|
) {
|
||||||
|
const rowsHeight = rowList.reduce((pre, cur) => pre + cur.height, 0)
|
||||||
|
const blankHeight = td.height! - tdGap - rowsHeight
|
||||||
|
const offsetHeight = td.verticalAlign === VerticalAlign.MIDDLE ? blankHeight / 2 : blankHeight
|
||||||
|
if (Math.floor(offsetHeight) > 0) {
|
||||||
|
td.positionList.forEach(tdPosition => {
|
||||||
|
const { coordinate: { leftTop, leftBottom, rightBottom, rightTop } } = tdPosition
|
||||||
|
leftTop[1] += offsetHeight
|
||||||
|
leftBottom[1] += offsetHeight
|
||||||
|
rightBottom[1] += offsetHeight
|
||||||
|
rightTop[1] += offsetHeight
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
x = drawRowResult.x
|
x = drawRowResult.x
|
||||||
y = drawRowResult.y
|
y = drawRowResult.y
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
export enum VerticalAlign {
|
||||||
|
TOP = 'top',
|
||||||
|
MIDDLE = 'middle',
|
||||||
|
BOTTOM = 'bottom'
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ import { ICursorOption } from './interface/Cursor'
|
|||||||
import { defaultCursorOption } from './dataset/constant/Cursor'
|
import { defaultCursorOption } from './dataset/constant/Cursor'
|
||||||
import { IPageNumber } from './interface/PageNumber'
|
import { IPageNumber } from './interface/PageNumber'
|
||||||
import { defaultPageNumberOption } from './dataset/constant/PageNumber'
|
import { defaultPageNumberOption } from './dataset/constant/PageNumber'
|
||||||
|
import { VerticalAlign } from './dataset/enum/VerticalAlign'
|
||||||
|
|
||||||
export default class Editor {
|
export default class Editor {
|
||||||
|
|
||||||
@@ -161,6 +162,7 @@ export default class Editor {
|
|||||||
export {
|
export {
|
||||||
Editor,
|
Editor,
|
||||||
RowFlex,
|
RowFlex,
|
||||||
|
VerticalAlign,
|
||||||
EditorZone,
|
EditorZone,
|
||||||
EditorMode,
|
EditorMode,
|
||||||
ElementType,
|
ElementType,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { VerticalAlign } from '../../dataset/enum/VerticalAlign'
|
||||||
import { IElement, IElementPosition } from '../Element'
|
import { IElement, IElementPosition } from '../Element'
|
||||||
import { IRow } from '../Row'
|
import { IRow } from '../Row'
|
||||||
|
|
||||||
@@ -17,4 +18,5 @@ export interface ITd {
|
|||||||
colIndex?: number;
|
colIndex?: number;
|
||||||
rowList?: IRow[];
|
rowList?: IRow[];
|
||||||
positionList?: IElementPosition[];
|
positionList?: IElementPosition[];
|
||||||
|
verticalAlign?: VerticalAlign;
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@ import { ZERO } from '../dataset/constant/Common'
|
|||||||
import { defaultControlOption } from '../dataset/constant/Control'
|
import { defaultControlOption } from '../dataset/constant/Control'
|
||||||
import { EDITOR_ELEMENT_ZIP_ATTR } from '../dataset/constant/Element'
|
import { EDITOR_ELEMENT_ZIP_ATTR } from '../dataset/constant/Element'
|
||||||
import { ControlComponent, ControlType } from '../dataset/enum/Control'
|
import { ControlComponent, ControlType } from '../dataset/enum/Control'
|
||||||
|
import { ITd } from '../interface/table/Td'
|
||||||
|
|
||||||
interface IFormatElementListOption {
|
interface IFormatElementListOption {
|
||||||
isHandleFirstElement?: boolean;
|
isHandleFirstElement?: boolean;
|
||||||
@@ -308,11 +309,15 @@ export function zipElementList(payload: IElement[]): IElement[] {
|
|||||||
delete tr.id
|
delete tr.id
|
||||||
for (let d = 0; d < tr.tdList.length; d++) {
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
const td = tr.tdList[d]
|
const td = tr.tdList[d]
|
||||||
tr.tdList[d] = {
|
const zipTd: ITd = {
|
||||||
colspan: td.colspan,
|
colspan: td.colspan,
|
||||||
rowspan: td.rowspan,
|
rowspan: td.rowspan,
|
||||||
value: zipElementList(td.value)
|
value: zipElementList(td.value)
|
||||||
}
|
}
|
||||||
|
if (td.verticalAlign) {
|
||||||
|
zipTd.verticalAlign = td.verticalAlign
|
||||||
|
}
|
||||||
|
tr.tdList[d] = zipTd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user