Simplified the code for input method highlighting. This had the nice side effect of fixing the multi line highlighting bug.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11291 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2005-02-08 17:43:56 +00:00
parent c1d1fdbc43
commit e005dc757f
2 changed files with 55 additions and 57 deletions
+13 -1
View File
@@ -24,7 +24,9 @@
// Description: Helper class to handle input method requests // Description: Helper class to handle input method requests
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// TODO: he bebook says we should highlight in blue/red different "clauses". // For a deeper understanding of this class, see the BeBook, sez.
// "The Input Server".
// TODO: the bebook says we should highlight in blue/red different "clauses".
// Though it looks like what really matters is the "selection" field in // Though it looks like what really matters is the "selection" field in
// the BMessage sent by the input method addon. Have I missed something ? // the BMessage sent by the input method addon. Have I missed something ?
@@ -127,6 +129,8 @@ _BInlineInput_::SetOffset(int32 offset)
} }
/*! \brief Returns the length of the selection, if any.
*/
int32 int32
_BInlineInput_::SelectionLength() const _BInlineInput_::SelectionLength() const
{ {
@@ -134,6 +138,9 @@ _BInlineInput_::SelectionLength() const
} }
/*! \brief Sets the length of the selection.
\param length The length of the selection.
*/
void void
_BInlineInput_::SetSelectionLength(int32 length) _BInlineInput_::SetSelectionLength(int32 length)
{ {
@@ -141,6 +148,8 @@ _BInlineInput_::SetSelectionLength(int32 length)
} }
/*! \brief Returns the offset into the method string of the selection.
*/
int32 int32
_BInlineInput_::SelectionOffset() const _BInlineInput_::SelectionOffset() const
{ {
@@ -148,6 +157,9 @@ _BInlineInput_::SelectionOffset() const
} }
/*! \brief Sets the offset into the method string of the selection.
\param offset The offset where the selection starts.
*/
void void
_BInlineInput_::SetSelectionOffset(int32 offset) _BInlineInput_::SetSelectionOffset(int32 offset)
{ {
+35 -49
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2004, Haiku, Inc. // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -35,13 +35,7 @@
// to refresh only changed parts of text (currently we often redraw the whole text) // to refresh only changed parts of text (currently we often redraw the whole text)
// Known Bugs: // Known Bugs:
// - Andrew reported some issue with beshare in _BWidthBuffer_::HashEscapements() // - Double buffering doesn't work well (disabled by default)
// (that's why its use is disabled by default), though I couldn't reproduce it.
// Could be a different handling of Lock/UnlockWidthBuffer() between R5 and us; if it's
// the case, it should disappear as soon as we use our libraries for everything.
// - Double buffering doesn't work well (disabled by default too)
// - Text inputted using the inline input method isn't highlighted correctly
// if it spans over multiple lines
#include <cstdlib> #include <cstdlib>
#include <cstdio> #include <cstdio>
@@ -74,7 +68,7 @@
#endif #endif
#define USE_WIDTHBUFFER 0 #define USE_WIDTHBUFFER 1
#define USE_DOUBLEBUFFERING 0 #define USE_DOUBLEBUFFERING 0
@@ -132,8 +126,8 @@ int32 BTextView::sWidthAtom = 0;
#endif #endif
const static rgb_color kBlackColor = { 0, 0, 0, 255 }; const static rgb_color kBlackColor = { 0, 0, 0, 255 };
const static rgb_color kBlueInputColor = { 152, 203, 255 }; const static rgb_color kBlueInputColor = { 152, 203, 255, 255 };
const static rgb_color kRedInputColor = { 255, 152, 152 }; const static rgb_color kRedInputColor = { 255, 152, 152, 255 };
static property_info static property_info
sPropertyList[] = { sPropertyList[] = {
@@ -3665,6 +3659,10 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
eraseRect = clipRect; eraseRect = clipRect;
} }
BRegion inputRegion;
if (fInline != NULL && fInline->IsActive())
GetTextRegion(fInline->Offset(), fInline->Offset() + fInline->Length(), &inputRegion);
float startLeft = fTextRect.left; float startLeft = fTextRect.left;
for (long i = startLine; i <= endLine; i++) { for (long i = startLine; i <= endLine; i++) {
long length = (line + 1)->offset - line->offset; long length = (line + 1)->offset - line->offset;
@@ -3714,43 +3712,32 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
} while ((tabChars + numTabs) < numChars); } while ((tabChars + numTabs) < numChars);
} }
// TODO: Revisit this as it looks ugly, and it's not even efficient, if (inputRegion.CountRects() > 0) {
// as the red highlight is drawn over the blue one. BRegion textRegion;
if (fInline && fInline->IsActive()) { GetTextRegion(offset, offset + length, &textRegion);
int32 inlineOffset = fInline->Offset();
int32 inlineLength = fInline->Length();
if (offset <= inlineOffset + inlineLength &&
offset + length >= inlineOffset + inlineLength) {
BPoint leftTop;
if (offset > inlineOffset)
leftTop = PointAt(offset);
else
leftTop = PointAt(inlineOffset);
float height;
BPoint rightBottom = PointAt(inlineOffset + inlineLength, &height);
rightBottom.y += height;
BRect rect(leftTop, rightBottom);
textRegion.IntersectWith(&inputRegion);
view->PushState(); view->PushState();
// Highlight in blue the inputted text // Highlight in blue the inputted text
view->SetLowColor(kBlueInputColor); view->SetHighColor(kBlueInputColor);
view->FillRect(rect, B_SOLID_LOW); view->FillRect(textRegion.Frame());
// Highlight in red the selected part // Highlight in red the selected part
if (fInline->SelectionLength() > 0) { if (fInline->SelectionLength() > 0) {
rightBottom = PointAt(inlineOffset + fInline->SelectionOffset() + BRegion selectedRegion;
fInline->SelectionLength(), &height); GetTextRegion(fInline->Offset() + fInline->SelectionOffset(),
rightBottom.y += height; fInline->Offset() + fInline->SelectionOffset() + fInline->SelectionLength(),
rect.SetLeftTop(PointAt(inlineOffset + fInline->SelectionOffset())); &selectedRegion);
rect.SetRightBottom(rightBottom);
view->SetLowColor(kRedInputColor); textRegion.IntersectWith(&selectedRegion);
view->FillRect(rect, B_SOLID_LOW);
view->SetHighColor(kRedInputColor);
view->FillRect(textRegion.Frame());
} }
view->PopState(); view->PopState();
} }
}
view->DrawString(fText->GetString(offset, tabChars), tabChars); view->DrawString(fText->GetString(offset, tabChars), tabChars);
@@ -3776,7 +3763,6 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
line++; line++;
} }
// TODO: Maybe this fits better into "BTextView::Refresh()"
// draw the caret/hilite the selection // draw the caret/hilite the selection
if (fActive) { if (fActive) {
if (fSelStart != fSelEnd && fSelectable) if (fSelStart != fSelEnd && fSelectable)
@@ -4017,11 +4003,11 @@ void
BTextView::UpdateScrollbars() BTextView::UpdateScrollbars()
{ {
BRect bounds(Bounds()); BRect bounds(Bounds());
BScrollBar *hsb = ScrollBar(B_HORIZONTAL); BScrollBar *horizontalScrollBar = ScrollBar(B_HORIZONTAL);
BScrollBar *vsb = ScrollBar(B_VERTICAL); BScrollBar *verticalScrollBar = ScrollBar(B_VERTICAL);
// do we have a horizontal scroll bar? // do we have a horizontal scroll bar?
if (hsb != NULL) { if (horizontalScrollBar != NULL) {
long viewWidth = bounds.IntegerWidth(); long viewWidth = bounds.IntegerWidth();
long dataWidth = fTextRect.IntegerWidth(); long dataWidth = fTextRect.IntegerWidth();
dataWidth += (long)ceil(fTextRect.left) + 1; dataWidth += (long)ceil(fTextRect.left) + 1;
@@ -4029,13 +4015,13 @@ BTextView::UpdateScrollbars()
long maxRange = dataWidth - viewWidth; long maxRange = dataWidth - viewWidth;
maxRange = max_c(maxRange, 0); maxRange = max_c(maxRange, 0);
hsb->SetRange(0, (float)maxRange); horizontalScrollBar->SetRange(0, (float)maxRange);
hsb->SetProportion((float)viewWidth / (float)dataWidth); horizontalScrollBar->SetProportion((float)viewWidth / (float)dataWidth);
hsb->SetSteps(10, dataWidth / 10); horizontalScrollBar->SetSteps(10, dataWidth / 10);
} }
// how about a vertical scroll bar? // how about a vertical scroll bar?
if (vsb != NULL) { if (verticalScrollBar != NULL) {
long viewHeight = bounds.IntegerHeight(); long viewHeight = bounds.IntegerHeight();
long dataHeight = fTextRect.IntegerHeight(); long dataHeight = fTextRect.IntegerHeight();
dataHeight += (long)ceil(fTextRect.top) + 1; dataHeight += (long)ceil(fTextRect.top) + 1;
@@ -4043,9 +4029,9 @@ BTextView::UpdateScrollbars()
long maxRange = dataHeight - viewHeight; long maxRange = dataHeight - viewHeight;
maxRange = max_c(maxRange, 0); maxRange = max_c(maxRange, 0);
vsb->SetRange(0, maxRange); verticalScrollBar->SetRange(0, maxRange);
vsb->SetProportion((float)viewHeight / (float)dataHeight); verticalScrollBar->SetProportion((float)viewHeight / (float)dataHeight);
vsb->SetSteps(12, viewHeight); verticalScrollBar->SetSteps(12, viewHeight);
} }
} }