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