in projectional/src/main/java/jetbrains/jetpad/projectional/util/CellNavigationController.java [200:316]
private void handleKeyPress(Cell cell, KeyEvent event) {
Cell current = focusedCell().get();
Integer currentOffset = null;
if (event.is(Key.UP) || event.is(Key.DOWN) || event.is(Key.PAGE_UP) || event.is(Key.PAGE_DOWN)) {
currentOffset = myPrevXOffset.get();
if (currentOffset == null) {
currentOffset = selectedXOffset();
}
}
Rectangle visibleRect = focusedCell().get().getContainer().visibleRect();
Cell next = null;
boolean restoreOffset = false;
if (event.is(Key.RIGHT)) {
next = nextFocusable(current);
moveToHome(next);
} else if (event.is(KeyStrokeSpecs.NEXT_WORD)) {
next = nextFocusable(current);
if (next != null) {
moveToHome(next);
} else if (!current.get(PositionHandler.PROPERTY).isEnd()) {
next = current;
moveToEnd(next);
}
} else if (event.is(KeyStrokeSpecs.NEXT_EDITABLE)) {
next = next(current, EDITABLE);
if (next != null) {
moveToHome(next);
} else if (!current.get(PositionHandler.PROPERTY).isEnd()) {
next = current;
moveToEnd(next);
}
} else if (event.is(Key.LEFT)) {
next = prevFocusable(current);
moveToEnd(next);
} else if (event.is(KeyStrokeSpecs.PREV_WORD)) {
next = prevFocusable(current);
moveToHome(next);
} else if (event.is(KeyStrokeSpecs.PREV_EDITABLE)) {
next = prev(current, EDITABLE);
moveToHome(next);
} else if (event.is(Key.UP)) {
next = WITH_BOUNDS.upperFocusable(current, currentOffset);
restoreOffset = true;
} else if (event.is(Key.DOWN)) {
next = WITH_BOUNDS.lowerFocusable(current, currentOffset);
restoreOffset = true;
} else if (event.is(Key.PAGE_UP)) {
next = new PageUpDown(current, currentOffset, visibleRect.dimension.y) {
@Override
protected Cell next(Cell current, int offset) {
return WITH_BOUNDS.upperFocusable(current, offset);
}
}.execute();
restoreOffset = true;
} else if (event.is(Key.PAGE_DOWN)) {
next = new PageUpDown(current, currentOffset, visibleRect.dimension.y) {
@Override
protected Cell next(Cell current, int offset) {
return WITH_BOUNDS.lowerFocusable(current, offset);
}
}.execute();
restoreOffset = true;
} else if (event.is(KeyStrokeSpecs.HOME)) {
next = WITH_BOUNDS.homeElement(current);
moveToHome(next);
} else if (event.is(KeyStrokeSpecs.END)) {
next = WITH_BOUNDS.endElement(current);
moveToEnd(next);
} else if (event.is(KeyStrokeSpecs.FILE_HOME)) {
next = Composites.firstFocusable(cell, true);
moveToHome(next);
} else if (event.is(KeyStrokeSpecs.FILE_END)) {
next = Composites.lastFocusable(cell, true);
moveToEnd(next);
} else if (event.is(KeyStrokeSpecs.SELECT_UP)) {
Cell focusableParent = Composites.focusableParent(current);
if (focusableParent != null) {
mySelectionStack.push(current);
next = focusableParent;
myStackResetEnabled.set(false);
}
} else if (event.is(KeyStrokeSpecs.SELECT_DOWN)) {
if (mySelectionStack.isEmpty()) {
next = Composites.firstFocusable(current, false);
} else {
next = mySelectionStack.pop();
}
myStackResetEnabled.set(false);
} else if (event.is(KeyStrokeSpecs.MATCHING_CONSTRUCTS) && current.get(PAIR_CELL) != null) {
next = current.get(PAIR_CELL);
if (Composites.isBefore(next, current)) {
moveToHome(next);
} else {
moveToEnd(next);
}
restoreOffset = false;
}
if (next != null) {
focusedCell().set(next);
if (restoreOffset) {
moveCaretTo(next, currentOffset - next.getBounds().origin.x);
myPrevXOffset.set(currentOffset);
}
if (next instanceof TextCell) {
((TextCell) next).scrollToCaret();
} else {
scrollTo(next);
}
event.consume();
}
myStackResetEnabled.set(true);
}