diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index 43a1297e75..bf3e3c9a35 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -255,6 +255,7 @@ virtual void Undo(BClipboard *clipboard); undo_state UndoState(bool *isRedo) const; protected: +void _ScrollToOffset(int32 nOffset, bool useHorz, bool useVert); virtual void GetDragParameters(BMessage *drag, BBitmap **bitmap, BPoint *point, diff --git a/src/kits/interface/TextInput.cpp b/src/kits/interface/TextInput.cpp index 9b92d7ea13..109393124b 100644 --- a/src/kits/interface/TextInput.cpp +++ b/src/kits/interface/TextInput.cpp @@ -100,6 +100,11 @@ _BTextInput_::KeyDown(const char* bytes, int32 numBytes) } } +void +_BTextInput_::ScrollToOffset(int32 nOffset) +{ + _ScrollToOffset(nOffset, true, false); +} void _BTextInput_::MakeFocus(bool state) diff --git a/src/kits/interface/TextInput.h b/src/kits/interface/TextInput.h index a2bec282ff..26f6ebbfba 100644 --- a/src/kits/interface/TextInput.h +++ b/src/kits/interface/TextInput.h @@ -62,6 +62,7 @@ virtual void MakeFocus(bool focusState = true); void AlignTextRect(); void SetInitialText(); +virtual void ScrollToOffset(int32 nOffset); virtual void Paste(BClipboard *clipboard); protected: diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 6479e7dda8..2832c9ae05 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -24,7 +24,7 @@ #include #include using namespace std; - +#define DEBUG 1 #include #include #include @@ -806,6 +806,7 @@ BTextView::MessageReceived(BMessage *message) switch (opcode) { case B_INPUT_METHOD_STARTED: { + PRINT(("B_INPUT_METHOD_STARTED\n")); BMessenger messenger; if (message->FindMessenger("be:reply_to", &messenger) == B_OK) { ASSERT(fInline == NULL); @@ -815,16 +816,21 @@ BTextView::MessageReceived(BMessage *message) } case B_INPUT_METHOD_STOPPED: + PRINT(("B_INPUT_METHOD_STOPPED\n")); delete fInline; fInline = NULL; break; case B_INPUT_METHOD_CHANGED: - HandleInputMethodChanged(message); + PRINT(("B_INPUT_METHOD_CHANGED\n")); + if (fInline != NULL) + HandleInputMethodChanged(message); break; case B_INPUT_METHOD_LOCATION_REQUEST: - HandleInputMethodLocationRequest(); + PRINT(("B_INPUT_METHOD_LOCATION_REQUEST\n")); + if (fInline != NULL) + HandleInputMethodLocationRequest(); break; default: @@ -1928,25 +1934,40 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset, BRegion *outRegion) */ void BTextView::ScrollToOffset(int32 inOffset) +{ + _ScrollToOffset(inOffset, ScrollBar(B_HORIZONTAL) != NULL, ScrollBar(B_VERTICAL) != NULL); +} + +void +BTextView::_ScrollToOffset(int32 inOffset, bool useHorz, bool useVert) { BRect bounds = Bounds(); float lineHeight = 0.0; + float xdiff = 0.0; + float ydiff = 0.0; BPoint point = PointAt(inOffset, &lineHeight); - // TODO: We should do the following, since otherwise the textview - // won't scroll unless it's attached to a scrollview. - /*if (!bounds.Contains(point)) - ScrollTo(point); */ - - if (ScrollBar(B_HORIZONTAL) != NULL) { - if (point.x < bounds.left || point.x >= bounds.right) - ScrollBar(B_HORIZONTAL)->SetValue(point.x - (bounds.IntegerWidth() / 2)); + if (useHorz) { + if (point.x < bounds.left) { + xdiff = -1 * (bounds.IntegerWidth() / 2); + // normalize scroll value to prevent scrolling past left boundary of view + if (bounds.left < fabs(xdiff)) + xdiff = -1 * bounds.left; + } else if (point.x >= bounds.right) + xdiff = bounds.IntegerWidth() / 2; } - if (ScrollBar(B_VERTICAL) != NULL) { - if (point.y < bounds.top || (point.y + lineHeight) >= bounds.bottom) - ScrollBar(B_VERTICAL)->SetValue(point.y - (bounds.IntegerHeight() / 2)); + if (useVert) { + if (point.y < bounds.top) { + ydiff = -1 * (bounds.IntegerHeight() / 2); + // normalize scroll value to prevent scrolling past top of view + if (bounds.top < fabs(ydiff)) + ydiff = -1 * bounds.top; + } else if (point.y >= bounds.bottom) + ydiff = bounds.IntegerHeight() / 2; } + + ScrollBy(xdiff, ydiff); } @@ -4398,8 +4419,7 @@ void BTextView::HandleInputMethodChanged(BMessage *message) { // TODO: block input if not editable (Andrew) - if (!fInline) - return; + ASSERT(fInline != NULL); const char *string = NULL; if (message->FindString("be:string", &string) < B_OK || string == NULL) @@ -4470,8 +4490,7 @@ BTextView::HandleInputMethodChanged(BMessage *message) void BTextView::HandleInputMethodLocationRequest() { - if (!fInline) - return; + ASSERT(fInline != NULL); int32 offset = fInline->Offset(); const int32 limit = offset + fInline->Length();