feat: move between table cells using left and right keys #465
parent
3796cabb37
commit
83f37edbca
@ -0,0 +1,140 @@
|
|||||||
|
import { ElementType } from '../../../../dataset/enum/Element'
|
||||||
|
import { isMod } from '../../../../utils/hotkey'
|
||||||
|
import { CanvasEvent } from '../../CanvasEvent'
|
||||||
|
|
||||||
|
export function left(evt: KeyboardEvent, host: CanvasEvent) {
|
||||||
|
const draw = host.getDraw()
|
||||||
|
const isReadonly = draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const position = draw.getPosition()
|
||||||
|
const cursorPosition = position.getCursorPosition()
|
||||||
|
if (!cursorPosition) return
|
||||||
|
const positionContext = position.getPositionContext()
|
||||||
|
const { index } = cursorPosition
|
||||||
|
if (index <= 0 && !positionContext.isTable) return
|
||||||
|
const rangeManager = draw.getRange()
|
||||||
|
const { startIndex, endIndex } = rangeManager.getRange()
|
||||||
|
const isCollapsed = rangeManager.getIsCollapsed()
|
||||||
|
const elementList = draw.getElementList()
|
||||||
|
// 单词整体移动
|
||||||
|
let moveCount = 1
|
||||||
|
if (isMod(evt)) {
|
||||||
|
const LETTER_REG = draw.getLetterReg()
|
||||||
|
// 起始位置
|
||||||
|
const moveStartIndex =
|
||||||
|
evt.shiftKey && !isCollapsed && startIndex === cursorPosition?.index
|
||||||
|
? endIndex
|
||||||
|
: startIndex
|
||||||
|
if (LETTER_REG.test(elementList[moveStartIndex]?.value)) {
|
||||||
|
let i = moveStartIndex - 1
|
||||||
|
while (i > 0) {
|
||||||
|
const element = elementList[i]
|
||||||
|
if (!LETTER_REG.test(element.value)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
moveCount++
|
||||||
|
i--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const curIndex = startIndex - moveCount
|
||||||
|
// shift则缩放选区
|
||||||
|
let anchorStartIndex = curIndex
|
||||||
|
let anchorEndIndex = curIndex
|
||||||
|
if (evt.shiftKey && cursorPosition) {
|
||||||
|
if (startIndex !== endIndex) {
|
||||||
|
if (startIndex === cursorPosition.index) {
|
||||||
|
// 减小选区
|
||||||
|
anchorStartIndex = startIndex
|
||||||
|
anchorEndIndex = endIndex - moveCount
|
||||||
|
} else {
|
||||||
|
anchorStartIndex = curIndex
|
||||||
|
anchorEndIndex = endIndex
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
anchorEndIndex = endIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 表格单元格间跳转
|
||||||
|
if (!evt.shiftKey) {
|
||||||
|
const element = elementList[startIndex]
|
||||||
|
// 之前是表格则进入最后一个单元格最后一个元素
|
||||||
|
if (element.type === ElementType.TABLE) {
|
||||||
|
const trList = element.trList!
|
||||||
|
const lastTrIndex = trList.length - 1
|
||||||
|
const lastTr = trList[lastTrIndex]
|
||||||
|
const lastTdIndex = lastTr.tdList.length - 1
|
||||||
|
const lastTd = lastTr.tdList[lastTdIndex]
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index: startIndex,
|
||||||
|
trIndex: lastTrIndex,
|
||||||
|
tdIndex: lastTdIndex,
|
||||||
|
tdId: lastTd.id,
|
||||||
|
trId: lastTr.id,
|
||||||
|
tableId: element.id
|
||||||
|
})
|
||||||
|
anchorStartIndex = lastTd.value.length - 1
|
||||||
|
anchorEndIndex = anchorStartIndex
|
||||||
|
draw.getTableTool().render()
|
||||||
|
} else if (element.tableId) {
|
||||||
|
// 在表格单元格内&在首位则往前移动单元格
|
||||||
|
if (startIndex === 0) {
|
||||||
|
const originalElementList = draw.getOriginalElementList()
|
||||||
|
const trList = originalElementList[positionContext.index!].trList!
|
||||||
|
for (let r = 0; r < trList.length; r++) {
|
||||||
|
const tr = trList[r]
|
||||||
|
if (tr.id !== element.trId) continue
|
||||||
|
const tdList = tr.tdList
|
||||||
|
for (let d = 0; d < tdList.length; d++) {
|
||||||
|
const td = tdList[d]
|
||||||
|
if (td.id !== element.tdId) continue
|
||||||
|
// 移动到表格前
|
||||||
|
if (r === 0 && d === 0) {
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: false
|
||||||
|
})
|
||||||
|
anchorStartIndex = positionContext.index! - 1
|
||||||
|
anchorEndIndex = anchorStartIndex
|
||||||
|
draw.getTableTool().dispose()
|
||||||
|
} else {
|
||||||
|
// 上一个单元格
|
||||||
|
let preTrIndex = r
|
||||||
|
let preTdIndex = d - 1
|
||||||
|
if (preTdIndex < 0) {
|
||||||
|
preTrIndex = r - 1
|
||||||
|
preTdIndex = trList[preTrIndex].tdList.length - 1
|
||||||
|
}
|
||||||
|
const preTr = trList[preTrIndex]
|
||||||
|
const preTd = preTr.tdList[preTdIndex]
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index: positionContext.index,
|
||||||
|
trIndex: preTrIndex,
|
||||||
|
tdIndex: preTdIndex,
|
||||||
|
tdId: preTr.id,
|
||||||
|
trId: preTd.id,
|
||||||
|
tableId: element.id
|
||||||
|
})
|
||||||
|
anchorStartIndex = preTd.value.length - 1
|
||||||
|
anchorEndIndex = anchorStartIndex
|
||||||
|
draw.getTableTool().render()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 执行跳转
|
||||||
|
if (!~anchorStartIndex || !~anchorEndIndex) return
|
||||||
|
rangeManager.setRange(anchorStartIndex, anchorEndIndex)
|
||||||
|
const isAnchorCollapsed = anchorStartIndex === anchorEndIndex
|
||||||
|
draw.render({
|
||||||
|
curIndex: isAnchorCollapsed ? anchorStartIndex : undefined,
|
||||||
|
isSetCursor: isAnchorCollapsed,
|
||||||
|
isSubmitHistory: false,
|
||||||
|
isCompute: false
|
||||||
|
})
|
||||||
|
evt.preventDefault()
|
||||||
|
}
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
import { ElementType } from '../../../../dataset/enum/Element'
|
||||||
|
import { isMod } from '../../../../utils/hotkey'
|
||||||
|
import { CanvasEvent } from '../../CanvasEvent'
|
||||||
|
|
||||||
|
export function right(evt: KeyboardEvent, host: CanvasEvent) {
|
||||||
|
const draw = host.getDraw()
|
||||||
|
const isReadonly = draw.isReadonly()
|
||||||
|
if (isReadonly) return
|
||||||
|
const position = draw.getPosition()
|
||||||
|
const cursorPosition = position.getCursorPosition()
|
||||||
|
if (!cursorPosition) return
|
||||||
|
const { index } = cursorPosition
|
||||||
|
const positionList = position.getPositionList()
|
||||||
|
const positionContext = position.getPositionContext()
|
||||||
|
if (index > positionList.length - 1 && !positionContext.isTable) return
|
||||||
|
const rangeManager = draw.getRange()
|
||||||
|
const { startIndex, endIndex } = rangeManager.getRange()
|
||||||
|
const isCollapsed = rangeManager.getIsCollapsed()
|
||||||
|
let elementList = draw.getElementList()
|
||||||
|
// 单词整体移动
|
||||||
|
let moveCount = 1
|
||||||
|
if (isMod(evt)) {
|
||||||
|
const LETTER_REG = draw.getLetterReg()
|
||||||
|
// 起始位置
|
||||||
|
const moveStartIndex =
|
||||||
|
evt.shiftKey && !isCollapsed && startIndex === cursorPosition?.index
|
||||||
|
? endIndex
|
||||||
|
: startIndex
|
||||||
|
if (LETTER_REG.test(elementList[moveStartIndex + 1]?.value)) {
|
||||||
|
let i = moveStartIndex + 2
|
||||||
|
while (i < elementList.length) {
|
||||||
|
const element = elementList[i]
|
||||||
|
if (!LETTER_REG.test(element.value)) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
moveCount++
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const curIndex = endIndex + moveCount
|
||||||
|
// shift则缩放选区
|
||||||
|
let anchorStartIndex = curIndex
|
||||||
|
let anchorEndIndex = curIndex
|
||||||
|
if (evt.shiftKey && cursorPosition) {
|
||||||
|
if (startIndex !== endIndex) {
|
||||||
|
if (startIndex === cursorPosition.index) {
|
||||||
|
// 增大选区
|
||||||
|
anchorStartIndex = startIndex
|
||||||
|
anchorEndIndex = curIndex
|
||||||
|
} else {
|
||||||
|
anchorStartIndex = startIndex + moveCount
|
||||||
|
anchorEndIndex = endIndex
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
anchorStartIndex = startIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 表格单元格间跳转
|
||||||
|
if (!evt.shiftKey) {
|
||||||
|
const element = elementList[endIndex]
|
||||||
|
const nextElement = elementList[endIndex + 1]
|
||||||
|
// 后一个元素是表格,则进入单元格第一个起始位置
|
||||||
|
if (nextElement?.type === ElementType.TABLE) {
|
||||||
|
const trList = nextElement.trList!
|
||||||
|
const nextTr = trList[0]
|
||||||
|
const nextTd = nextTr.tdList[0]
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index: endIndex + 1,
|
||||||
|
trIndex: 0,
|
||||||
|
tdIndex: 0,
|
||||||
|
tdId: nextTd.id,
|
||||||
|
trId: nextTr.id,
|
||||||
|
tableId: nextElement.id
|
||||||
|
})
|
||||||
|
anchorStartIndex = 0
|
||||||
|
anchorEndIndex = 0
|
||||||
|
draw.getTableTool().render()
|
||||||
|
} else if (element.tableId) {
|
||||||
|
// 在表格单元格内&单元格元素最后
|
||||||
|
if (!nextElement) {
|
||||||
|
const originalElementList = draw.getOriginalElementList()
|
||||||
|
const trList = originalElementList[positionContext.index!].trList!
|
||||||
|
for (let r = 0; r < trList.length; r++) {
|
||||||
|
const tr = trList[r]
|
||||||
|
if (tr.id !== element.trId) continue
|
||||||
|
const tdList = tr.tdList
|
||||||
|
for (let d = 0; d < tdList.length; d++) {
|
||||||
|
const td = tdList[d]
|
||||||
|
if (td.id !== element.tdId) continue
|
||||||
|
// 移动到表格后
|
||||||
|
if (r === trList.length - 1 && d === tdList.length - 1) {
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: false
|
||||||
|
})
|
||||||
|
anchorStartIndex = positionContext.index!
|
||||||
|
anchorEndIndex = anchorStartIndex
|
||||||
|
elementList = draw.getElementList()
|
||||||
|
draw.getTableTool().dispose()
|
||||||
|
} else {
|
||||||
|
// 下一个单元格
|
||||||
|
let nextTrIndex = r
|
||||||
|
let nextTdIndex = d + 1
|
||||||
|
if (nextTdIndex > tdList.length - 1) {
|
||||||
|
nextTrIndex = r + 1
|
||||||
|
nextTdIndex = 0
|
||||||
|
}
|
||||||
|
const preTr = trList[nextTrIndex]
|
||||||
|
const preTd = preTr.tdList[nextTdIndex]
|
||||||
|
position.setPositionContext({
|
||||||
|
isTable: true,
|
||||||
|
index: positionContext.index,
|
||||||
|
trIndex: nextTrIndex,
|
||||||
|
tdIndex: nextTdIndex,
|
||||||
|
tdId: preTr.id,
|
||||||
|
trId: preTd.id,
|
||||||
|
tableId: element.id
|
||||||
|
})
|
||||||
|
anchorStartIndex = 0
|
||||||
|
anchorEndIndex = anchorStartIndex
|
||||||
|
draw.getTableTool().render()
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 执行跳转
|
||||||
|
const maxElementListIndex = elementList.length - 1
|
||||||
|
if (
|
||||||
|
anchorStartIndex > maxElementListIndex ||
|
||||||
|
anchorEndIndex > maxElementListIndex
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rangeManager.setRange(anchorStartIndex, anchorEndIndex)
|
||||||
|
const isAnchorCollapsed = anchorStartIndex === anchorEndIndex
|
||||||
|
draw.render({
|
||||||
|
curIndex: isAnchorCollapsed ? anchorStartIndex : undefined,
|
||||||
|
isSetCursor: isAnchorCollapsed,
|
||||||
|
isSubmitHistory: false,
|
||||||
|
isCompute: false
|
||||||
|
})
|
||||||
|
evt.preventDefault()
|
||||||
|
}
|
||||||
Loading…
Reference in new issue