feat:add table context menus
@@ -223,7 +223,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.contextmenu-content .contextmenu-item {
|
.contextmenu-content .contextmenu-item {
|
||||||
width: 180px;
|
min-width: 140px;
|
||||||
padding: 0 32px 0 16px;
|
padding: 0 32px 0 16px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -248,6 +248,7 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
|
margin-left: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.contextmenu-content .contextmenu-item i {
|
.contextmenu-content .contextmenu-item i {
|
||||||
@@ -269,4 +270,40 @@
|
|||||||
|
|
||||||
.contextmenu-print {
|
.contextmenu-print {
|
||||||
background-image: url(../../assets/images/print.svg);
|
background-image: url(../../assets/images/print.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-insert-row-col {
|
||||||
|
background-image: url(../../assets/images/insert-row-col.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-insert-top-row {
|
||||||
|
background-image: url(../../assets/images/insert-top-row.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-insert-bottom-row {
|
||||||
|
background-image: url(../../assets/images/insert-bottom-row.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-insert-left-col {
|
||||||
|
background-image: url(../../assets/images/insert-left-col.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-insert-right-col {
|
||||||
|
background-image: url(../../assets/images/insert-right-col.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-delete-row-col {
|
||||||
|
background-image: url(../../assets/images/delete-row-col.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-delete-row {
|
||||||
|
background-image: url(../../assets/images/delete-row.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-delete-col {
|
||||||
|
background-image: url(../../assets/images/delete-col.svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextmenu-delete-table {
|
||||||
|
background-image: url(../../assets/images/delete-table.svg);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path stroke="#929AA8" d="M5.5 7.5v-6h4v6z"/><path fill="#3D4757" d="M13 15V3h1v12zM1 15V3h1v12zm4 0v-1h1v1zm1-1v-1h1v1zm1-1v-1h1v1zm-1-1v-1h1v1zm-1-1v-1h1v1zm3 1v-1h1v1zm0 2v-1h1v1zm1-3v-1h1v1zm0 4v-1h1v1z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 317 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path stroke="#929AA8" d="M8.5 6.5h6v2h-6z"/><path fill="#3D4757" d="M2 12h11v1H2zM2 2h11v1H2zm.63 3L7 9.35l-.635.65L2 5.63z"/><path fill="#3D4757" d="M2 9.363L6.355 5 7 5.707 2.695 10z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 296 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path stroke="#929AA8" d="M8.5 5.5h6v4h-6z"/><path fill="#3D4757" d="M1 13h12v1H1zM1 1h12v1H1zm0 4h1v1H1zm1 1h1v1H2zm1 1h1v1H3zm1-1h1v1H4zm1-1h1v1H5zM4 8h1v1H4zM2 8h1v1H2zm3 1h1v1H5zM1 9h1v1H1z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 304 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="#3D4757" fill-rule="evenodd"><path d="M14 13h-1v-3H2v3H1v-3a1 1 0 011-1h11a1 1 0 011 1v3z" fill-rule="nonzero"/><path d="M5.625 2L10 6.375 9.375 7 5 2.625z"/><path d="M5 6.375L9.375 2l.625.625L5.625 7z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 286 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#3D4757" d="M7 11h1V8H7zm.5 3L5 11h5z"/><rect stroke="#3D4757" x="1.5" y="2.5" width="12" height="3" rx="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 229 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#3D4757" d="M11 7v1h3V7zm-3 .5L11 5v5z"/><rect stroke="#3D4757" transform="rotate(90 4 7.5)" x="-2" y="6" width="12" height="3" rx="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 256 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#3D4757" d="M5 8V7H2v1zm3-.5L5 10V5z"/><rect stroke="#3D4757" transform="rotate(90 12 7.5)" x="6" y="6" width="12" height="3" rx="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 254 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path stroke="#3D4757" d="M8.5 5.5h6v4h-6z"/><path fill="#3D4757" d="M4 7v1h2V7zm-3 .5L4 5v5zM1 1h12v1H1zm0 12h12v1H1z"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 229 B |
@@ -0,0 +1 @@
|
|||||||
|
<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg"><g fill="none" fill-rule="evenodd"><path fill="#3D4757" d="M8 5H7v3h1zm-.5-3L10 5H5z"/><rect stroke="#3D4757" x="1.5" y="10.5" width="12" height="3" rx="1"/></g></svg>
|
||||||
|
After Width: | Height: | Size: 230 B |
@@ -26,6 +26,13 @@ export class Command {
|
|||||||
private static right: Function
|
private static right: Function
|
||||||
private static rowMargin: Function
|
private static rowMargin: Function
|
||||||
private static insertTable: Function
|
private static insertTable: Function
|
||||||
|
private static insertTableTopRow: Function
|
||||||
|
private static insertTableBottomRow: Function
|
||||||
|
private static insertTableLeftCol: Function
|
||||||
|
private static insertTableRightCol: Function
|
||||||
|
private static deleteTableRow: Function
|
||||||
|
private static deleteTableCol: Function
|
||||||
|
private static deleteTable: Function
|
||||||
private static image: Function
|
private static image: Function
|
||||||
private static search: Function
|
private static search: Function
|
||||||
private static print: Function
|
private static print: Function
|
||||||
@@ -56,6 +63,13 @@ export class Command {
|
|||||||
Command.right = adapt.rowFlex.bind(adapt)
|
Command.right = adapt.rowFlex.bind(adapt)
|
||||||
Command.rowMargin = adapt.rowMargin.bind(adapt)
|
Command.rowMargin = adapt.rowMargin.bind(adapt)
|
||||||
Command.insertTable = adapt.insertTable.bind(adapt)
|
Command.insertTable = adapt.insertTable.bind(adapt)
|
||||||
|
Command.insertTableTopRow = adapt.insertTableTopRow.bind(adapt)
|
||||||
|
Command.insertTableBottomRow = adapt.insertTableBottomRow.bind(adapt)
|
||||||
|
Command.insertTableLeftCol = adapt.insertTableLeftCol.bind(adapt)
|
||||||
|
Command.insertTableRightCol = adapt.insertTableRightCol.bind(adapt)
|
||||||
|
Command.deleteTableRow = adapt.deleteTableRow.bind(adapt)
|
||||||
|
Command.deleteTableCol = adapt.deleteTableCol.bind(adapt)
|
||||||
|
Command.deleteTable = adapt.deleteTable.bind(adapt)
|
||||||
Command.image = adapt.image.bind(adapt)
|
Command.image = adapt.image.bind(adapt)
|
||||||
Command.search = adapt.search.bind(adapt)
|
Command.search = adapt.search.bind(adapt)
|
||||||
Command.print = adapt.print.bind(adapt)
|
Command.print = adapt.print.bind(adapt)
|
||||||
@@ -156,6 +170,34 @@ export class Command {
|
|||||||
return Command.insertTable(row, col)
|
return Command.insertTable(row, col)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public executeInsertTableTopRow() {
|
||||||
|
return Command.insertTableTopRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executeInsertTableBottomRow() {
|
||||||
|
return Command.insertTableBottomRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executeInsertTableLeftCol() {
|
||||||
|
return Command.insertTableLeftCol()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executeInsertTableRightCol() {
|
||||||
|
return Command.insertTableRightCol()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executDeleteTableRow() {
|
||||||
|
return Command.deleteTableRow()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executDeleteTableCol() {
|
||||||
|
return Command.deleteTableCol()
|
||||||
|
}
|
||||||
|
|
||||||
|
public executDeleteTable() {
|
||||||
|
return Command.deleteTable()
|
||||||
|
}
|
||||||
|
|
||||||
public executeImage(payload: IDrawImagePayload) {
|
public executeImage(payload: IDrawImagePayload) {
|
||||||
return Command.image(payload)
|
return Command.image(payload)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { getUUID } from "../../utils"
|
|||||||
import { formatElementList } from "../../utils/element"
|
import { formatElementList } from "../../utils/element"
|
||||||
import { printImageBase64 } from "../../utils/print"
|
import { printImageBase64 } from "../../utils/print"
|
||||||
import { Draw } from "../draw/Draw"
|
import { Draw } from "../draw/Draw"
|
||||||
|
import { TableTool } from "../draw/particle/table/TableTool"
|
||||||
import { CanvasEvent } from "../event/CanvasEvent"
|
import { CanvasEvent } from "../event/CanvasEvent"
|
||||||
import { HistoryManager } from "../history/HistoryManager"
|
import { HistoryManager } from "../history/HistoryManager"
|
||||||
import { Position } from "../position/Position"
|
import { Position } from "../position/Position"
|
||||||
@@ -22,11 +23,14 @@ import { RangeManager } from "../range/RangeManager"
|
|||||||
|
|
||||||
export class CommandAdapt {
|
export class CommandAdapt {
|
||||||
|
|
||||||
|
private readonly defaultWidth: number = 40
|
||||||
|
|
||||||
private draw: Draw
|
private draw: Draw
|
||||||
private range: RangeManager
|
private range: RangeManager
|
||||||
private position: Position
|
private position: Position
|
||||||
private historyManager: HistoryManager
|
private historyManager: HistoryManager
|
||||||
private canvasEvent: CanvasEvent
|
private canvasEvent: CanvasEvent
|
||||||
|
private tableTool: TableTool
|
||||||
private options: Required<IEditorOption>
|
private options: Required<IEditorOption>
|
||||||
|
|
||||||
constructor(draw: Draw) {
|
constructor(draw: Draw) {
|
||||||
@@ -35,6 +39,7 @@ export class CommandAdapt {
|
|||||||
this.position = draw.getPosition()
|
this.position = draw.getPosition()
|
||||||
this.historyManager = draw.getHistoryManager()
|
this.historyManager = draw.getHistoryManager()
|
||||||
this.canvasEvent = draw.getCanvasEvent()
|
this.canvasEvent = draw.getCanvasEvent()
|
||||||
|
this.tableTool = draw.getTableTool()
|
||||||
this.options = draw.getOptions()
|
this.options = draw.getOptions()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,6 +296,364 @@ export class CommandAdapt {
|
|||||||
this.draw.render({ curIndex, isSetCursor: false })
|
this.draw.render({ curIndex, isSetCursor: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public insertTableTopRow() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, trIndex, tableId } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTr = curTrList[trIndex!]
|
||||||
|
// 之前跨行的增加跨行数
|
||||||
|
if (curTr.tdList.length < element.colgroup!.length) {
|
||||||
|
const curTrNo = curTr.tdList[0].rowIndex!
|
||||||
|
for (let t = 0; t < trIndex!; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
|
const td = tr.tdList[d]
|
||||||
|
if (td.rowspan > 1 && td.rowIndex! + td.rowspan >= curTrNo + 1) {
|
||||||
|
td.rowspan += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 增加当前行
|
||||||
|
const newTrId = getUUID()
|
||||||
|
const newTr: ITr = {
|
||||||
|
height: curTr.height,
|
||||||
|
id: newTrId,
|
||||||
|
tdList: []
|
||||||
|
}
|
||||||
|
for (let t = 0; t < curTr.tdList.length; t++) {
|
||||||
|
const curTd = curTr.tdList[t]
|
||||||
|
const newTdId = getUUID()
|
||||||
|
newTr.tdList.push({
|
||||||
|
id: newTdId,
|
||||||
|
rowspan: 1,
|
||||||
|
colspan: curTd.colspan,
|
||||||
|
value: [{
|
||||||
|
value: ZERO,
|
||||||
|
size: 16,
|
||||||
|
tableId,
|
||||||
|
trId: newTrId,
|
||||||
|
tdId: newTdId
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
curTrList.splice(trIndex!, 0, newTr)
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index,
|
||||||
|
trIndex,
|
||||||
|
tdIndex: 0,
|
||||||
|
tdId: newTr.tdList[0].id,
|
||||||
|
trId: newTr.id,
|
||||||
|
tableId
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ curIndex: 0 })
|
||||||
|
const position = this.position.getOriginalPositionList()
|
||||||
|
this.tableTool.render(element, position[index!])
|
||||||
|
}
|
||||||
|
|
||||||
|
public insertTableBottomRow() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, trIndex, tableId } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTr = curTrList[trIndex!]
|
||||||
|
const anchorTr = curTrList.length - 1 === trIndex
|
||||||
|
? curTr
|
||||||
|
: curTrList[trIndex! + 1]
|
||||||
|
// 之前/当前行跨行的增加跨行数
|
||||||
|
if (anchorTr.tdList.length < element.colgroup!.length) {
|
||||||
|
const curTrNo = anchorTr.tdList[0].rowIndex!
|
||||||
|
for (let t = 0; t < trIndex! + 1; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
|
const td = tr.tdList[d]
|
||||||
|
if (td.rowspan > 1 && td.rowIndex! + td.rowspan >= curTrNo + 1) {
|
||||||
|
td.rowspan += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 增加当前行
|
||||||
|
const newTrId = getUUID()
|
||||||
|
const newTr: ITr = {
|
||||||
|
height: anchorTr.height,
|
||||||
|
id: newTrId,
|
||||||
|
tdList: []
|
||||||
|
}
|
||||||
|
for (let t = 0; t < anchorTr.tdList.length; t++) {
|
||||||
|
const curTd = anchorTr.tdList[t]
|
||||||
|
const newTdId = getUUID()
|
||||||
|
newTr.tdList.push({
|
||||||
|
id: newTdId,
|
||||||
|
rowspan: 1,
|
||||||
|
colspan: curTd.colspan,
|
||||||
|
value: [{
|
||||||
|
value: ZERO,
|
||||||
|
size: 16,
|
||||||
|
tableId,
|
||||||
|
trId: newTrId,
|
||||||
|
tdId: newTdId
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
curTrList.splice(trIndex! + 1, 0, newTr)
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index,
|
||||||
|
trIndex: trIndex! + 1,
|
||||||
|
tdIndex: 0,
|
||||||
|
tdId: newTr.tdList[0].id,
|
||||||
|
trId: newTr.id,
|
||||||
|
tableId
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ curIndex: 0 })
|
||||||
|
const position = this.position.getOriginalPositionList()
|
||||||
|
this.tableTool.render(element, position[index!])
|
||||||
|
}
|
||||||
|
|
||||||
|
public insertTableLeftCol() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, tdIndex, tableId } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTdIndex = tdIndex!
|
||||||
|
// 增加列
|
||||||
|
for (let t = 0; t < curTrList.length; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
const tdId = getUUID()
|
||||||
|
tr.tdList.splice(curTdIndex, 0, {
|
||||||
|
id: tdId,
|
||||||
|
rowspan: 1,
|
||||||
|
colspan: 1,
|
||||||
|
value: [{
|
||||||
|
value: ZERO,
|
||||||
|
size: 16,
|
||||||
|
tableId,
|
||||||
|
trId: tr.id,
|
||||||
|
tdId
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 重新计算宽度
|
||||||
|
const colgroup = element.colgroup!
|
||||||
|
colgroup.splice(curTdIndex, 0, {
|
||||||
|
width: this.defaultWidth
|
||||||
|
})
|
||||||
|
const colgroupWidth = colgroup.reduce((pre, cur) => pre + cur.width, 0)
|
||||||
|
const width = this.draw.getOriginalInnerWidth()
|
||||||
|
if (colgroupWidth > width) {
|
||||||
|
const adjustWidth = (colgroupWidth - width) / colgroup.length
|
||||||
|
for (let g = 0; g < colgroup.length; g++) {
|
||||||
|
const group = colgroup[g]
|
||||||
|
group.width -= adjustWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index,
|
||||||
|
trIndex: 0,
|
||||||
|
tdIndex: curTdIndex,
|
||||||
|
tdId: curTrList[0].tdList[curTdIndex].id,
|
||||||
|
trId: curTrList[0].id,
|
||||||
|
tableId
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ curIndex: 0 })
|
||||||
|
const position = this.position.getOriginalPositionList()
|
||||||
|
this.tableTool.render(element, position[index!])
|
||||||
|
}
|
||||||
|
|
||||||
|
public insertTableRightCol() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, tdIndex, tableId } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTdIndex = tdIndex! + 1
|
||||||
|
// 增加列
|
||||||
|
for (let t = 0; t < curTrList.length; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
const tdId = getUUID()
|
||||||
|
tr.tdList.splice(curTdIndex, 0, {
|
||||||
|
id: tdId,
|
||||||
|
rowspan: 1,
|
||||||
|
colspan: 1,
|
||||||
|
value: [{
|
||||||
|
value: ZERO,
|
||||||
|
size: 16,
|
||||||
|
tableId,
|
||||||
|
trId: tr.id,
|
||||||
|
tdId
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 重新计算宽度
|
||||||
|
const colgroup = element.colgroup!
|
||||||
|
colgroup.splice(curTdIndex, 0, {
|
||||||
|
width: this.defaultWidth
|
||||||
|
})
|
||||||
|
const colgroupWidth = colgroup.reduce((pre, cur) => pre + cur.width, 0)
|
||||||
|
const width = this.draw.getOriginalInnerWidth()
|
||||||
|
if (colgroupWidth > width) {
|
||||||
|
const adjustWidth = (colgroupWidth - width) / colgroup.length
|
||||||
|
for (let g = 0; g < colgroup.length; g++) {
|
||||||
|
const group = colgroup[g]
|
||||||
|
group.width -= adjustWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index,
|
||||||
|
trIndex: 0,
|
||||||
|
tdIndex: curTdIndex,
|
||||||
|
tdId: curTrList[0].tdList[curTdIndex].id,
|
||||||
|
trId: curTrList[0].id,
|
||||||
|
tableId
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ curIndex: 0 })
|
||||||
|
const position = this.position.getOriginalPositionList()
|
||||||
|
this.tableTool.render(element, position[index!])
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteTableRow() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, trIndex } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTr = curTrList[trIndex!]
|
||||||
|
// 如果是最后一行,直接删除整个表格
|
||||||
|
if (curTrList.length <= 1) {
|
||||||
|
this.deleteTable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 补跨行
|
||||||
|
for (let d = 0; d < curTr.tdList.length; d++) {
|
||||||
|
const td = curTr.tdList[d]
|
||||||
|
if (td.rowspan > 1) {
|
||||||
|
let start = trIndex! + 1
|
||||||
|
while (start < trIndex! + td.rowspan) {
|
||||||
|
const tdId = getUUID()
|
||||||
|
const tr = curTrList[start]
|
||||||
|
tr.tdList.splice(d, 0, {
|
||||||
|
id: tdId,
|
||||||
|
rowspan: 1,
|
||||||
|
colspan: 1,
|
||||||
|
value: [{
|
||||||
|
value: ZERO,
|
||||||
|
size: 16,
|
||||||
|
tableId: element.id,
|
||||||
|
trId: tr.id,
|
||||||
|
tdId
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
start += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除当前行
|
||||||
|
curTrList.splice(trIndex!, 1)
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: false
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ isSetCursor: false })
|
||||||
|
this.tableTool.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteTableCol() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (!positionContext.isTable) return
|
||||||
|
const { index, tdIndex, trIndex } = positionContext
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
const element = originalElementList[index!]
|
||||||
|
const curTrList = element.trList!
|
||||||
|
const curTd = curTrList[trIndex!].tdList[tdIndex!]
|
||||||
|
const curColIndex = curTd.colIndex!
|
||||||
|
// 如果是最后一列,直接删除整个表格
|
||||||
|
const moreTdTr = curTrList.find(tr => tr.tdList.length > 1)
|
||||||
|
if (!moreTdTr) {
|
||||||
|
this.deleteTable()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 跨列处理
|
||||||
|
for (let t = 0; t < curTrList.length; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
|
const td = tr.tdList[d]
|
||||||
|
if (td.colspan > 1) {
|
||||||
|
const tdColIndex = td.colIndex!
|
||||||
|
// 交叉减去一列
|
||||||
|
if (tdColIndex <= curColIndex && tdColIndex + td.colspan - 1 >= curColIndex) {
|
||||||
|
td.colspan -= 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除当前列
|
||||||
|
for (let t = 0; t < curTrList.length; t++) {
|
||||||
|
const tr = curTrList[t]
|
||||||
|
let start = -1
|
||||||
|
for (let d = 0; d < tr.tdList.length; d++) {
|
||||||
|
const td = tr.tdList[d]
|
||||||
|
if (td.colIndex === curColIndex) {
|
||||||
|
start = d
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (~start) {
|
||||||
|
tr.tdList.splice(start, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
element.colgroup?.splice(curColIndex, 1)
|
||||||
|
// 重新设置上下文
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: false
|
||||||
|
})
|
||||||
|
this.range.setRange(0, 0)
|
||||||
|
// 重新渲染
|
||||||
|
this.draw.render({ isSetCursor: false })
|
||||||
|
this.tableTool.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
|
public deleteTable() {
|
||||||
|
const positionContext = this.position.getPositionContext()
|
||||||
|
if (positionContext.isTable) {
|
||||||
|
const originalElementList = this.draw.getOriginalElementList()
|
||||||
|
originalElementList.splice(positionContext.index!, 1)
|
||||||
|
const curIndex = positionContext.index! - 1
|
||||||
|
this.position.setPositionContext({
|
||||||
|
isTable: false,
|
||||||
|
index: curIndex
|
||||||
|
})
|
||||||
|
this.range.setRange(curIndex, curIndex)
|
||||||
|
this.draw.render({ curIndex })
|
||||||
|
this.tableTool.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public image(payload: IDrawImagePayload) {
|
public image(payload: IDrawImagePayload) {
|
||||||
const { startIndex, endIndex } = this.range.getRange()
|
const { startIndex, endIndex } = this.range.getRange()
|
||||||
if (startIndex === 0 && endIndex === 0) return
|
if (startIndex === 0 && endIndex === 0) return
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
import { IRegisterContextMenu } from "../../../interface/contextmenu/ContextMenu"
|
||||||
|
import { Command } from "../../command/Command"
|
||||||
|
|
||||||
|
export const tableMenus: IRegisterContextMenu[] = [
|
||||||
|
{
|
||||||
|
isDivider: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '插入行列',
|
||||||
|
icon: 'insert-row-col',
|
||||||
|
when: (payload) => {
|
||||||
|
return payload.isInTable
|
||||||
|
},
|
||||||
|
childMenus: [
|
||||||
|
{
|
||||||
|
name: '上方插入1行',
|
||||||
|
icon: 'insert-top-row',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeInsertTableTopRow()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: '下方插入1行',
|
||||||
|
icon: 'insert-bottom-row',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeInsertTableBottomRow()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: '左侧插入1列',
|
||||||
|
icon: 'insert-left-col',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeInsertTableLeftCol()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: '右侧插入1列',
|
||||||
|
icon: 'insert-right-col',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executeInsertTableRightCol()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '删除行列',
|
||||||
|
icon: 'delete-row-col',
|
||||||
|
when: (payload) => {
|
||||||
|
return payload.isInTable
|
||||||
|
},
|
||||||
|
childMenus: [
|
||||||
|
{
|
||||||
|
name: '删除1行',
|
||||||
|
icon: 'delete-row',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executDeleteTableRow()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '删除一列',
|
||||||
|
icon: 'delete-col',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executDeleteTableCol()
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: '删除整个表格',
|
||||||
|
icon: 'delete-table',
|
||||||
|
when: () => true,
|
||||||
|
callback: (command: Command) => {
|
||||||
|
command.executDeleteTable()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -123,6 +123,11 @@ export class Draw {
|
|||||||
return width - margins[1] - margins[3]
|
return width - margins[1] - margins[3]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getOriginalInnerWidth(): number {
|
||||||
|
const { width, margins } = this.options
|
||||||
|
return width - margins[1] - margins[3]
|
||||||
|
}
|
||||||
|
|
||||||
public getMargins(): number[] {
|
public getMargins(): number[] {
|
||||||
return this.options.margins.map(m => m * this.options.scale)
|
return this.options.margins.map(m => m * this.options.scale)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export class TableParticle {
|
|||||||
let colIndex = 0
|
let colIndex = 0
|
||||||
const preTd = tr.tdList[d - 1]
|
const preTd = tr.tdList[d - 1]
|
||||||
if (preTd) {
|
if (preTd) {
|
||||||
colIndex = preTd.colIndex! + (offsetXIndex || 1)
|
colIndex = preTd.colIndex! + offsetXIndex + 1
|
||||||
if (preTd.colspan > 1) {
|
if (preTd.colspan > 1) {
|
||||||
colIndex += preTd.colspan - 1
|
colIndex += preTd.colspan - 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { formatElementList } from './utils/element'
|
|||||||
import { Register } from './core/register/Register'
|
import { Register } from './core/register/Register'
|
||||||
import { globalMenus } from './core/contextmenu/menus/GlobalMenus'
|
import { globalMenus } from './core/contextmenu/menus/GlobalMenus'
|
||||||
import { ContextMenu } from './core/contextmenu/ContextMenu'
|
import { ContextMenu } from './core/contextmenu/ContextMenu'
|
||||||
|
import { tableMenus } from './core/contextmenu/menus/tableMenus'
|
||||||
import { IRegisterContextMenu } from './interface/contextmenu/ContextMenu'
|
import { IRegisterContextMenu } from './interface/contextmenu/ContextMenu'
|
||||||
|
|
||||||
export default class Editor {
|
export default class Editor {
|
||||||
@@ -64,6 +65,7 @@ export default class Editor {
|
|||||||
contextMenu
|
contextMenu
|
||||||
})
|
})
|
||||||
this.register.contextMenuList(globalMenus)
|
this.register.contextMenuList(globalMenus)
|
||||||
|
this.register.contextMenuList(tableMenus)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||