* unified application of style into a separate method _ApplyStyleRange()
in order to maintain the null-style appropriately, if required * finally fix #3040 for real (a single style is now maintained at all times for non-stylable textviews) * the caret is now being drawn with the correct size, even if it is on the empty line at the end of the buffer and a specific font size has been requested git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30532 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -362,6 +362,13 @@ private:
|
|||||||
void _SetRunArray(int32 startOffset, int32 endOffset,
|
void _SetRunArray(int32 startOffset, int32 endOffset,
|
||||||
const text_run_array* inRuns);
|
const text_run_array* inRuns);
|
||||||
|
|
||||||
|
void _ApplyStyleRange(int32 fromOffset,
|
||||||
|
int32 toOffset,
|
||||||
|
uint32 inMode = B_FONT_ALL,
|
||||||
|
const BFont *inFont = NULL,
|
||||||
|
const rgb_color *inColor = NULL,
|
||||||
|
bool syncNullStyle = true);
|
||||||
|
|
||||||
uint32 _CharClassification(int32 offset) const;
|
uint32 _CharClassification(int32 offset) const;
|
||||||
int32 _NextInitialByte(int32 offset) const;
|
int32 _NextInitialByte(int32 offset) const;
|
||||||
int32 _PreviousInitialByte(int32 offset) const;
|
int32 _PreviousInitialByte(int32 offset) const;
|
||||||
@@ -385,6 +392,8 @@ private:
|
|||||||
int32 _LineAt(const BPoint& point) const;
|
int32 _LineAt(const BPoint& point) const;
|
||||||
bool _IsOnEmptyLastLine(int32 offset) const;
|
bool _IsOnEmptyLastLine(int32 offset) const;
|
||||||
|
|
||||||
|
float _NullStyleHeight() const;
|
||||||
|
|
||||||
BPrivate::TextGapBuffer* fText;
|
BPrivate::TextGapBuffer* fText;
|
||||||
LineBuffer* fLines;
|
LineBuffer* fLines;
|
||||||
StyleBuffer* fStyles;
|
StyleBuffer* fStyles;
|
||||||
|
|||||||
@@ -1162,13 +1162,11 @@ BTextView::SetText(BFile *inFile, int32 inOffset, int32 inLength,
|
|||||||
// update the style runs
|
// update the style runs
|
||||||
fStyles->BumpOffset(inLength, fStyles->OffsetToRun(inOffset - 1) + 1);
|
fStyles->BumpOffset(inLength, fStyles->OffsetToRun(inOffset - 1) + 1);
|
||||||
|
|
||||||
if (inRuns != NULL)
|
if (fStylable && inRuns != NULL)
|
||||||
SetRunArray(inOffset, inOffset + inLength, inRuns);
|
SetRunArray(inOffset, inOffset + inLength, inRuns);
|
||||||
else {
|
else {
|
||||||
// apply nullStyle to inserted text
|
// apply null-style to inserted text
|
||||||
fStyles->SyncNullStyle(inOffset);
|
_ApplyStyleRange(inOffset, inOffset + inLength);
|
||||||
fStyles->SetStyleRange(inOffset, inOffset + inLength,
|
|
||||||
fText->Length(), B_FONT_ALL, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// recalc line breaks and draw the text
|
// recalc line breaks and draw the text
|
||||||
@@ -1591,14 +1589,7 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset,
|
|||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
|
|
||||||
if (startOffset > endOffset)
|
_HideCaret();
|
||||||
return;
|
|
||||||
|
|
||||||
BFont newFont;
|
|
||||||
if (font != NULL) {
|
|
||||||
newFont = font;
|
|
||||||
_NormalizeFont(&newFont);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int32 textLength = fText->Length();
|
const int32 textLength = fText->Length();
|
||||||
|
|
||||||
@@ -1607,23 +1598,22 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset,
|
|||||||
// style and ignore the offsets
|
// style and ignore the offsets
|
||||||
startOffset = 0;
|
startOffset = 0;
|
||||||
endOffset = textLength;
|
endOffset = textLength;
|
||||||
|
} else {
|
||||||
|
// pin offsets at reasonable values
|
||||||
|
if (startOffset < 0)
|
||||||
|
startOffset = 0;
|
||||||
|
else if (startOffset > textLength)
|
||||||
|
startOffset = textLength;
|
||||||
|
|
||||||
|
if (endOffset < 0)
|
||||||
|
endOffset = 0;
|
||||||
|
else if (endOffset > textLength)
|
||||||
|
endOffset = textLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pin offsets at reasonable values
|
// apply the style to the style buffer
|
||||||
if (startOffset < 0)
|
fStyles->InvalidateNullStyle();
|
||||||
startOffset = 0;
|
_ApplyStyleRange(startOffset, endOffset, fontMode, font, color);
|
||||||
else if (startOffset > textLength)
|
|
||||||
startOffset = textLength;
|
|
||||||
|
|
||||||
if (endOffset < 0)
|
|
||||||
endOffset = 0;
|
|
||||||
else if (endOffset > textLength)
|
|
||||||
endOffset = textLength;
|
|
||||||
|
|
||||||
// add the style to the style buffer
|
|
||||||
fStyles->SyncNullStyle(startOffset);
|
|
||||||
fStyles->SetStyleRange(startOffset, endOffset, fText->Length(),
|
|
||||||
fontMode, &newFont, color);
|
|
||||||
|
|
||||||
if ((fontMode & (B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE)) != 0) {
|
if ((fontMode & (B_FONT_FAMILY_AND_STYLE | B_FONT_SIZE)) != 0) {
|
||||||
// TODO: maybe only invalidate the layout (depending on
|
// TODO: maybe only invalidate the layout (depending on
|
||||||
@@ -1636,6 +1626,8 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset,
|
|||||||
_RequestDrawLines(_LineAt(startOffset), _LineAt(endOffset), startOffset,
|
_RequestDrawLines(_LineAt(startOffset), _LineAt(endOffset), startOffset,
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_ShowCaret();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1769,20 +1761,18 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
// Handle the case where there is only one line (no text inserted)
|
// Handle the case where there is only one 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) {
|
||||||
const rgb_color *color = NULL;
|
fStyles->SyncNullStyle(0);
|
||||||
const BFont *font = NULL;
|
height = _NullStyleHeight();
|
||||||
fStyles->GetNullStyle(&font, &color);
|
|
||||||
|
|
||||||
font_height fontHeight;
|
|
||||||
font->GetHeight(&fontHeight);
|
|
||||||
height = fontHeight.ascent + fontHeight.descent;
|
|
||||||
} else {
|
} else {
|
||||||
height = (line + 1)->origin - line->origin;
|
height = (line + 1)->origin - line->origin;
|
||||||
|
|
||||||
if (_IsOnEmptyLastLine(inOffset)) {
|
if (_IsOnEmptyLastLine(inOffset)) {
|
||||||
// special case: go down one line if inOffset is the newline
|
// special case: go down one line if inOffset is at the newline
|
||||||
// at the end of the buffer
|
// at the end of the buffer ...
|
||||||
result.y += height;
|
result.y += height;
|
||||||
|
// ... and return the height of that (empty) line
|
||||||
|
fStyles->SyncNullStyle(inOffset);
|
||||||
|
height = _NullStyleHeight();
|
||||||
} else {
|
} else {
|
||||||
int32 offset = line->offset;
|
int32 offset = line->offset;
|
||||||
int32 length = inOffset - line->offset;
|
int32 length = inOffset - line->offset;
|
||||||
@@ -2983,27 +2973,31 @@ BTextView::InsertText(const char *inText, int32 inLength, int32 inOffset,
|
|||||||
const text_run_array *inRuns)
|
const text_run_array *inRuns)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
// why add nothing?
|
|
||||||
if (inLength < 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// TODO: Pin offset/lenght
|
if (inLength < 0)
|
||||||
// add the text to the buffer
|
inLength = 0;
|
||||||
fText->InsertText(inText, inLength, inOffset);
|
|
||||||
|
|
||||||
// update the start offsets of each line below offset
|
if (inOffset < 0)
|
||||||
fLines->BumpOffset(inLength, _LineAt(inOffset) + 1);
|
inOffset = 0;
|
||||||
|
else if (inOffset > fText->Length())
|
||||||
|
inOffset = fText->Length();
|
||||||
|
|
||||||
// update the style runs
|
if (inLength > 0) {
|
||||||
fStyles->BumpOffset(inLength, fStyles->OffsetToRun(inOffset - 1) + 1);
|
// add the text to the buffer
|
||||||
|
fText->InsertText(inText, inLength, inOffset);
|
||||||
|
|
||||||
if (fStylable && (inRuns != NULL)) {
|
// update the start offsets of each line below offset
|
||||||
|
fLines->BumpOffset(inLength, _LineAt(inOffset) + 1);
|
||||||
|
|
||||||
|
// update the style runs
|
||||||
|
fStyles->BumpOffset(inLength, fStyles->OffsetToRun(inOffset - 1) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fStylable && inRuns != NULL) {
|
||||||
_SetRunArray(inOffset, inOffset + inLength, inRuns);
|
_SetRunArray(inOffset, inOffset + inLength, inRuns);
|
||||||
} else {
|
} else {
|
||||||
// apply nullStyle to inserted text
|
// apply null-style to inserted text
|
||||||
fStyles->SyncNullStyle(inOffset);
|
_ApplyStyleRange(inOffset, inOffset + inLength);
|
||||||
fStyles->SetStyleRange(inOffset, inOffset + inLength,
|
|
||||||
fText->Length(), B_FONT_ALL, NULL, NULL);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4927,10 +4921,8 @@ BTextView::_SetRunArray(int32 startOffset, int32 endOffset,
|
|||||||
toOffset = (toOffset > endOffset) ? endOffset : toOffset;
|
toOffset = (toOffset > endOffset) ? endOffset : toOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
BFont font = theRun->font;
|
_ApplyStyleRange(fromOffset, toOffset, B_FONT_ALL, &theRun->font,
|
||||||
_NormalizeFont(&font);
|
&theRun->color, false);
|
||||||
fStyles->SetStyleRange(fromOffset, toOffset, textLength,
|
|
||||||
B_FONT_ALL, &theRun->font, &theRun->color);
|
|
||||||
|
|
||||||
theRun++;
|
theRun++;
|
||||||
}
|
}
|
||||||
@@ -5289,6 +5281,43 @@ BTextView::_IsOnEmptyLastLine(int32 offset) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BTextView::_ApplyStyleRange(int32 fromOffset, int32 toOffset, uint32 inMode,
|
||||||
|
const BFont *inFont, const rgb_color *inColor, bool syncNullStyle)
|
||||||
|
{
|
||||||
|
if (inFont != NULL) {
|
||||||
|
// if a font has been given, normalize it
|
||||||
|
BFont font = *inFont;
|
||||||
|
_NormalizeFont(&font);
|
||||||
|
inFont = &font;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fStylable) {
|
||||||
|
// always apply font and color to full range for non-stylable textviews
|
||||||
|
fromOffset = 0;
|
||||||
|
toOffset = fText->Length();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (syncNullStyle)
|
||||||
|
fStyles->SyncNullStyle(fromOffset);
|
||||||
|
|
||||||
|
fStyles->SetStyleRange(fromOffset, toOffset, fText->Length(), inMode,
|
||||||
|
inFont, inColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
BTextView::_NullStyleHeight() const
|
||||||
|
{
|
||||||
|
const BFont *font = NULL;
|
||||||
|
fStyles->GetNullStyle(&font, NULL);
|
||||||
|
|
||||||
|
font_height fontHeight;
|
||||||
|
font->GetHeight(&fontHeight);
|
||||||
|
return fontHeight.ascent + fontHeight.descent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - BTextView::TextTrackState
|
// #pragma mark - BTextView::TextTrackState
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user