From 8fd209b4de878c718aae2844e87a0fab7cb2feb9 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Sun, 26 Apr 2009 18:05:42 +0000 Subject: [PATCH] Fixed incompatibility with R5 (and general PITA) - LineAt(TextLength()) returned one less than it should, causing unexpected moves of the caret, for instance when pressing HOME on the last (empty) line: * LineBuffer::OffsetToLine() and LineBuffer::PixelToLine() did not check for the last line in their binary search * removed a special case from TextView::PointAt() which now is no longer necessary (not sure if it was, before) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30435 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/TextView.cpp | 46 ++++++++----------- .../interface/textview_support/LineBuffer.cpp | 19 +++++--- 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 4dd2bfcaac..d1b86afbf1 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -1749,7 +1749,6 @@ BPoint BTextView::PointAt(int32 inOffset, float *outHeight) const { // TODO: Cleanup. - const int32 textLength = fText->Length(); int32 lineNum = LineAt(inOffset); STELine* line = (*fLines)[lineNum]; float height = 0; @@ -1758,10 +1757,9 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const result.x = 0.0; result.y = line->origin + fTextRect.top; - // Handle the case where there is only one line - // (no text inserted) + // Handle the case where we are on the last (always empty) line // TODO: See if we can do this better - if (fStyles->NumRuns() == 0) { + if (fStyles->NumRuns() == 0 || lineNum == fLines->NumLines()) { const rgb_color *color = NULL; const BFont *font = NULL; fStyles->GetNullStyle(&font, &color); @@ -1773,32 +1771,24 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const } else { height = (line + 1)->origin - line->origin; - // special case: go down one line if inOffset is a newline - if (inOffset == textLength && fText->RealCharAt(inOffset - 1) - == B_ENTER) { - result.y += height; - height = LineHeight(CountLines() - 1); + int32 offset = line->offset; + int32 length = inOffset - line->offset; + int32 numBytes = length; + bool foundTab = false; + do { + foundTab = fText->FindChar(B_TAB, offset, &numBytes); + float width = _StyledWidth(offset, numBytes); + result.x += width; - } else { - int32 offset = line->offset; - int32 length = inOffset - line->offset; - int32 numBytes = length; - bool foundTab = false; - do { - foundTab = fText->FindChar(B_TAB, offset, &numBytes); - float width = _StyledWidth(offset, numBytes); - result.x += width; + if (foundTab) { + result.x += _ActualTabWidth(result.x); + numBytes++; + } - if (foundTab) { - result.x += _ActualTabWidth(result.x); - numBytes++; - } - - offset += numBytes; - length -= numBytes; - numBytes = length; - } while (foundTab && length > 0); - } + offset += numBytes; + length -= numBytes; + numBytes = length; + } while (foundTab && length > 0); } if (fAlignment != B_ALIGN_LEFT) { diff --git a/src/kits/interface/textview_support/LineBuffer.cpp b/src/kits/interface/textview_support/LineBuffer.cpp index 4ff3af2edc..55676bb5c4 100644 --- a/src/kits/interface/textview_support/LineBuffer.cpp +++ b/src/kits/interface/textview_support/LineBuffer.cpp @@ -8,7 +8,6 @@ #include "LineBuffer.h" - BTextView::LineBuffer::LineBuffer() : _BTextViewSupportBuffer_(20, 2) { @@ -54,7 +53,7 @@ BTextView::LineBuffer::OffsetToLine(int32 offset) const int32 minIndex = 0; int32 maxIndex = fItemCount - 1; int32 index = 0; - + while (minIndex < maxIndex) { index = (minIndex + maxIndex) >> 1; if (offset >= fBuffer[index].offset) { @@ -65,7 +64,11 @@ BTextView::LineBuffer::OffsetToLine(int32 offset) const } else maxIndex = index; } - + + // do check for last line + if (minIndex == maxIndex && offset >= fBuffer[maxIndex].offset) + index = maxIndex; + return index; } @@ -76,7 +79,7 @@ BTextView::LineBuffer::PixelToLine(float pixel) const int32 minIndex = 0; int32 maxIndex = fItemCount - 1; int32 index = 0; - + while (minIndex < maxIndex) { index = (minIndex + maxIndex) >> 1; if (pixel >= fBuffer[index].origin) { @@ -87,14 +90,18 @@ BTextView::LineBuffer::PixelToLine(float pixel) const } else maxIndex = index; } - + + // do check for last line + if (minIndex == maxIndex && pixel >= fBuffer[maxIndex].origin) + index = maxIndex; + return index; } void BTextView::LineBuffer::BumpOrigin(float delta, long index) -{ +{ for (long i = index; i < fItemCount; i++) fBuffer[i].origin += delta; }