fixed behaviour of non-editable textviews:

* non-editable textviews no longer draw the caret
* the cursor keys scroll immediately, not only when the (invisible) caret 
  reaches the views bounds
* HOME/END work more reliably
* any selection stays active throughout keyboard navigation
Tested with AboutSystem, Mail, StyledEdit and Beam - seems to work ok


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30756 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe
2009-05-13 22:09:15 +00:00
parent f945cef7cb
commit f287ca7dc8
2 changed files with 101 additions and 28 deletions
+4
View File
@@ -394,6 +394,10 @@ private:
float _NullStyleHeight() const; float _NullStyleHeight() const;
void _ScrollBy(float horizontalStep,
float verticalStep);
void _ScrollTo(float x, float y);
BPrivate::TextGapBuffer* fText; BPrivate::TextGapBuffer* fText;
LineBuffer* fLines; LineBuffer* fLines;
StyleBuffer* fStyles; StyleBuffer* fStyles;
+97 -28
View File
@@ -157,9 +157,12 @@ struct BTextView::LayoutData {
}; };
const static rgb_color kBlackColor = { 0, 0, 0, 255 }; static const rgb_color kBlackColor = { 0, 0, 0, 255 };
const static rgb_color kBlueInputColor = { 152, 203, 255, 255 }; static const rgb_color kBlueInputColor = { 152, 203, 255, 255 };
const static rgb_color kRedInputColor = { 255, 152, 152, 255 }; static const rgb_color kRedInputColor = { 255, 152, 152, 255 };
static const float kHorizontalScrollBarStep = 10.0;
static const float kVerticalScrollBarStep = 12.0;
static property_info sPropertyList[] = { static property_info sPropertyList[] = {
@@ -3243,7 +3246,9 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
int32 lastClickOffset = fClickOffset; int32 lastClickOffset = fClickOffset;
switch (inArrowKey) { switch (inArrowKey) {
case B_LEFT_ARROW: case B_LEFT_ARROW:
if (fSelStart != fSelEnd && !shiftDown) if (!fEditable)
_ScrollBy(-1 * kHorizontalScrollBarStep, 0);
else if (fSelStart != fSelEnd && !shiftDown)
fClickOffset = fSelStart; fClickOffset = fSelStart;
else { else {
fClickOffset fClickOffset
@@ -3267,7 +3272,9 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
break; break;
case B_RIGHT_ARROW: case B_RIGHT_ARROW:
if (fSelStart != fSelEnd && !shiftDown) if (!fEditable)
_ScrollBy(kHorizontalScrollBarStep, 0);
else if (fSelStart != fSelEnd && !shiftDown)
fClickOffset = fSelEnd; fClickOffset = fSelEnd;
else { else {
fClickOffset fClickOffset
@@ -3292,7 +3299,9 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
case B_UP_ARROW: case B_UP_ARROW:
{ {
if (fSelStart != fSelEnd && !shiftDown) if (!fEditable)
_ScrollBy(0, -1 * kVerticalScrollBarStep);
else if (fSelStart != fSelEnd && !shiftDown)
fClickOffset = fSelStart; fClickOffset = fSelStart;
else { else {
float height; float height;
@@ -3318,7 +3327,9 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
case B_DOWN_ARROW: case B_DOWN_ARROW:
{ {
if (fSelStart != fSelEnd && !shiftDown) if (!fEditable)
_ScrollBy(0, kVerticalScrollBarStep);
else if (fSelStart != fSelEnd && !shiftDown)
fClickOffset = fSelEnd; fClickOffset = fSelEnd;
else { else {
float height; float height;
@@ -3346,13 +3357,15 @@ BTextView::_HandleArrowKey(uint32 inArrowKey)
// invalidate the null style // invalidate the null style
fStyles->InvalidateNullStyle(); fStyles->InvalidateNullStyle();
if (shiftDown) if (fEditable) {
Select(selStart, selEnd); if (shiftDown)
else Select(selStart, selEnd);
Select(fClickOffset, fClickOffset); else
Select(fClickOffset, fClickOffset);
// scroll if needed // scroll if needed
ScrollToOffset(fClickOffset); ScrollToOffset(fClickOffset);
}
} }
@@ -3406,9 +3419,15 @@ BTextView::_HandlePageKey(uint32 inPageKey)
int32 lastClickOffset = fClickOffset; int32 lastClickOffset = fClickOffset;
switch (inPageKey) { switch (inPageKey) {
case B_HOME: case B_HOME:
if (ctrlDown) if (!fEditable) {
_ScrollTo(0, 0);
break;
}
if (ctrlDown) {
_ScrollTo(0, 0);
fClickOffset = 0; fClickOffset = 0;
else { } else {
// get the start of the last line if caret is on it // get the start of the last line if caret is on it
line = (*fLines)[_LineAt(lastClickOffset)]; line = (*fLines)[_LineAt(lastClickOffset)];
fClickOffset = line->offset; fClickOffset = line->offset;
@@ -3433,7 +3452,13 @@ BTextView::_HandlePageKey(uint32 inPageKey)
break; break;
case B_END: case B_END:
if (!fEditable) {
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset);
break;
}
if (ctrlDown) { if (ctrlDown) {
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset);
fClickOffset = fText->Length(); fClickOffset = fText->Length();
} else { } else {
// If we are on the last line, just go to the last // If we are on the last line, just go to the last
@@ -3479,7 +3504,10 @@ BTextView::_HandlePageKey(uint32 inPageKey)
currentPos.y -= Bounds().Height(); currentPos.y -= Bounds().Height();
fClickOffset = OffsetAt(LineAt(currentPos)); fClickOffset = OffsetAt(LineAt(currentPos));
ScrollBy(0, -1 * Bounds().Height()); _ScrollBy(0, -1 * Bounds().Height());
if (!fEditable)
break;
if (!shiftDown) if (!shiftDown)
selStart = selEnd = fClickOffset; selStart = selEnd = fClickOffset;
@@ -3506,7 +3534,10 @@ BTextView::_HandlePageKey(uint32 inPageKey)
currentPos.y += Bounds().Height(); currentPos.y += Bounds().Height();
fClickOffset = OffsetAt(LineAt(currentPos)); fClickOffset = OffsetAt(LineAt(currentPos));
ScrollBy(0, Bounds().Height()); _ScrollBy(0, Bounds().Height());
if (!fEditable)
break;
if (!shiftDown) if (!shiftDown)
selStart = selEnd = fClickOffset; selStart = selEnd = fClickOffset;
@@ -3528,12 +3559,14 @@ BTextView::_HandlePageKey(uint32 inPageKey)
} }
} }
if (shiftDown) if (fEditable) {
Select(selStart, selEnd); if (shiftDown)
else Select(selStart, selEnd);
Select(fClickOffset, fClickOffset); else
Select(fClickOffset, fClickOffset);
ScrollToOffset(fClickOffset); ScrollToOffset(fClickOffset);
}
} }
@@ -3580,7 +3613,8 @@ BTextView::_HandleAlphaKey(const char *bytes, int32 numBytes)
fClickOffset = fSelEnd; fClickOffset = fSelEnd;
ScrollToOffset(fClickOffset); if (fEditable)
ScrollToOffset(fClickOffset);
} }
@@ -4368,7 +4402,7 @@ BTextView::_DrawCaret(int32 offset)
inline void inline void
BTextView::_ShowCaret() BTextView::_ShowCaret()
{ {
if (!fCaretVisible) if (!fCaretVisible && fEditable)
_InvertCaret(); _InvertCaret();
} }
@@ -4719,8 +4753,8 @@ void
BTextView::_UpdateScrollbars() BTextView::_UpdateScrollbars()
{ {
BRect bounds(Bounds()); BRect bounds(Bounds());
BScrollBar *horizontalScrollBar = ScrollBar(B_HORIZONTAL); BScrollBar* horizontalScrollBar = ScrollBar(B_HORIZONTAL);
BScrollBar *verticalScrollBar = ScrollBar(B_VERTICAL); BScrollBar* verticalScrollBar = ScrollBar(B_VERTICAL);
// do we have a horizontal scroll bar? // do we have a horizontal scroll bar?
if (horizontalScrollBar != NULL) { if (horizontalScrollBar != NULL) {
@@ -4733,7 +4767,7 @@ BTextView::_UpdateScrollbars()
horizontalScrollBar->SetRange(0, (float)maxRange); horizontalScrollBar->SetRange(0, (float)maxRange);
horizontalScrollBar->SetProportion((float)viewWidth / (float)dataWidth); horizontalScrollBar->SetProportion((float)viewWidth / (float)dataWidth);
horizontalScrollBar->SetSteps(10, dataWidth / 10); horizontalScrollBar->SetSteps(kHorizontalScrollBarStep, dataWidth / 10);
} }
// how about a vertical scroll bar? // how about a vertical scroll bar?
@@ -4747,11 +4781,45 @@ BTextView::_UpdateScrollbars()
verticalScrollBar->SetRange(0, maxRange); verticalScrollBar->SetRange(0, maxRange);
verticalScrollBar->SetProportion((float)viewHeight / (float)dataHeight); verticalScrollBar->SetProportion((float)viewHeight / (float)dataHeight);
verticalScrollBar->SetSteps(12, viewHeight); verticalScrollBar->SetSteps(kVerticalScrollBarStep, viewHeight);
} }
} }
/*! \brief Scrolls by the given offsets
*/
void
BTextView::_ScrollBy(float horizontal, float vertical)
{
BRect bounds = Bounds();
_ScrollTo(bounds.left + horizontal, bounds.top + vertical);
}
/*! \brief Scrolls to the given position, making sure not to scroll out of
bounds
*/
void
BTextView::_ScrollTo(float x, float y)
{
BRect bounds = Bounds();
long viewWidth = bounds.IntegerWidth();
long viewHeight = bounds.IntegerHeight();
if (x > fTextRect.right - viewWidth)
x = fTextRect.right - viewWidth;
if (x < 0.0)
x = 0.0;
if (y > fTextRect.bottom + fLayoutData->bottomInset - viewHeight)
y = fTextRect.bottom + fLayoutData->bottomInset - viewHeight;
if (y < 0.0)
y = 0.0;
ScrollTo(x, y);
}
/*! \brief Autoresizes the view to fit the contained text. /*! \brief Autoresizes the view to fit the contained text.
*/ */
void void
@@ -5185,6 +5253,7 @@ BTextView::_HandleInputMethodChanged(BMessage *message)
fInline->SetSelectionOffset(selectionStart); fInline->SetSelectionOffset(selectionStart);
fInline->SetSelectionLength(selectionEnd - selectionStart); fInline->SetSelectionLength(selectionEnd - selectionStart);
printf("string=%s\n", string);
const int32 inlineOffset = fInline->Offset(); const int32 inlineOffset = fInline->Offset();
InsertText(string, stringLen, fSelStart, NULL); InsertText(string, stringLen, fSelStart, NULL);
fSelStart += stringLen; fSelStart += stringLen;