feat: move between table cells using left and right keys #465

pr675
Hufe921 2 years ago
parent 3796cabb37
commit 83f37edbca

@ -8,6 +8,8 @@ import { formatElementContext } from '../../../../utils/element'
import { isMod } from '../../../../utils/hotkey'
import { CanvasEvent } from '../../CanvasEvent'
import { enter } from './enter'
import { left } from './left'
import { right } from './right'
export function keydown(evt: KeyboardEvent, host: CanvasEvent) {
if (host.isComposing) return
@ -95,119 +97,9 @@ export function keydown(evt: KeyboardEvent, host: CanvasEvent) {
} else if (evt.key === KeyMap.Enter) {
enter(evt, host)
} else if (evt.key === KeyMap.Left) {
if (isReadonly) return
if (index > 0) {
const cursorPosition = position.getCursorPosition()
// 单词整体移动
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 (!~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()
}
left(evt, host)
} else if (evt.key === KeyMap.Right) {
if (isReadonly) return
if (index < positionList.length) {
const cursorPosition = position.getCursorPosition()
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
}
}
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()
}
right(evt, host)
} else if (evt.key === KeyMap.Up || evt.key === KeyMap.Down) {
if (isReadonly) return
let anchorPosition: IElementPosition = cursorPosition

@ -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…
Cancel
Save