From 46ea5b1e49005fa48c79898fb3ad9f8f28476b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Mon, 25 Feb 2008 23:34:23 +0000 Subject: [PATCH] Further improvements to auto scrolling and text rect + container view resizing: * Renaming things in Tracker list mode no longer magically grows the text view. * ScrollToOffset() is not supposed to depend on the existence of any scroll bars, in R5 text views simply scroll to where they need to. This fixes renaming things in Tracker when hitting the window bounds (text widget stops growing and starts to autoscroll) and also the Text tool in WonderBrush. * _ScrollToOffset() is therefor no longer needed. * The insets of the text rect are not so interesting as the original width. In auto resizing mode, the original width is important when there is no container view. In this setup, the text rect auto resizing is mainly needed for auto scrolling, but it should never shrink below the original size. * Further improved auto scrolling for right aligned and center aligned text views, it works like R5 now. Also take the line height into account when checking for the bounds bottom. Removed extra spacing for vertical scrolling. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24130 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/TextView.h | 7 +-- src/kits/interface/TextInput.cpp | 6 -- src/kits/interface/TextInput.h | 1 - src/kits/interface/TextView.cpp | 97 ++++++++++++++++---------------- 4 files changed, 50 insertions(+), 61 deletions(-) diff --git a/headers/os/interface/TextView.h b/headers/os/interface/TextView.h index de356b4be7..0509a8085f 100644 --- a/headers/os/interface/TextView.h +++ b/headers/os/interface/TextView.h @@ -205,8 +205,6 @@ class BTextView : public BView { undo_state UndoState(bool* isRedo) const; protected: - void _ScrollToOffset(int32 nOffset, bool useHorz, bool useVert); - virtual void GetDragParameters(BMessage* drag, BBitmap** _bitmap, BPoint* point, BHandler** _handler); @@ -315,8 +313,7 @@ class BTextView : public BView { _BLineBuffer_* fLines; _BStyleBuffer_* fStyles; BRect fTextRect; - float fLeftInset; - float fRightInset; + float fMinTextRectWidth; int32 fSelStart; int32 fSelEnd; bool fCaretVisible; @@ -347,7 +344,7 @@ class BTextView : public BView { BPoint fWhere; _BTextTrackState_* fTrackingMouse; _BTextChangeResult_* fTextChange; - uint32 _reserved[7]; + uint32 _reserved[8]; static _BWidthBuffer_* sWidths; static sem_id sWidthSem; diff --git a/src/kits/interface/TextInput.cpp b/src/kits/interface/TextInput.cpp index 784945feec..782b359821 100644 --- a/src/kits/interface/TextInput.cpp +++ b/src/kits/interface/TextInput.cpp @@ -114,12 +114,6 @@ _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 2fd3122286..6825c9cead 100644 --- a/src/kits/interface/TextInput.h +++ b/src/kits/interface/TextInput.h @@ -37,7 +37,6 @@ 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 dac8188d04..eb0c81756a 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -1904,39 +1904,33 @@ 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 useHorizontal, bool useVertical) { BRect bounds = Bounds(); float lineHeight = 0.0; float xDiff = 0.0; float yDiff = 0.0; BPoint point = PointAt(inOffset, &lineHeight); - - if (useHorizontal) { - if (point.x < bounds.left) - xDiff = point.x - bounds.left - bounds.IntegerWidth() / 2; - else if (point.x >= bounds.right) - xDiff = point.x - bounds.right + bounds.IntegerWidth() / 2; - // prevent negative scroll offset - if (bounds.left + xDiff < 0.0) - xDiff = -bounds.left; - } - if (useVertical) { - if (point.y < bounds.top) - yDiff = point.y - bounds.top - bounds.IntegerHeight() / 2; - else if (point.y >= bounds.bottom) - yDiff = point.y - bounds.bottom + bounds.IntegerHeight() / 2; - // prevent negative scroll offset - if (bounds.top + yDiff < 0.0) - yDiff = -bounds.top; - } + // horizontal + float extraSpace = fAlignment == B_ALIGN_LEFT ? + ceilf(bounds.IntegerWidth() / 2) : 0.0; + + if (point.x < bounds.left) + xDiff = point.x - bounds.left - extraSpace; + else if (point.x >= bounds.right) + xDiff = point.x - bounds.right + extraSpace; + + // vertical + if (point.y < bounds.top) + yDiff = point.y - bounds.top; + else if (point.y + lineHeight >= bounds.bottom) + yDiff = point.y + lineHeight - bounds.bottom; + + // prevent negative scroll offset + if (bounds.left + xDiff < 0.0) + xDiff = -bounds.left; + if (bounds.top + yDiff < 0.0) + yDiff = -bounds.top; ScrollBy(xDiff, yDiff); } @@ -1983,13 +1977,10 @@ BTextView::SetTextRect(BRect rect) return; fTextRect = rect; - fLeftInset = fTextRect.left; - fRightInset = Bounds().right - fTextRect.right; - - if (Window() != NULL) { + fMinTextRectWidth = fTextRect.Width(); + + if (Window() != NULL) Invalidate(); - Window()->UpdateIfNeeded(); - } } @@ -2237,11 +2228,8 @@ BTextView::SetAlignment(alignment flag) fAlignment = flag; // After setting new alignment, update the view/window - BWindow *window = Window(); - if (window) { + if (Window() != NULL) Invalidate(); - window->UpdateIfNeeded(); - } } } @@ -2715,8 +2703,7 @@ BTextView::_InitObject(BRect textRect, const BFont *initialFont, // to have less code duplication, and a single place where to do changes // if needed., fTextRect = textRect; - fLeftInset = fTextRect.left; - fRightInset = Bounds().right - fTextRect.right; + fMinTextRectWidth = fTextRect.Width(); fSelStart = fSelEnd = 0; fCaretVisible = false; fCaretTime = 0; @@ -4031,7 +4018,7 @@ BTextView::_PerformAutoScrolling() if (bounds.left - value >= 0) scrollBy.x = -value; } - + float lineHeight = 0; float vertDiff = 0; if (fWhere.y > bounds.bottom) { @@ -4106,16 +4093,24 @@ BTextView::_AutoResize(bool redraw) BRect bounds = Bounds(); float oldWidth = fTextRect.Width(); - float newWidth = max_c(bounds.Width() - (fLeftInset + fRightInset), - ceilf(LineWidth(0))); + float minWidth = fContainerView != NULL ? 3.0 : fMinTextRectWidth; + float newWidth = max_c(minWidth, ceilf(LineWidth(0))); + + if (newWidth == oldWidth) + return; if (fContainerView != NULL) { - fContainerView->ResizeBy(ceilf(newWidth - oldWidth), 0); - if (fAlignment == B_ALIGN_CENTER) - fContainerView->MoveBy(ceilf((oldWidth - newWidth) / 2), 0); - else if (fAlignment == B_ALIGN_RIGHT) + // NOTE: This container view thing is only used by Tracker + // move container view if not left aligned + if (fAlignment == B_ALIGN_CENTER) { + if (fmod(ceilf(newWidth - oldWidth), 2.0) != 0.0) + newWidth += 1; + fContainerView->MoveBy(ceilf(oldWidth - newWidth) / 2, 0); + } else if (fAlignment == B_ALIGN_RIGHT) { fContainerView->MoveBy(ceilf(oldWidth - newWidth), 0); -// fContainerView->Invalidate(); + } + // resize container view + fContainerView->ResizeBy(ceilf(newWidth - oldWidth), 0); } fTextRect.right = fTextRect.left + newWidth; @@ -4123,9 +4118,13 @@ BTextView::_AutoResize(bool redraw) if (redraw) _DrawLines(0, 0); - // Erase the old text (TODO: Might not work for alignments different than B_ALIGN_LEFT) - SetLowColor(ViewColor()); - FillRect(BRect(fTextRect.right, fTextRect.top, Bounds().right, fTextRect.bottom), B_SOLID_LOW); + // erase any potential left over outside the text rect + // (can only be on right hand side) + BRect dirty(fTextRect.right + 1, fTextRect.top, bounds.right, fTextRect.bottom); + if (dirty.IsValid()) { + SetLowColor(ViewColor()); + FillRect(dirty, B_SOLID_LOW); + } }