BTextView uses cmd instead of ctrl for navigation

* Adjust BTextView to use B_COMMAND_KEY instead of B_CONTROL_KEY
  for wordwise navigation and jumping to the top and bottom.
  This requires a shortcut, which is only installed if there is
  none already (for the groups B_LEFT_ARROW/B_RIGHT_ARROW and
  B_HOME/B_END). As a result, wordwise navigation no longer works
  in Mail, for instance.
This commit is contained in:
Oliver Tappe 2012-11-04 17:34:26 +01:00 committed by Alexander von Gluck IV
parent f8e4b43426
commit 5a0a951419
2 changed files with 70 additions and 11 deletions

View File

@ -294,9 +294,11 @@ private:
void _ResetTextRect();
void _HandleBackspace();
void _HandleArrowKey(uint32 inArrowKey);
void _HandleArrowKey(uint32 inArrowKey,
bool commandKeyDown = false);
void _HandleDelete();
void _HandlePageKey(uint32 inPageKey);
void _HandlePageKey(uint32 inPageKey,
bool commandKeyDown = false);
void _HandleAlphaKey(const char* bytes,
int32 numBytes);
@ -451,8 +453,10 @@ private:
float fMinTextRectWidth;
LayoutData* fLayoutData;
int32 fLastClickOffset;
bool fInstalledNavigateWordwiseShortcuts;
bool fInstalledNavigateToTopOrBottomShortcuts;
uint32 _reserved[7];
uint32 _reserved[6];
};
#endif // _TEXTVIEW_H

View File

