📄 richbox.java
字号:
resetSelection(caretOffset, selectionEnd);
}
/**
* 光标左移1格,选中移动的位置
*/
private void doSelectionCaretLeft() {
int old = caretOffset;
doSimpleCaretLeft();
if(old == caretOffset)
return;
if(caretOffset == selectionStart)
resetSelection(caretOffset, caretOffset);
else if(caretOffset < selectionStart)
resetSelection(caretOffset, selectionEnd);
else
resetSelection(selectionStart, caretOffset);
}
/**
* 选择到行尾
*/
private void doSelectionColumnEnd() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
int lineLength = content.getLine(caretLine).length();
int lineEndOffset = lineOffset + lineLength;
if(hasSelection()) {
int startLine = content.getLineAtOffset(selectionStart);
int endLine = content.getLineAtOffset(selectionEnd);
if(startLine == endLine)
resetSelection((caretOffset == selectionEnd) ? selectionStart : selectionEnd, lineEndOffset);
else if(caretLine == startLine)
resetSelection(lineEndOffset, selectionEnd);
else
resetSelection(selectionStart, lineEndOffset);
} else
resetSelection(caretOffset, lineEndOffset);
caretOffset = lineEndOffset;
showCaret(caretLine);
}
/**
* 选择到行首
*/
private void doSelectionColumnStart() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
if(hasSelection()) {
int startLine = content.getLineAtOffset(selectionStart);
int endLine = content.getLineAtOffset(selectionEnd);
if(startLine == endLine)
resetSelection(lineOffset, (caretOffset == selectionStart) ? selectionEnd : selectionStart);
else if(caretLine == startLine)
resetSelection(lineOffset, selectionEnd);
else
resetSelection(selectionStart, lineOffset);
} else
resetSelection(lineOffset, caretOffset);
caretOffset = lineOffset;
showCaret(caretLine);
}
/**
* 下翻一页,不改变光标的X参考点
*/
private void doPageDown() {
int lineCount = content.getLineCount();
int oldColumnX = columnX;
int caretLine;
caretLine = content.getLineAtOffset(caretOffset);
if (caretLine < lineCount - 1) {
GC _gc = getGC();
int verticalMaximum = contentHelper.getHeightOfLines(_gc, 0, lineCount);
int pageSize = clientAreaHeight - topMargin - bottomMargin;
int scrollLines = Math.min(lineCount - caretLine - 1, getFullVisibleLineCount());
scrollLines = Math.max(1, scrollLines);
caretLine += scrollLines;
caretOffset = contentHelper.getOffsetAtX(_gc, caretLine, columnX);
if(pageSize > verticalMaximum)
showCaret();
else
setVerticalScrollOffset(contentHelper.getHeightOfLines(_gc, 0, caretLine), true);
releaseGC();
}
// 显示光标
showCaret(caretLine);
columnX = oldColumnX;
}
/**
* 上翻一页,保持光标X位置不变。上翻页将光标减掉view中的全部可见行数。
*/
private void doPageUp() {
int oldColumnX = columnX;
int caretLine = content.getLineAtOffset(caretOffset);
// 如果当前光标所在的行大于0,上翻一页
if (caretLine > 0) {
GC _gc = getGC();
int scrollLines = Math.max(1, Math.min(caretLine, getFullVisibleLineCount()));
caretLine -= scrollLines;
caretOffset = contentHelper.getOffsetAtX(_gc, caretLine, columnX);
setVerticalScrollOffset(contentHelper.getHeightOfLines(_gc, 0, caretLine), true);
releaseGC();
}
// 显示光标
showCaret(caretLine);
columnX = oldColumnX;
}
/**
* @return
* 返回窗口中完全可见行的行数
*/
private int getFullVisibleLineCount() {
GC _gc = getGC();
int fullVisibleBottomLine = getFullVisibleBottomLine(_gc);
int fullVisibleTopLine = topLine;
if(contentHelper.getHeightOfLines(_gc, 0, fullVisibleTopLine) - verticalScrollOffset < 0)
fullVisibleTopLine++;
releaseGC();
int lineCount = fullVisibleBottomLine - fullVisibleTopLine + 1;
if(lineCount < 0)
return 0;
else
return lineCount;
}
/**
* 光标置于最后
*/
private void doTextEnd() {
if(caretOffset < content.getCharCount()) {
caretOffset = content.getCharCount();
showCaret();
}
}
/**
* 光标置于最开头
*/
private void doTextStart() {
if(caretOffset != 0) {
caretOffset = 0;
showCaret();
}
}
/**
* 将光标置于行结尾
*/
private void doLineEnd() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
int lineLength = content.getLine(caretLine).length();
int lineEndOffset = lineOffset + lineLength;
if (caretOffset < lineEndOffset) {
caretOffset = lineEndOffset;
showCaret();
}
}
/**
* 将光标置于行开始
*/
private void doLineStart() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
if (caretOffset > lineOffset) {
caretOffset = lineOffset;
showCaret(caretLine);
}
}
/**
*如果存在被选择区,则把光标放置到被选择区结束,否则简单移动
* <p>
*
* @see #doSimpleCaretRigth
*/
private void doCaretRight() {
if (selectionEnd > selectionStart) {
int caretLine;
caretOffset = selectionEnd;
caretLine = content.getLineAtOffset(caretOffset);
showCaret(caretLine);
} else {
doSimpleCaretRigth();
}
}
/**
* 往后移动光标一格,如果光标在一行的末尾,则要置光标到下一行的开头,如果后面是个图片,
* 要注意移动两个位置
*/
private void doSimpleCaretRigth() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
int offsetInLine = caretOffset - lineOffset;
if (offsetInLine < content.getLine(caretLine).length()) {
if(content.isImageTag(caretOffset))
caretOffset++;
caretOffset++;
showCaret();
} else if (caretLine < content.getLineCount() - 1) {
caretLine++;
caretOffset = content.getLineStartOffset(caretLine);
showCaret(caretLine);
}
}
/**
* 如果存在被选择区,则把光标放置到被选择区开始,否则简单移动
* <p>
*
* @see #doSimpleCaretLeft
*/
private void doCaretLeft() {
if (selectionEnd > selectionStart) {
int caretLine;
caretOffset = selectionStart;
caretLine = content.getLineAtOffset(caretOffset);
showCaret(caretLine);
} else {
doSimpleCaretLeft();
}
}
/**
* 往前移动光标一格,如果光标在一行的开头,则要置光标到上一行的末尾,如果前面是个图片,
* 要注意移动两个位置
*/
private void doSimpleCaretLeft() {
int caretLine = content.getLineAtOffset(caretOffset);
int lineOffset = content.getLineStartOffset(caretLine);
int offsetInLine = caretOffset - lineOffset;
if (offsetInLine > 0) {
caretOffset--;
if(content.isImageTag(caretOffset - 1))
caretOffset--;
showCaret(caretLine);
} else if (caretLine > 0) {
caretLine--;
lineOffset = content.getLineStartOffset(caretLine);
int newCaretOffset = lineOffset + content.getLine(caretLine).length();
if(newCaretOffset == caretOffset)
caretOffset--;
else
caretOffset = newCaretOffset;
if(content.isImageTag(caretOffset - 1))
caretOffset--;
showCaret();
}
}
/**
* 删除一个用户自定义按键绑定
*
* @param key
* a key code defined in SWT.java or a character. Optionally ORd
* with a state mask. Preferred state masks are one or more of
* SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
* modifier platform differences. However, there may be cases
* where using the specific state masks (i.e., SWT.CTRL,
* SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
*/
public void removeUserKeyAction(int key) {
setUserKeyAction(key, null);
}
/**
* 添加一个用户自定义按键事件
*
* @param key
* @param action
*/
public void setUserKeyAction(int key, Runnable action) {
if(action == null)
setKeyBinding(key, SWT.NULL);
else
setKeyBinding(key, CUSTOM_ACTION);
int keyValue = key & SWT.KEY_MASK;
int modifierValue = key & SWT.MODIFIER_MASK;
char keyChar = (char)keyValue;
if (Character.isLetter(keyChar)) {
// 添加key的大写形式
char ch = Character.toUpperCase(keyChar);
int newKey = ch | modifierValue;
if (action == null)
userActionMap.remove(newKey);
else
userActionMap.put(newKey, action);
// 添加key的小写形式
ch = Character.toLowerCase(keyChar);
newKey = ch | modifierValue;
if (action == null)
userActionMap.remove(newKey);
else
userActionMap.put(newKey, action);
} else {
// 不是字符形式的按键则直接添加
if (action == null)
userActionMap.remove(key);
else
userActionMap.put(key, action);
}
}
/**
* 得到用户自定义动作对象
*
* @param key
* 按键值
* @return
* Runnable对象
*/
public Runnable getUserKeyAction(int key) {
return userActionMap.get(key);
}
/**
* 查找和相关按键绑定的动作id
* <p>
*
* @param key
* a key code defined in SWT.java or a character. Optionally ORd
* with a state mask. Preferred state masks are one or more of
* SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
* modifier platform differences. However, there may be cases
* where using the specific state masks (i.e., SWT.CTRL,
* SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
* @return
* 动作ID,SWT.NULL表示没有动作
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public int getKeyBinding(int key) {
checkWidget();
Integer action = keyActionMap.get(key);
if (action == null)
return SWT.NULL;
else
return action;
}
/**
* 添加一个按键绑定
* <p>
*
* @param key
* a key code defined in SWT.java or a character. Optionally ORd
* with a state mask. Preferred state masks are one or more of
* SWT.MOD1, SWT.MOD2, SWT.MOD3, since these masks account for
* modifier platform differences. However, there may be cases
* where using the specific state masks (i.e., SWT.CTRL,
* SWT.SHIFT, SWT.ALT, SWT.COMMAND) makes sense.
* @param action
* 动作ID
* @exception SWTException
* <ul>
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been
* disposed</li>
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the
* thread that created the receiver</li>
* </ul>
*/
public void setKeyBinding(int key, int action) {
checkWidget();
int keyValue = key & SWT.KEY_MASK;
int modifierValue = key & SWT.MODIFIER_MASK;
char keyChar = (char)keyValue;
if (Character.isLetter(keyChar)) {
// 添加key的大写形式
char ch = Character.toUpperCase(keyChar);
int newKey = ch | modifierValue;
if (action == SWT.NULL)
keyActionMap.remove(newKey);
else
keyActionMap.put(newKey, action);
// 添加key的小写形式
ch = Character.toLowerCase(keyChar);
newKey = ch | modifierValue;
if (action == SWT.NULL)
keyActionMap.remove(newKey);
else
keyActionMap.put(newKey, action);
} else {
// 不是字符形式的按键则直接添加
if (action == SWT.NULL)
keyActionMap.remove(key);
else
keyActionMap.put(key, action);
}
}
/**
* 删除一个按键绑定
*
* @param key
*/
public void removeKeyBinding(int key) {
setKeyBinding(key, SWT.NULL);
}
/**
* 添加缺省按键绑定
*/
private void createKeyBindings() {
// 导航按键绑定
setKeyBinding(SWT.HOME, LINE_START);
setKeyBinding(SWT.END, LINE_END);
setKeyBinding(SWT.PAGE_UP, PAGE_UP);
setKeyBinding(SWT.PAGE_DOWN, PAGE_DOWN);
setKeyBinding(SWT.HOME | SWT.MOD1, TEXT_START);
setKeyBinding(SWT.END | SWT.MOD1, TEXT_END);
setKeyBinding(SWT.PAGE_UP | SWT.MOD1, TEXT_START);
setKeyBinding(SWT.PAGE_DOWN | SWT.MOD1, TEXT_END);
setKeyBinding(SWT.ARROW_LEFT, COLUMN_LEFT);
setKeyBinding(SWT.ARROW_RIGHT, COLUMN_RIGHT);
setKeyBinding(SWT.ARROW_UP, LINE_UP);
setKeyBinding(SWT.ARROW_DOWN, LINE_DOWN);
// Selection
setKeyBinding(SWT.ARROW_UP | SWT.MOD2, SELECT_LINE_UP);
setKeyBinding(SWT.ARROW_DOWN | SWT.MOD2, SELECT_LINE_DOWN);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -