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
This commit is contained in:
@@ -1749,7 +1749,6 @@ BPoint
|
|||||||
BTextView::PointAt(int32 inOffset, float *outHeight) const
|
BTextView::PointAt(int32 inOffset, float *outHeight) const
|
||||||
{
|
{
|
||||||
// TODO: Cleanup.
|
// TODO: Cleanup.
|
||||||
const int32 textLength = fText->Length();
|
|
||||||
int32 lineNum = LineAt(inOffset);
|
int32 lineNum = LineAt(inOffset);
|
||||||
STELine* line = (*fLines)[lineNum];
|
STELine* line = (*fLines)[lineNum];
|
||||||
float height = 0;
|
float height = 0;
|
||||||
@@ -1758,10 +1757,9 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
result.x = 0.0;
|
result.x = 0.0;
|
||||||
result.y = line->origin + fTextRect.top;
|
result.y = line->origin + fTextRect.top;
|
||||||
|
|
||||||
// Handle the case where there is only one line
|
// Handle the case where we are on the last (always empty) line
|
||||||
// (no text inserted)
|
|
||||||
// TODO: See if we can do this better
|
// 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 rgb_color *color = NULL;
|
||||||
const BFont *font = NULL;
|
const BFont *font = NULL;
|
||||||
fStyles->GetNullStyle(&font, &color);
|
fStyles->GetNullStyle(&font, &color);
|
||||||
@@ -1773,32 +1771,24 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
} else {
|
} else {
|
||||||
height = (line + 1)->origin - line->origin;
|
height = (line + 1)->origin - line->origin;
|
||||||
|
|
||||||
// special case: go down one line if inOffset is a newline
|
int32 offset = line->offset;
|
||||||
if (inOffset == textLength && fText->RealCharAt(inOffset - 1)
|
int32 length = inOffset - line->offset;
|
||||||
== B_ENTER) {
|
int32 numBytes = length;
|
||||||
result.y += height;
|
bool foundTab = false;
|
||||||
height = LineHeight(CountLines() - 1);
|
do {
|
||||||
|
foundTab = fText->FindChar(B_TAB, offset, &numBytes);
|
||||||
|
float width = _StyledWidth(offset, numBytes);
|
||||||
|
result.x += width;
|
||||||
|
|
||||||
} else {
|
if (foundTab) {
|
||||||
int32 offset = line->offset;
|
result.x += _ActualTabWidth(result.x);
|
||||||
int32 length = inOffset - line->offset;
|
numBytes++;
|
||||||
int32 numBytes = length;
|
}
|
||||||
bool foundTab = false;
|
|
||||||
do {
|
|
||||||
foundTab = fText->FindChar(B_TAB, offset, &numBytes);
|
|
||||||
float width = _StyledWidth(offset, numBytes);
|
|
||||||
result.x += width;
|
|
||||||
|
|
||||||
if (foundTab) {
|
offset += numBytes;
|
||||||
result.x += _ActualTabWidth(result.x);
|
length -= numBytes;
|
||||||
numBytes++;
|
numBytes = length;
|
||||||
}
|
} while (foundTab && length > 0);
|
||||||
|
|
||||||
offset += numBytes;
|
|
||||||
length -= numBytes;
|
|
||||||
numBytes = length;
|
|
||||||
} while (foundTab && length > 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fAlignment != B_ALIGN_LEFT) {
|
if (fAlignment != B_ALIGN_LEFT) {
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
#include "LineBuffer.h"
|
#include "LineBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
BTextView::LineBuffer::LineBuffer()
|
BTextView::LineBuffer::LineBuffer()
|
||||||
: _BTextViewSupportBuffer_<STELine>(20, 2)
|
: _BTextViewSupportBuffer_<STELine>(20, 2)
|
||||||
{
|
{
|
||||||
@@ -54,7 +53,7 @@ BTextView::LineBuffer::OffsetToLine(int32 offset) const
|
|||||||
int32 minIndex = 0;
|
int32 minIndex = 0;
|
||||||
int32 maxIndex = fItemCount - 1;
|
int32 maxIndex = fItemCount - 1;
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while (minIndex < maxIndex) {
|
while (minIndex < maxIndex) {
|
||||||
index = (minIndex + maxIndex) >> 1;
|
index = (minIndex + maxIndex) >> 1;
|
||||||
if (offset >= fBuffer[index].offset) {
|
if (offset >= fBuffer[index].offset) {
|
||||||
@@ -65,7 +64,11 @@ BTextView::LineBuffer::OffsetToLine(int32 offset) const
|
|||||||
} else
|
} else
|
||||||
maxIndex = index;
|
maxIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do check for last line
|
||||||
|
if (minIndex == maxIndex && offset >= fBuffer[maxIndex].offset)
|
||||||
|
index = maxIndex;
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +79,7 @@ BTextView::LineBuffer::PixelToLine(float pixel) const
|
|||||||
int32 minIndex = 0;
|
int32 minIndex = 0;
|
||||||
int32 maxIndex = fItemCount - 1;
|
int32 maxIndex = fItemCount - 1;
|
||||||
int32 index = 0;
|
int32 index = 0;
|
||||||
|
|
||||||
while (minIndex < maxIndex) {
|
while (minIndex < maxIndex) {
|
||||||
index = (minIndex + maxIndex) >> 1;
|
index = (minIndex + maxIndex) >> 1;
|
||||||
if (pixel >= fBuffer[index].origin) {
|
if (pixel >= fBuffer[index].origin) {
|
||||||
@@ -87,14 +90,18 @@ BTextView::LineBuffer::PixelToLine(float pixel) const
|
|||||||
} else
|
} else
|
||||||
maxIndex = index;
|
maxIndex = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// do check for last line
|
||||||
|
if (minIndex == maxIndex && pixel >= fBuffer[maxIndex].origin)
|
||||||
|
index = maxIndex;
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTextView::LineBuffer::BumpOrigin(float delta, long index)
|
BTextView::LineBuffer::BumpOrigin(float delta, long index)
|
||||||
{
|
{
|
||||||
for (long i = index; i < fItemCount; i++)
|
for (long i = index; i < fItemCount; i++)
|
||||||
fBuffer[i].origin += delta;
|
fBuffer[i].origin += delta;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user