Implemented auto horizontal scrolling (by fixed steps for now), moved
auto scrolling to its own method, introduced a new private StyledWidthUTF8Safe method. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19694 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -311,6 +311,11 @@ virtual void _ReservedTextView12();
|
|||||||
int32 length,
|
int32 length,
|
||||||
float *outAscent = NULL,
|
float *outAscent = NULL,
|
||||||
float *outDescent = NULL) const;
|
float *outDescent = NULL) const;
|
||||||
|
float StyledWidthUTF8Safe(int32 fromOffset,
|
||||||
|
int32 numChars,
|
||||||
|
float *outAscent = NULL,
|
||||||
|
float *outDescent = NULL) const;
|
||||||
|
|
||||||
float ActualTabWidth(float location) const;
|
float ActualTabWidth(float location) const;
|
||||||
|
|
||||||
void DoInsertText(const char *inText,
|
void DoInsertText(const char *inText,
|
||||||
@@ -343,7 +348,8 @@ virtual void _ReservedTextView12();
|
|||||||
bool MessageDropped(BMessage *inMessage,
|
bool MessageDropped(BMessage *inMessage,
|
||||||
BPoint where,
|
BPoint where,
|
||||||
BPoint offset);
|
BPoint offset);
|
||||||
|
|
||||||
|
void PerformAutoScrolling();
|
||||||
void UpdateScrollbars();
|
void UpdateScrollbars();
|
||||||
void AutoResize(bool doredraw=true);
|
void AutoResize(bool doredraw=true);
|
||||||
|
|
||||||
|
|||||||
@@ -911,35 +911,8 @@ BTextView::MessageReceived(BMessage *message)
|
|||||||
delete fClickRunner;
|
delete fClickRunner;
|
||||||
fClickRunner = NULL;
|
fClickRunner = NULL;
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
// Scroll the view a bit if mouse is outside the view bounds
|
PerformAutoScrolling();
|
||||||
|
|
||||||
BRect bounds = Bounds();
|
|
||||||
|
|
||||||
// TODO: Horizontal scrolling
|
|
||||||
/*if (fWhere.x > bounds.right)
|
|
||||||
scrollBy.x = fWhere.x - bounds.right;
|
|
||||||
else if (fWhere.x < bounds.left)
|
|
||||||
scrollBy.x = fWhere.x - bounds.left;
|
|
||||||
*/
|
|
||||||
float lineHeight = 0;
|
|
||||||
float diff = 0;
|
|
||||||
if (fWhere.y > bounds.bottom) {
|
|
||||||
lineHeight = LineHeight(LineAt(bounds.LeftBottom()));
|
|
||||||
diff = fWhere.y - bounds.bottom;
|
|
||||||
} else if (fWhere.y < bounds.top) {
|
|
||||||
lineHeight = LineHeight(LineAt(bounds.LeftTop()));
|
|
||||||
diff = fWhere.y - bounds.top; // negative value
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always scroll vertically by multiples of line height,
|
|
||||||
// based on the distance of the cursor from the border of the view
|
|
||||||
// TODO: Refine this, I can't even remember how beos works here
|
|
||||||
BPoint scrollBy;
|
|
||||||
scrollBy.y = lineHeight > 0 ? lineHeight * (int32)(floorf(diff) / lineHeight) : 0;
|
|
||||||
if (scrollBy != B_ORIGIN)
|
|
||||||
ScrollBy(scrollBy.x, scrollBy.y);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1690,7 +1663,7 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
// special case: go down one line if inOffset is a newline
|
// special case: go down one line if inOffset is a newline
|
||||||
if (inOffset == textLength && (*fText)[inOffset - 1] == B_ENTER) {
|
if (inOffset == textLength && (*fText)[inOffset - 1] == B_ENTER) {
|
||||||
float ascent, descent;
|
float ascent, descent;
|
||||||
StyledWidth(inOffset, 1, &ascent, &descent);
|
StyledWidthUTF8Safe(inOffset, 1, &ascent, &descent);
|
||||||
|
|
||||||
result.y += height;
|
result.y += height;
|
||||||
height = ascent + descent;
|
height = ascent + descent;
|
||||||
@@ -1698,23 +1671,23 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
} else {
|
} else {
|
||||||
int32 offset = line->offset;
|
int32 offset = line->offset;
|
||||||
int32 length = inOffset - line->offset;
|
int32 length = inOffset - line->offset;
|
||||||
int32 numChars = length;
|
int32 numBytes = length;
|
||||||
bool foundTab = false;
|
bool foundTab = false;
|
||||||
do {
|
do {
|
||||||
foundTab = fText->FindChar(B_TAB, offset, &numChars);
|
foundTab = fText->FindChar(B_TAB, offset, &numBytes);
|
||||||
|
|
||||||
float width = StyledWidth(offset, numChars);
|
float width = StyledWidth(offset, numBytes);
|
||||||
|
|
||||||
result.x += width;
|
result.x += width;
|
||||||
|
|
||||||
if (foundTab) {
|
if (foundTab) {
|
||||||
result.x += ActualTabWidth(result.x);
|
result.x += ActualTabWidth(result.x);
|
||||||
numChars++;
|
numBytes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset += numChars;
|
offset += numBytes;
|
||||||
length -= numChars;
|
length -= numBytes;
|
||||||
numChars = length;
|
numBytes = length;
|
||||||
} while (foundTab && length > 0);
|
} while (foundTab && length > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3497,6 +3470,21 @@ BTextView::StyledWidth(int32 fromOffset, int32 length, float *outAscent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Unlike the StyledWidth method, this one takes as parameter
|
||||||
|
// the number of chars, not the number of bytes.
|
||||||
|
float
|
||||||
|
BTextView::StyledWidthUTF8Safe(int32 fromOffset, int32 numChars,
|
||||||
|
float *outAscent, float *outDescent) const
|
||||||
|
{
|
||||||
|
int32 toOffset = fromOffset;
|
||||||
|
while (numChars--)
|
||||||
|
toOffset = NextInitialByte(toOffset);
|
||||||
|
|
||||||
|
const int32 length = toOffset - fromOffset;
|
||||||
|
return StyledWidth(fromOffset, length, outAscent, outDescent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Calculate the actual tab width for the given location.
|
/*! \brief Calculate the actual tab width for the given location.
|
||||||
\param location The location to calculate the tab width of.
|
\param location The location to calculate the tab width of.
|
||||||
\return The actual tab width for the given location
|
\return The actual tab width for the given location
|
||||||
@@ -4007,6 +3995,41 @@ BTextView::MessageDropped(BMessage *inMessage, BPoint where, BPoint offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BTextView::PerformAutoScrolling()
|
||||||
|
{
|
||||||
|
// Scroll the view a bit if mouse is outside the view bounds
|
||||||
|
BRect bounds = Bounds();
|
||||||
|
BPoint scrollBy;
|
||||||
|
|
||||||
|
// TODO: refine horizontal scrolling, for example by
|
||||||
|
// scrolling char by char and not using fixed values
|
||||||
|
if (fWhere.x > bounds.right) {
|
||||||
|
scrollBy.x = floorf((fWhere.x - bounds.right) / 10);
|
||||||
|
} else if (fWhere.x < bounds.left) {
|
||||||
|
scrollBy.x = floorf((fWhere.x - bounds.left) / 10); // negative value
|
||||||
|
}
|
||||||
|
|
||||||
|
float lineHeight = 0;
|
||||||
|
float vertDiff = 0;
|
||||||
|
if (fWhere.y > bounds.bottom) {
|
||||||
|
lineHeight = LineHeight(LineAt(bounds.LeftBottom()));
|
||||||
|
vertDiff = fWhere.y - bounds.bottom;
|
||||||
|
} else if (fWhere.y < bounds.top) {
|
||||||
|
lineHeight = LineHeight(LineAt(bounds.LeftTop()));
|
||||||
|
vertDiff = fWhere.y - bounds.top; // negative value
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always scroll vertically line by line or by multiples of that
|
||||||
|
// based on the distance of the cursor from the border of the view
|
||||||
|
// TODO: Refine this, I can't even remember how beos works here
|
||||||
|
scrollBy.y = lineHeight > 0 ? lineHeight * (int32)(floorf(vertDiff) / lineHeight) : 0;
|
||||||
|
|
||||||
|
if (scrollBy != B_ORIGIN)
|
||||||
|
ScrollBy(scrollBy.x, scrollBy.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! \brief Updates the scrollbars associated with the object (if any).
|
/*! \brief Updates the scrollbars associated with the object (if any).
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
|
|||||||
Reference in New Issue
Block a user