@ -194,6 +194,14 @@ static const float kHorizontalScrollBarStep = 10.0;
static const float kVerticalScrollBarStep = 12.0;
enum {
NAVIGATE_TO_PREVIOUS_WORD = '_NVP',
NAVIGATE_TO_NEXT_WORD = '_NVN',
NAVIGATE_TO_TOP = '_NVT',
NAVIGATE_TO_BOTTOM = '_NVB',
};
static property_info sPropertyList[] = {
{
"selection",
@ -1032,6 +1040,20 @@ BTextView::MessageReceived(BMessage *message)
_TrackDrag(fWhere);
break;
case NAVIGATE_TO_PREVIOUS_WORD:
_HandleArrowKey(B_LEFT_ARROW, true);
break;
case NAVIGATE_TO_NEXT_WORD:
_HandleArrowKey(B_RIGHT_ARROW, true);
break;
case NAVIGATE_TO_TOP:
_HandlePageKey(B_HOME, true);
break;
case NAVIGATE_TO_BOTTOM:
_HandlePageKey(B_END, true);
break;
default:
BView::MessageReceived(message);
break;
@ -3216,6 +3238,9 @@ BTextView::_InitObject(BRect textRect, const BFont *initialFont,
fLines = new LineBuffer;
fStyles = new StyleBuffer(&font, initialColor);
fInstalledNavigateWordwiseShortcuts = false;
fInstalledNavigateToTopOrBottomShortcuts = false;
// We put these here instead of in the constructor initializer list
// to have less code duplication, and a single place where to do changes
// if needed.
@ -3298,7 +3323,7 @@ BTextView::_HandleBackspace()
\param inArrowKey The code for the pressed key.
*/
void
BTextView::_HandleArrowKey(uint32 inArrowKey)
BTextView::_HandleArrowKey(uint32 inArrowKey, bool commandKeyDown)
{
// return if there's nowhere to go
if (fText->Length() == 0)
@ -3313,7 +3338,6 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
message->FindInt32("modifiers", &modifiers);
bool shiftDown = modifiers & B_SHIFT_KEY;
bool ctrlDown = modifiers & B_CONTROL_KEY;
int32 lastClickOffset = fCaretOffset;
switch (inArrowKey) {
@ -3324,7 +3348,7 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
fCaretOffset = fSelStart;
else {
fCaretOffset
= ctrlDown
= commandKeyDown
? _PreviousWordStart(fCaretOffset - 1)
: _PreviousInitialByte(fCaretOffset);
if (shiftDown && fCaretOffset != lastClickOffset) {
@ -3350,7 +3374,7 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
fCaretOffset = fSelEnd;
else {
fCaretOffset
= ctrlDown
= commandKeyDown
? _NextWordEnd(fCaretOffset)
: _NextInitialByte(fCaretOffset);
if (shiftDown && fCaretOffset != lastClickOffset) {
@ -3475,7 +3499,7 @@ BTextView::_HandleDelete()
\param inPageKey The page key which has been pressed.
*/
void
BTextView::_HandlePageKey(uint32 inPageKey)
BTextView::_HandlePageKey(uint32 inPageKey, bool commandKeyDown)
{
int32 mods = 0;
BMessage *currentMessage = Window()->CurrentMessage();
@ -3483,7 +3507,6 @@ BTextView::_HandlePageKey(uint32 inPageKey)
currentMessage->FindInt32("modifiers", &mods);
bool shiftDown = mods & B_SHIFT_KEY;
bool ctrlDown = mods & B_CONTROL_KEY;
STELine* line = NULL;
int32 selStart = fSelStart;
int32 selEnd = fSelEnd;
@ -3496,7 +3519,7 @@ BTextView::_HandlePageKey(uint32 inPageKey)
break;
}
if (ctrlDown) {
if (commandKeyDown) {
_ScrollTo(0, 0);
fCaretOffset = 0;
} else {
@ -3529,7 +3552,7 @@ BTextView::_HandlePageKey(uint32 inPageKey)
break;
}
if (ctrlDown) {
if (commandKeyDown) {
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset);
fCaretOffset = fText->Length();
} else {
@ -5044,6 +5067,25 @@ BTextView::_Activate()
GetMouse(&where, &buttons, false);
if (Bounds().Contains(where))
_TrackMouse(where, NULL);
if (Window() != NULL) {
if (!Window()->HasShortcut(B_LEFT_ARROW, B_COMMAND_KEY)
&& !Window()->HasShortcut(B_RIGHT_ARROW, B_COMMAND_KEY)) {
Window()->AddShortcut(B_LEFT_ARROW, B_COMMAND_KEY,
new BMessage(NAVIGATE_TO_PREVIOUS_WORD), this);
Window()->AddShortcut(B_RIGHT_ARROW, B_COMMAND_KEY,
new BMessage(NAVIGATE_TO_NEXT_WORD), this);
fInstalledNavigateWordwiseShortcuts = true;
}
if (!Window()->HasShortcut(B_HOME, B_COMMAND_KEY)
&& !Window()->HasShortcut(B_END, B_COMMAND_KEY)) {
Window()->AddShortcut(B_HOME, B_COMMAND_KEY,
new BMessage(NAVIGATE_TO_TOP), this);
Window()->AddShortcut(B_END, B_COMMAND_KEY,
new BMessage(NAVIGATE_TO_BOTTOM), this);
fInstalledNavigateToTopOrBottomShortcuts = true;
}
}
}
@ -5062,6 +5104,19 @@ BTextView::_Deactivate()
Highlight(fSelStart, fSelEnd);
} else
_HideCaret();
if (Window() != NULL) {
if (fInstalledNavigateWordwiseShortcuts) {
Window()->RemoveShortcut(B_LEFT_ARROW, B_COMMAND_KEY);
Window()->RemoveShortcut(B_RIGHT_ARROW, B_COMMAND_KEY);
fInstalledNavigateWordwiseShortcuts = false;
}
if (fInstalledNavigateToTopOrBottomShortcuts) {
Window()->RemoveShortcut(B_HOME, B_COMMAND_KEY);
Window()->RemoveShortcut(B_END, B_COMMAND_KEY);
fInstalledNavigateToTopOrBottomShortcuts = false;
}
}
}