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:
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user