IK: align BTextView text rect/fix alignment

Preserve passed in text rect in fTextRext (unless in layout)
and create an internal version fAlignedTextRect which is used
in place of fTextRect. fAlignedTextRext is aligned to fit the
text rect bounds and grows to fit. fAlignedTextRect always grows
vertically but only grows horizontally if wrap is off.

Left-aligned text view's grow right, right-aligned ones grow left,
and center center aligned ones grow out.

Set fTextRect to bounds in _DoLayout().

Reduce left and right padding inside text views from full label
spacing to half label spacing. Unify padding between BTextControl
and BTextView.

Fixing padding also fixes right and center-aligned BTextViews.

Undo extra scrolling for non-left text views from hrev24130 fixing
a scrolling left and right with mouse bug when it shouldn't.

Replace max_c and min_c with std::max and std::min respectively.

Remove scrolling from one instance of BTextView::SetText as it
produced undesired results while editing a scrolled text view.

Set text rect in BTextControl::DoLayout() and ScreenSaver
PreviewView::AddPreview().

Don't add padding if BTextView::SetInsets() is called. Set insets
to 0 in Tracker "Edit name" setting which prevents default padding
from being added. This is so that when you rename a file in Tracker
the TextView appears on top of the file name text with no padding.

80 char limit fixes.

Fixes #1651 #12608 #13796 #15189 #15688

Change-Id: I8c6106effc612f49aff374f29742471628b5df86
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3054
Reviewed-by: Adrien Destugues <[email protected]>
This commit is contained in:
John Scipione
2020-08-06 11:51:15 +00:00
committed by Adrien Destugues
parent a8ea8cd1d4
commit a9b301871d
9 changed files with 251 additions and 175 deletions
+1 -1
View File
@@ -136,7 +136,7 @@ class Haiku(callbacks.Plugin):
to = None to = None
if len(args) > 0: if len(args) > 0:
to = args[0] to = args[0]
t = "Current release: http://www.haiku-os.org/get-haiku - Nightly builds: http://haiku-files.org/haiku/development/" t = "Current release: http://www.haiku-os.org/get-haiku - Nightly builds: http://download.haiku-os.org"
irc.reply(t, to = to) irc.reply(t, to = to)
def dl(self, irc, msg, args): def dl(self, irc, msg, args):
+3 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2007-2009, Haiku, Inc. All rights reserved. * Copyright 2007-2020 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef _TEXTVIEW_H #ifndef _TEXTVIEW_H
@@ -416,6 +416,7 @@ private:
LineBuffer* fLines; LineBuffer* fLines;
StyleBuffer* fStyles; StyleBuffer* fStyles;
BRect fTextRect; BRect fTextRect;
BRect fAlignedTextRect;
int32 fSelStart; int32 fSelStart;
int32 fSelEnd; int32 fSelEnd;
bool fCaretVisible; bool fCaretVisible;
@@ -463,7 +464,7 @@ private:
bool fInstalledRemoveCommandWordwiseShortcuts : 1; bool fInstalledRemoveCommandWordwiseShortcuts : 1;
bool fInstalledRemoveOptionWordwiseShortcuts : 1; bool fInstalledRemoveOptionWordwiseShortcuts : 1;
uint32 _reserved[6]; uint32 _reserved[2];
}; };
#endif // _TEXTVIEW_H #endif // _TEXTVIEW_H
+3 -4
View File
@@ -1,11 +1,12 @@
/* /*
* Copyright 2001-2015, Haiku Inc. * Copyright 2001-2020 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Frans van Nispen (xlr8@tref.nl) * Frans van Nispen (xlr8@tref.nl)
* Stephan Aßmus <superstippi@gmx.de> * Stephan Aßmus <superstippi@gmx.de>
* Ingo Weinhold <bonefish@cs.tu-berlin.de> * Ingo Weinhold <bonefish@cs.tu-berlin.de>
* John Scipione <jscipione@gmail.com>
*/ */
@@ -637,7 +638,6 @@ void
BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment) BTextControl::SetAlignment(alignment labelAlignment, alignment textAlignment)
{ {
fText->SetAlignment(textAlignment); fText->SetAlignment(textAlignment);
fText->AlignTextRect();
if (fLabelAlign != labelAlignment) { if (fLabelAlign != labelAlignment) {
fLabelAlign = labelAlignment; fLabelAlign = labelAlignment;
@@ -911,6 +911,7 @@ BTextControl::DoLayout()
// place the text view and set the divider // place the text view and set the divider
textFrame.InsetBy(kFrameMargin, kFrameMargin); textFrame.InsetBy(kFrameMargin, kFrameMargin);
BLayoutUtils::AlignInFrame(fText, textFrame); BLayoutUtils::AlignInFrame(fText, textFrame);
fText->SetTextRect(textFrame.OffsetToCopy(B_ORIGIN));
fDivider = divider; fDivider = divider;
@@ -1115,7 +1116,6 @@ BTextControl::_InitText(const char* initialText, const BMessage* archive)
SetText(initialText); SetText(initialText);
fText->SetAlignment(B_ALIGN_LEFT); fText->SetAlignment(B_ALIGN_LEFT);
fText->AlignTextRect();
} }
// Although this is not strictly initializing the text view, // Although this is not strictly initializing the text view,
@@ -1171,7 +1171,6 @@ BTextControl::_LayoutTextView()
frame.InsetBy(kFrameMargin, kFrameMargin); frame.InsetBy(kFrameMargin, kFrameMargin);
fText->MoveTo(frame.left, frame.top); fText->MoveTo(frame.left, frame.top);
fText->ResizeTo(frame.Width(), frame.Height()); fText->ResizeTo(frame.Width(), frame.Height());
fText->AlignTextRect();
TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height()); TRACE("width: %.2f, height: %.2f\n", Frame().Width(), Frame().Height());
TRACE("fDivider: %.2f\n", fDivider); TRACE("fDivider: %.2f\n", fDivider);
+2 -40
View File
@@ -1,10 +1,11 @@
/* /*
* Copyright 2001-2015, Haiku Inc. All rights reserved. * Copyright 2001-2020 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Frans van Nispen (xlr8@tref.nl) * Frans van Nispen (xlr8@tref.nl)
* Marc Flerackers (mflerackers@androme.be) * Marc Flerackers (mflerackers@androme.be)
* John Scipione (jscipione@gmail.com)
*/ */
@@ -14,7 +15,6 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ControlLook.h>
#include <InterfaceDefs.h> #include <InterfaceDefs.h>
#include <LayoutUtils.h> #include <LayoutUtils.h>
#include <Message.h> #include <Message.h>
@@ -84,8 +84,6 @@ void
_BTextInput_::FrameResized(float width, float height) _BTextInput_::FrameResized(float width, float height)
{ {
BTextView::FrameResized(width, height); BTextView::FrameResized(width, height);
AlignTextRect();
} }
@@ -162,42 +160,6 @@ _BTextInput_::MinSize()
} }
void
_BTextInput_::AlignTextRect()
{
// the label font could require the control to be higher than
// necessary for the text view, we compensate this by layouting
// the text rect to be in the middle, normally this means there
// is one pixel spacing on each side
BRect textRect(Bounds());
float vInset = max_c(1,
floorf((textRect.Height() - LineHeight(0)) / 2.0));
float hInset = 2;
float textFontWidth = TextRect().right;
switch (Alignment()) {
case B_ALIGN_LEFT:
hInset = be_control_look->DefaultLabelSpacing();
break;
case B_ALIGN_RIGHT:
hInset = textRect.right - textFontWidth;
hInset -= be_control_look->DefaultLabelSpacing();
break;
case B_ALIGN_CENTER:
hInset = (textRect.right - textFontWidth) / 2.0;
break;
default:
break;
}
textRect.InsetBy(hInset, vInset);
SetTextRect(textRect);
}
void void
_BTextInput_::SetInitialText() _BTextInput_::SetInitialText()
{ {
+2 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2008, Haiku Inc. All rights reserved. * Copyright 2001-2020 Haiku Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -11,6 +11,7 @@
#ifndef _TEXT_CONTROLI_H #ifndef _TEXT_CONTROLI_H
#define _TEXT_CONTROLI_H #define _TEXT_CONTROLI_H
#include <TextView.h> #include <TextView.h>
@@ -36,7 +37,6 @@ virtual void MakeFocus(bool focusState = true);
virtual BSize MinSize(); virtual BSize MinSize();
void AlignTextRect();
void SetInitialText(); void SetInitialText();
virtual void Paste(BClipboard *clipboard); virtual void Paste(BClipboard *clipboard);
+238 -124
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2015 Haiku, Inc. All rights reserved. * Copyright 2001-2020 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -25,6 +25,7 @@
#include <TextView.h> #include <TextView.h>
#include <algorithm>
#include <new> #include <new>
#include <stdio.h> #include <stdio.h>
@@ -34,6 +35,7 @@
#include <Beep.h> #include <Beep.h>
#include <Bitmap.h> #include <Bitmap.h>
#include <Clipboard.h> #include <Clipboard.h>
#include <ControlLook.h>
#include <Debug.h> #include <Debug.h>
#include <Entry.h> #include <Entry.h>
#include <Input.h> #include <Input.h>
@@ -155,12 +157,17 @@ struct BTextView::LayoutData {
topInset(0), topInset(0),
rightInset(0), rightInset(0),
bottomInset(0), bottomInset(0),
valid(false) valid(false),
overridden(false)
{ {
} }
void UpdateInsets(const BRect& bounds, const BRect& textRect) void UpdateInsets(const BRect& bounds, const BRect& textRect)
{ {
// do not update insets if SetInsets() was called
if (overridden)
return;
// we disallow negative insets, as they would cause parts of the // we disallow negative insets, as they would cause parts of the
// text to be hidden // text to be hidden
leftInset = textRect.left >= bounds.left leftInset = textRect.left >= bounds.left
@@ -184,7 +191,8 @@ struct BTextView::LayoutData {
BSize min; BSize min;
BSize preferred; BSize preferred;
bool valid; bool valid : 1;
bool overridden : 1;
}; };
@@ -260,7 +268,15 @@ BTextView::BTextView(BRect frame, const char* name, BRect textRect,
uint32 resizeMask, uint32 flags) uint32 resizeMask, uint32 flags)
: :
BView(frame, name, resizeMask, BView(frame, name, resizeMask,
flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE) flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE),
fText(NULL),
fLines(NULL),
fStyles(NULL),
fDisallowedChars(NULL),
fUndo(NULL),
fDragRunner(NULL),
fClickRunner(NULL),
fLayoutData(NULL)
{ {
_InitObject(textRect, NULL, NULL); _InitObject(textRect, NULL, NULL);
SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR);
@@ -272,7 +288,15 @@ BTextView::BTextView(BRect frame, const char* name, BRect textRect,
uint32 resizeMask, uint32 flags) uint32 resizeMask, uint32 flags)
: :
BView(frame, name, resizeMask, BView(frame, name, resizeMask,
flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE) flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE),
fText(NULL),
fLines(NULL),
fStyles(NULL),
fDisallowedChars(NULL),
fUndo(NULL),
fDragRunner(NULL),
fClickRunner(NULL),
fLayoutData(NULL)
{ {
_InitObject(textRect, initialFont, initialColor); _InitObject(textRect, initialFont, initialColor);
SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR);
@@ -282,7 +306,15 @@ BTextView::BTextView(BRect frame, const char* name, BRect textRect,
BTextView::BTextView(const char* name, uint32 flags) BTextView::BTextView(const char* name, uint32 flags)
: :
BView(name, BView(name,
flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE) flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE),
fText(NULL),
fLines(NULL),
fStyles(NULL),
fDisallowedChars(NULL),
fUndo(NULL),
fDragRunner(NULL),
fClickRunner(NULL),
fLayoutData(NULL)
{ {
_InitObject(Bounds(), NULL, NULL); _InitObject(Bounds(), NULL, NULL);
SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR);
@@ -293,7 +325,15 @@ BTextView::BTextView(const char* name, const BFont* initialFont,
const rgb_color* initialColor, uint32 flags) const rgb_color* initialColor, uint32 flags)
: :
BView(name, BView(name,
flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE) flags | B_FRAME_EVENTS | B_PULSE_NEEDED | B_INPUT_METHOD_AWARE),
fText(NULL),
fLines(NULL),
fStyles(NULL),
fDisallowedChars(NULL),
fUndo(NULL),
fDragRunner(NULL),
fClickRunner(NULL),
fLayoutData(NULL)
{ {
_InitObject(Bounds(), initialFont, initialColor); _InitObject(Bounds(), initialFont, initialColor);
SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR); SetViewUIColor(B_DOCUMENT_BACKGROUND_COLOR);
@@ -302,7 +342,15 @@ BTextView::BTextView(const char* name, const BFont* initialFont,
BTextView::BTextView(BMessage* archive) BTextView::BTextView(BMessage* archive)
: :
BView(archive) BView(archive),
fText(NULL),
fLines(NULL),
fStyles(NULL),
fDisallowedChars(NULL),
fUndo(NULL),
fDragRunner(NULL),
fClickRunner(NULL),
fLayoutData(NULL)
{ {
CALLED(); CALLED();
BRect rect; BRect rect;
@@ -394,8 +442,8 @@ BTextView::~BTextView()
delete fStyles; delete fStyles;
delete fDisallowedChars; delete fDisallowedChars;
delete fUndo; delete fUndo;
delete fClickRunner;
delete fDragRunner; delete fDragRunner;
delete fClickRunner;
delete fLayoutData; delete fLayoutData;
} }
@@ -1106,7 +1154,6 @@ BTextView::SetText(const char* text, int32 length, const text_run_array* runs)
// recalculate line breaks and draw the text // recalculate line breaks and draw the text
_Refresh(0, length, false); _Refresh(0, length, false);
fCaretOffset = fSelStart = fSelEnd = 0; fCaretOffset = fSelStart = fSelEnd = 0;
ScrollTo(B_ORIGIN);
// draw the caret // draw the caret
_ShowCaret(); _ShowCaret();
@@ -1681,6 +1728,7 @@ BTextView::LineAt(int32 offset) const
int32 lineNum = _LineAt(offset); int32 lineNum = _LineAt(offset);
if (_IsOnEmptyLastLine(offset)) if (_IsOnEmptyLastLine(offset))
lineNum++; lineNum++;
return lineNum; return lineNum;
} }
@@ -1689,7 +1737,7 @@ int32
BTextView::LineAt(BPoint point) const BTextView::LineAt(BPoint point) const
{ {
int32 lineNum = _LineAt(point); int32 lineNum = _LineAt(point);
if ((*fLines)[lineNum + 1]->origin <= point.y - fTextRect.top) if ((*fLines)[lineNum + 1]->origin <= point.y - fAlignedTextRect.top)
lineNum++; lineNum++;
return lineNum; return lineNum;
@@ -1712,7 +1760,7 @@ BTextView::PointAt(int32 offset, float* _height) const
BPoint result; BPoint result;
result.x = 0.0; result.x = 0.0;
result.y = line->origin + fTextRect.top; result.y = line->origin + fAlignedTextRect.top;
bool onEmptyLastLine = _IsOnEmptyLastLine(offset); bool onEmptyLastLine = _IsOnEmptyLastLine(offset);
@@ -1738,14 +1786,14 @@ BTextView::PointAt(int32 offset, float* _height) const
if (fAlignment != B_ALIGN_LEFT) { if (fAlignment != B_ALIGN_LEFT) {
float lineWidth = onEmptyLastLine ? 0.0 : LineWidth(lineNum); float lineWidth = onEmptyLastLine ? 0.0 : LineWidth(lineNum);
float alignmentOffset = fTextRect.Width() - lineWidth; float alignmentOffset = fAlignedTextRect.Width() - lineWidth;
if (fAlignment == B_ALIGN_CENTER) if (fAlignment == B_ALIGN_CENTER)
alignmentOffset /= 2; alignmentOffset = floorf(alignmentOffset / 2);
result.x += alignmentOffset; result.x += alignmentOffset;
} }
// convert from text rect coordinates // convert from text rect coordinates
result.x += fTextRect.left; result.x += fAlignedTextRect.left;
// round up // round up
result.x = lroundf(result.x); result.x = lroundf(result.x);
@@ -1763,9 +1811,9 @@ BTextView::OffsetAt(BPoint point) const
const int32 textLength = fText->Length(); const int32 textLength = fText->Length();
// should we even bother? // should we even bother?
if (point.y >= fTextRect.bottom) if (point.y >= fAlignedTextRect.bottom)
return textLength; return textLength;
else if (point.y < fTextRect.top) else if (point.y < fAlignedTextRect.top)
return 0; return 0;
int32 lineNum = _LineAt(point); int32 lineNum = _LineAt(point);
@@ -1779,21 +1827,22 @@ BTextView::OffsetAt(BPoint point) const
// lower than the bottom of the last line, return the last offset // lower than the bottom of the last line, return the last offset
// (can happen for newlines) // (can happen for newlines)
if (lineNum == (fLines->NumLines() - 1)) { if (lineNum == (fLines->NumLines() - 1)) {
if (point.y >= ((line + 1)->origin + fTextRect.top)) if (point.y >= ((line + 1)->origin + fAlignedTextRect.top))
return textLength; return textLength;
} }
#endif #endif
// convert to text rect coordinates // convert to text rect coordinates
if (fAlignment != B_ALIGN_LEFT) { if (fAlignment != B_ALIGN_LEFT) {
float alignmentOffset = fTextRect.Width() - LineWidth(lineNum); float alignmentOffset = fAlignedTextRect.Width()
- LineWidth(lineNum);
if (fAlignment == B_ALIGN_CENTER) if (fAlignment == B_ALIGN_CENTER)
alignmentOffset /= 2; alignmentOffset = floorf(alignmentOffset / 2);
point.x -= alignmentOffset; point.x -= alignmentOffset;
} }
point.x -= fTextRect.left; point.x -= fAlignedTextRect.left;
point.x = max_c(point.x, 0.0); point.x = std::max(point.x, 0.0f);
// ToDo: The following code isn't very efficient, because it always starts // ToDo: The following code isn't very efficient, because it always starts
// from the left end, so when the point is near the right end it's very // from the left end, so when the point is near the right end it's very
@@ -2020,6 +2069,7 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset,
startOffset = 0; startOffset = 0;
else if (startOffset > fText->Length()) else if (startOffset > fText->Length())
startOffset = fText->Length(); startOffset = fText->Length();
if (endOffset < 0) if (endOffset < 0)
endOffset = 0; endOffset = 0;
else if (endOffset > fText->Length()) else if (endOffset > fText->Length())
@@ -2041,29 +2091,29 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset,
if (startPt.y == endPt.y) { if (startPt.y == endPt.y) {
// this is a one-line region // this is a one-line region
selRect.left = max_c(startPt.x, fTextRect.left); selRect.left = std::max(startPt.x, fAlignedTextRect.left);
selRect.top = startPt.y; selRect.top = startPt.y;
selRect.right = endPt.x - 1.0; selRect.right = endPt.x - 1.0;
selRect.bottom = endPt.y + endLineHeight - 1.0; selRect.bottom = endPt.y + endLineHeight - 1.0;
outRegion->Include(selRect); outRegion->Include(selRect);
} else { } else {
// more than one line in the specified offset range // more than one line in the specified offset range
selRect.left = max_c(startPt.x, fTextRect.left); selRect.left = std::max(startPt.x, fAlignedTextRect.left);
selRect.top = startPt.y; selRect.top = startPt.y;
selRect.right = fTextRect.right; selRect.right = fAlignedTextRect.right;
selRect.bottom = startPt.y + startLineHeight - 1.0; selRect.bottom = startPt.y + startLineHeight - 1.0;
outRegion->Include(selRect); outRegion->Include(selRect);
if (startPt.y + startLineHeight < endPt.y) { if (startPt.y + startLineHeight < endPt.y) {
// more than two lines in the range // more than two lines in the range
selRect.left = fTextRect.left; selRect.left = fAlignedTextRect.left;
selRect.top = startPt.y + startLineHeight; selRect.top = startPt.y + startLineHeight;
selRect.right = fTextRect.right; selRect.right = fAlignedTextRect.right;
selRect.bottom = endPt.y - 1.0; selRect.bottom = endPt.y - 1.0;
outRegion->Include(selRect); outRegion->Include(selRect);
} }
selRect.left = fTextRect.left; selRect.left = fAlignedTextRect.left;
selRect.top = endPt.y; selRect.top = endPt.y;
selRect.right = endPt.x - 1.0; selRect.right = endPt.x - 1.0;
selRect.bottom = endPt.y + endLineHeight - 1.0; selRect.bottom = endPt.y + endLineHeight - 1.0;
@@ -2082,13 +2132,10 @@ BTextView::ScrollToOffset(int32 offset)
BPoint point = PointAt(offset, &lineHeight); BPoint point = PointAt(offset, &lineHeight);
// horizontal // horizontal
float extraSpace = fAlignment == B_ALIGN_LEFT ?
ceilf(bounds.IntegerWidth() / 2) : 0.0;
if (point.x < bounds.left) if (point.x < bounds.left)
xDiff = point.x - bounds.left - extraSpace; xDiff = point.x - bounds.right;
else if (point.x > bounds.right) else if (point.x > bounds.right)
xDiff = point.x - bounds.right + extraSpace; xDiff = point.x - bounds.left;
// vertical // vertical
if (point.y < bounds.top) if (point.y < bounds.top)
@@ -2156,6 +2203,9 @@ BTextView::SetTextRect(BRect rect)
fLayoutData->UpdateInsets(Bounds().OffsetToCopy(B_ORIGIN), rect); fLayoutData->UpdateInsets(Bounds().OffsetToCopy(B_ORIGIN), rect);
fTextRect = rect;
fAlignedTextRect = fTextRect;
_ResetTextRect(); _ResetTextRect();
} }
@@ -2170,21 +2220,21 @@ BTextView::TextRect() const
void void
BTextView::_ResetTextRect() BTextView::_ResetTextRect()
{ {
BRect oldTextRect(fTextRect); BRect oldTextRect(fAlignedTextRect);
// reset text rect to bounds minus insets ... // reset text rect to old text bounds minus insets
fTextRect = Bounds().OffsetToCopy(B_ORIGIN); fAlignedTextRect = fTextRect;
fTextRect.left += fLayoutData->leftInset; fAlignedTextRect.left += fLayoutData->leftInset;
fTextRect.top += fLayoutData->topInset; fAlignedTextRect.top += fLayoutData->topInset;
fTextRect.right -= fLayoutData->rightInset; fAlignedTextRect.right -= fLayoutData->rightInset;
fTextRect.bottom -= fLayoutData->bottomInset; fAlignedTextRect.bottom -= fLayoutData->bottomInset;
// and rewrap (potentially adjusting the right and the bottom of the text // and rewrap (potentially adjusting the right and the bottom of the text
// rect) // rect)
_Refresh(0, TextLength(), false); _Refresh(0, TextLength(), false);
// Make sure that the dirty area outside the text is redrawn too. // Make sure that the dirty area outside the text is redrawn too.
BRegion invalid(oldTextRect | fTextRect); BRegion invalid(oldTextRect | fAlignedTextRect);
invalid.Exclude(fTextRect); invalid.Exclude(fAlignedTextRect);
Invalidate(&invalid); Invalidate(&invalid);
} }
@@ -2203,6 +2253,8 @@ BTextView::SetInsets(float left, float top, float right, float bottom)
fLayoutData->rightInset = right; fLayoutData->rightInset = right;
fLayoutData->bottomInset = bottom; fLayoutData->bottomInset = bottom;
fLayoutData->overridden = true;
InvalidateLayout(); InvalidateLayout();
Invalidate(); Invalidate();
} }
@@ -2324,8 +2376,9 @@ BTextView::SetWordWrap(bool wrap)
fWrap = wrap; fWrap = wrap;
if (wrap) if (wrap)
_ResetTextRect(); _ResetTextRect(); // calls _Refresh
_Refresh(0, fText->Length(), false); else
_Refresh(0, fText->Length(), false);
if (updateOnScreen) { if (updateOnScreen) {
// show the caret, hilite the selection // show the caret, hilite the selection
@@ -2613,15 +2666,15 @@ BTextView::GetHeightForWidth(float width, float* min, float* max,
} }
// TODO: don't change the actual text rect! // TODO: don't change the actual text rect!
fTextRect.right = fTextRect.left + width; fAlignedTextRect.right = fAlignedTextRect.left + width;
_Refresh(0, TextLength(), false); _Refresh(0, TextLength(), false);
if (min != NULL) if (min != NULL)
*min = fTextRect.Height(); *min = fAlignedTextRect.Height();
if (max != NULL) if (max != NULL)
*max = B_SIZE_UNLIMITED; *max = B_SIZE_UNLIMITED;
if (preferred != NULL) if (preferred != NULL)
*preferred = fTextRect.Height(); *preferred = fAlignedTextRect.Height();
} }
@@ -2662,6 +2715,12 @@ BTextView::DoLayout()
if (size.height < fLayoutData->min.height) if (size.height < fLayoutData->min.height)
size.height = fLayoutData->min.height; size.height = fLayoutData->min.height;
// reset insets to 0 unless SetInsets() was called
BRect bounds(Bounds());
fLayoutData->UpdateInsets(Bounds().OffsetToCopy(B_ORIGIN), bounds);
// reset text rect to Bounds()
fTextRect = bounds;
fAlignedTextRect = fTextRect;
_ResetTextRect(); _ResetTextRect();
} }
@@ -2685,7 +2744,7 @@ BTextView::_ValidateLayoutData()
fLayoutData->min = min; fLayoutData->min = min;
// compute our preferred size // compute our preferred size
fLayoutData->preferred.height = fTextRect.Height() fLayoutData->preferred.height = fAlignedTextRect.Height()
+ fLayoutData->topInset + fLayoutData->bottomInset; + fLayoutData->topInset + fLayoutData->bottomInset;
if (fWrap) if (fWrap)
@@ -3094,6 +3153,7 @@ BTextView::_InitObject(BRect textRect, const BFont* initialFont,
// to have less code duplication, and a single place where to do changes // to have less code duplication, and a single place where to do changes
// if needed. // if needed.
fTextRect = textRect; fTextRect = textRect;
fAlignedTextRect = textRect;
// NOTE: The only places where text rect is changed: // NOTE: The only places where text rect is changed:
// * width is possibly adjusted in _AutoResize(), // * width is possibly adjusted in _AutoResize(),
// * height is adjusted in _RecalculateLineBreaks(). // * height is adjusted in _RecalculateLineBreaks().
@@ -3130,7 +3190,7 @@ BTextView::_InitObject(BRect textRect, const BFont* initialFont,
fTrackingMouse = NULL; fTrackingMouse = NULL;
fLayoutData = new LayoutData; fLayoutData = new LayoutData;
fLayoutData->UpdateInsets(Bounds().OffsetToCopy(B_ORIGIN), fTextRect); fLayoutData->UpdateInsets(Bounds().OffsetToCopy(B_ORIGIN), textRect);
fLastClickOffset = -1; fLastClickOffset = -1;
@@ -3319,7 +3379,8 @@ BTextView::_HandleArrowKey(uint32 arrowKey, int32 modifiers)
if (optionKeyDown && !commandKeyDown && !controlKeyDown) if (optionKeyDown && !commandKeyDown && !controlKeyDown)
fCaretOffset = _NextLineEnd(fCaretOffset); fCaretOffset = _NextLineEnd(fCaretOffset);
else if (commandKeyDown && !optionKeyDown && !controlKeyDown) { else if (commandKeyDown && !optionKeyDown && !controlKeyDown) {
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset); _ScrollTo(0, fAlignedTextRect.bottom
+ fLayoutData->bottomInset);
fCaretOffset = fText->Length(); fCaretOffset = fText->Length();
} else { } else {
float height; float height;
@@ -3382,8 +3443,7 @@ BTextView::_HandleDelete(int32 modifiers)
} }
if (fUndo) { if (fUndo) {
TypingUndoBuffer* undoBuffer = dynamic_cast<TypingUndoBuffer*>( TypingUndoBuffer* undoBuffer = dynamic_cast<TypingUndoBuffer*>(fUndo);
fUndo);
if (!undoBuffer) { if (!undoBuffer) {
delete fUndo; delete fUndo;
fUndo = undoBuffer = new TypingUndoBuffer(this); fUndo = undoBuffer = new TypingUndoBuffer(this);
@@ -3465,11 +3525,13 @@ BTextView::_HandlePageKey(uint32 pageKey, int32 modifiers)
case B_END: case B_END:
if (!fEditable) { if (!fEditable) {
fCaretOffset = fText->Length(); fCaretOffset = fText->Length();
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset); _ScrollTo(0, fAlignedTextRect.bottom
+ fLayoutData->bottomInset);
break; break;
} else { } else {
if (commandKeyDown && !optionKeyDown && !controlKeyDown) { if (commandKeyDown && !optionKeyDown && !controlKeyDown) {
_ScrollTo(0, fTextRect.bottom + fLayoutData->bottomInset); _ScrollTo(0, fAlignedTextRect.bottom
+ fLayoutData->bottomInset);
fCaretOffset = fText->Length(); fCaretOffset = fText->Length();
} else { } else {
// If we are on the last line, just go to the last // If we are on the last line, just go to the last
@@ -3622,7 +3684,6 @@ BTextView::_HandleAlphaKey(const char* bytes, int32 numBytes)
_DoInsertText(bytes, numBytes, fSelStart, NULL); _DoInsertText(bytes, numBytes, fSelStart, NULL);
fCaretOffset = fSelEnd; fCaretOffset = fSelEnd;
ScrollToOffset(fCaretOffset); ScrollToOffset(fCaretOffset);
} }
@@ -3638,8 +3699,8 @@ void
BTextView::_Refresh(int32 fromOffset, int32 toOffset, bool scroll) BTextView::_Refresh(int32 fromOffset, int32 toOffset, bool scroll)
{ {
// TODO: Cleanup // TODO: Cleanup
float saveHeight = fTextRect.Height(); float saveHeight = fAlignedTextRect.Height();
float saveWidth = fTextRect.Width(); float saveWidth = fAlignedTextRect.Width();
int32 fromLine = _LineAt(fromOffset); int32 fromLine = _LineAt(fromOffset);
int32 toLine = _LineAt(toOffset); int32 toLine = _LineAt(toOffset);
int32 saveFromLine = fromLine; int32 saveFromLine = fromLine;
@@ -3652,7 +3713,7 @@ BTextView::_Refresh(int32 fromOffset, int32 toOffset, bool scroll)
return; return;
BRect bounds = Bounds(); BRect bounds = Bounds();
float newHeight = fTextRect.Height(); float newHeight = fAlignedTextRect.Height();
// if the line breaks have changed, force an erase // if the line breaks have changed, force an erase
if (fromLine != saveFromLine || toLine != saveToLine if (fromLine != saveFromLine || toLine != saveToLine
@@ -3662,17 +3723,20 @@ BTextView::_Refresh(int32 fromOffset, int32 toOffset, bool scroll)
if (newHeight != saveHeight) { if (newHeight != saveHeight) {
// the text area has changed // the text area has changed
if (newHeight < saveHeight) if (newHeight < saveHeight) {
toLine = _LineAt(BPoint(0.0f, saveHeight + fTextRect.top)); toLine = _LineAt(BPoint(0.0f,
else saveHeight + fAlignedTextRect.top));
toLine = _LineAt(BPoint(0.0f, newHeight + fTextRect.top)); } else {
toLine = _LineAt(BPoint(0.0f,
newHeight + fAlignedTextRect.top));
}
} }
// draw only those lines that are visible // draw only those lines that are visible
int32 fromVisible = _LineAt(BPoint(0.0f, bounds.top)); int32 fromVisible = _LineAt(BPoint(0.0f, bounds.top));
int32 toVisible = _LineAt(BPoint(0.0f, bounds.bottom)); int32 toVisible = _LineAt(BPoint(0.0f, bounds.bottom));
fromLine = max_c(fromVisible, fromLine); fromLine = std::max(fromVisible, fromLine);
toLine = min_c(toLine, toVisible); toLine = std::min(toLine, toVisible);
_AutoResize(false); _AutoResize(false);
@@ -3680,8 +3744,9 @@ BTextView::_Refresh(int32 fromOffset, int32 toOffset, bool scroll)
// erase the area below the text // erase the area below the text
BRect eraseRect = bounds; BRect eraseRect = bounds;
eraseRect.top = fTextRect.top + (*fLines)[fLines->NumLines()]->origin; eraseRect.top = fAlignedTextRect.top
eraseRect.bottom = fTextRect.top + saveHeight; + (*fLines)[fLines->NumLines()]->origin;
eraseRect.bottom = fAlignedTextRect.top + saveHeight;
if (eraseRect.bottom > eraseRect.top && eraseRect.Intersects(bounds)) { if (eraseRect.bottom > eraseRect.top && eraseRect.Intersects(bounds)) {
SetLowColor(ViewColor()); SetLowColor(ViewColor());
FillRect(eraseRect, B_SOLID_LOW); FillRect(eraseRect, B_SOLID_LOW);
@@ -3708,7 +3773,7 @@ BTextView::_RecalculateLineBreaks(int32* startLine, int32* endLine)
{ {
CALLED(); CALLED();
float width = fTextRect.Width(); float width = fAlignedTextRect.Width();
// Don't try to compute anything if the text rect is not set // Don't try to compute anything if the text rect is not set
if (width <= 0) if (width <= 0)
@@ -3780,16 +3845,61 @@ BTextView::_RecalculateLineBreaks(int32* startLine, int32* endLine)
// has always a width of 0 // has always a width of 0
(*fLines)[fLines->NumLines()]->width = 0; (*fLines)[fLines->NumLines()]->width = 0;
// update the text rect // update fAlignedTextRect, leave fTextRect alone
fAlignedTextRect = fTextRect;
// adjust insets
fAlignedTextRect.left += fLayoutData->leftInset;
fAlignedTextRect.top += fLayoutData->topInset;
fAlignedTextRect.right -= fLayoutData->rightInset;
fAlignedTextRect.bottom -= fLayoutData->bottomInset;
// Set new bottom based on text height unless bottom is below
// the bottom of text height already.
float newHeight = TextHeight(0, fLines->NumLines() - 1); float newHeight = TextHeight(0, fLines->NumLines() - 1);
fTextRect.bottom = fTextRect.top + newHeight; fAlignedTextRect.bottom = std::max(fAlignedTextRect.bottom,
fAlignedTextRect.top + newHeight);
bool doPadding = !fLayoutData->overridden && (fEditable || fSelectable);
float hPadding = doPadding ? be_control_look->DefaultLabelSpacing() : 0;
// new min width
if (!fWrap) { if (!fWrap) {
fMinTextRectWidth = fLines->MaxWidth(); fMinTextRectWidth = fLines->MaxWidth();
fTextRect.right = ceilf(fTextRect.left + fMinTextRectWidth);
// expand width if needed (including padding)
switch (fAlignment) {
default:
case B_ALIGN_LEFT:
// grow right
fAlignedTextRect.right = std::max(fAlignedTextRect.right,
fAlignedTextRect.left + hPadding + fMinTextRectWidth);
break;
case B_ALIGN_RIGHT:
// grow left
fAlignedTextRect.left = std::min(fAlignedTextRect.left,
fAlignedTextRect.right - hPadding - fMinTextRectWidth);
break;
case B_ALIGN_CENTER:
// grow out
if (fMinTextRectWidth + hPadding > fAlignedTextRect.Width()) {
fAlignedTextRect.InsetBy(ceilf((fAlignedTextRect.Width()
- hPadding - fMinTextRectWidth) / 2.0f), 0);
}
break;
}
}
if (doPadding) {
float hInset = floorf(hPadding / 2.0f);
float vInset = 1;
fAlignedTextRect.InsetBy(hInset, vInset);
} }
*endLine = lineIndex - 1; *endLine = lineIndex - 1;
*startLine = min_c(*startLine, *endLine); *startLine = std::min(*startLine, *endLine);
} }
@@ -3880,7 +3990,7 @@ BTextView::_FindLineBreak(int32 fromOffset, float* _ascent, float* _descent,
} }
} }
delta = max_c(delta, 1); delta = std::max(delta, (int32)1);
// do not include B_ENTER-terminator into width & height calculations // do not include B_ENTER-terminator into width & height calculations
deltaWidth = _TabExpandedStyledWidth(offset, deltaWidth = _TabExpandedStyledWidth(offset,
@@ -3911,8 +4021,8 @@ BTextView::_FindLineBreak(int32 fromOffset, float* _ascent, float* _descent,
} }
} }
*_ascent = max_c(ascent, *_ascent); *_ascent = std::max(ascent, *_ascent);
*_descent = max_c(descent, *_descent); *_descent = std::max(descent, *_descent);
offset += delta; offset += delta;
delta = 0; delta = 0;
@@ -3935,12 +4045,12 @@ BTextView::_FindLineBreak(int32 fromOffset, float* _ascent, float* _descent,
break; break;
} }
*_ascent = max_c(ascent, *_ascent); *_ascent = std::max(ascent, *_ascent);
*_descent = max_c(descent, *_descent); *_descent = std::max(descent, *_descent);
} }
} }
return min_c(offset, limit); return std::min(offset, limit);
} }
@@ -4137,8 +4247,8 @@ BTextView::_StyledWidth(int32 fromOffset, int32 length, float* _ascent,
int32 numBytes; int32 numBytes;
while ((numBytes = fStyles->Iterate(fromOffset, length, fInline, &font, while ((numBytes = fStyles->Iterate(fromOffset, length, fInline, &font,
NULL, &ascent, &descent)) != 0) { NULL, &ascent, &descent)) != 0) {
maxAscent = max_c(ascent, maxAscent); maxAscent = std::max(ascent, maxAscent);
maxDescent = max_c(descent, maxDescent); maxDescent = std::max(descent, maxDescent);
#if USE_WIDTHBUFFER #if USE_WIDTHBUFFER
// Use _BWidthBuffer_ if possible // Use _BWidthBuffer_ if possible
@@ -4216,19 +4326,20 @@ BTextView::_DrawLine(BView* view, const int32 &lineNum,
BRegion &inputRegion) BRegion &inputRegion)
{ {
STELine* line = (*fLines)[lineNum]; STELine* line = (*fLines)[lineNum];
float startLeft = fTextRect.left; float startLeft = fAlignedTextRect.left;
if (startOffset != -1) { if (startOffset != -1) {
if (ByteAt(startOffset) == B_ENTER) { if (ByteAt(startOffset) == B_ENTER) {
// StartOffset is a newline // StartOffset is a newline
startLeft = PointAt(line->offset).x; startLeft = PointAt(line->offset).x;
} else } else
startLeft = PointAt(startOffset).x; startLeft = PointAt(startOffset).x;
} } else if (fAlignment != B_ALIGN_LEFT) {
else if (fAlignment != B_ALIGN_LEFT) { float alignmentOffset = fAlignedTextRect.Width()
float alignmentOffset = fTextRect.Width() - LineWidth(lineNum); - LineWidth(lineNum);
if (fAlignment == B_ALIGN_CENTER) if (fAlignment == B_ALIGN_CENTER)
alignmentOffset /= 2; alignmentOffset = floorf(alignmentOffset / 2);
startLeft = fTextRect.left + alignmentOffset; startLeft = fAlignedTextRect.left + alignmentOffset;
} }
int32 length = (line + 1)->offset; int32 length = (line + 1)->offset;
@@ -4241,11 +4352,12 @@ BTextView::_DrawLine(BView* view, const int32 &lineNum,
if (ByteAt((line + 1)->offset - 1) == B_ENTER) if (ByteAt((line + 1)->offset - 1) == B_ENTER)
length--; length--;
view->MovePenTo(startLeft, line->origin + line->ascent + fTextRect.top + 1); view->MovePenTo(startLeft,
line->origin + line->ascent + fAlignedTextRect.top + 1);
if (erase) { if (erase) {
eraseRect.top = line->origin + fTextRect.top; eraseRect.top = line->origin + fAlignedTextRect.top;
eraseRect.bottom = (line + 1)->origin + fTextRect.top; eraseRect.bottom = (line + 1)->origin + fAlignedTextRect.top;
view->FillRect(eraseRect, B_SOLID_LOW); view->FillRect(eraseRect, B_SOLID_LOW);
} }
@@ -4267,7 +4379,7 @@ BTextView::_DrawLine(BView* view, const int32 &lineNum,
view->SetFont(font); view->SetFont(font);
view->SetHighColor(*color); view->SetHighColor(*color);
tabChars = min_c(numBytes, length); tabChars = std::min(numBytes, length);
do { do {
foundTab = fText->FindChar(B_TAB, offset, &tabChars); foundTab = fText->FindChar(B_TAB, offset, &tabChars);
if (foundTab) { if (foundTab) {
@@ -4316,11 +4428,12 @@ BTextView::_DrawLine(BView* view, const int32 &lineNum,
} }
int32 returnedBytes = tabChars; int32 returnedBytes = tabChars;
const char* stringToDraw = fText->GetString(offset, &returnedBytes); const char* stringToDraw
= fText->GetString(offset, &returnedBytes);
view->SetDrawingMode(textRenderingMode); view->SetDrawingMode(textRenderingMode);
view->DrawString(stringToDraw, returnedBytes); view->DrawString(stringToDraw, returnedBytes);
if (foundTab) { if (foundTab) {
float penPos = PenLocation().x - fTextRect.left; float penPos = PenLocation().x - fAlignedTextRect.left;
float tabWidth = _ActualTabWidth(penPos); float tabWidth = _ActualTabWidth(penPos);
if (numTabs > 1) if (numTabs > 1)
tabWidth += ((numTabs - 1) * fTabWidth); tabWidth += ((numTabs - 1) * fTabWidth);
@@ -4332,7 +4445,7 @@ BTextView::_DrawLine(BView* view, const int32 &lineNum,
offset += tabChars; offset += tabChars;
length -= tabChars; length -= tabChars;
numBytes -= tabChars; numBytes -= tabChars;
tabChars = min_c(numBytes, length); tabChars = std::min(numBytes, length);
numTabs = 0; numTabs = 0;
} while (foundTab && tabChars > 0); } while (foundTab && tabChars > 0);
} }
@@ -4347,9 +4460,9 @@ BTextView::_DrawLines(int32 startLine, int32 endLine, int32 startOffset,
return; return;
// clip the text // clip the text
BRect textRect(fTextRect); BRect textRect(fAlignedTextRect);
float minWidth float minWidth = Bounds().Width() - fLayoutData->leftInset
= Bounds().Width() - fLayoutData->leftInset - fLayoutData->rightInset; - fLayoutData->rightInset;
if (textRect.Width() < minWidth) if (textRect.Width() < minWidth)
textRect.right = textRect.left + minWidth; textRect.right = textRect.left + minWidth;
BRect clipRect = Bounds() & textRect; BRect clipRect = Bounds() & textRect;
@@ -4395,7 +4508,7 @@ BTextView::_DrawLines(int32 startLine, int32 endLine, int32 startOffset,
BPoint erasePoint = PointAt(startErase); BPoint erasePoint = PointAt(startErase);
eraseRect.left = erasePoint.x; eraseRect.left = erasePoint.x;
eraseRect.top = erasePoint.y; eraseRect.top = erasePoint.y;
eraseRect.bottom = (line + 1)->origin + fTextRect.top; eraseRect.bottom = (line + 1)->origin + fAlignedTextRect.top;
view->FillRect(eraseRect, B_SOLID_LOW); view->FillRect(eraseRect, B_SOLID_LOW);
@@ -4450,9 +4563,10 @@ BTextView::_RequestDrawLines(int32 startLine, int32 endLine)
STELine* from = (*fLines)[startLine]; STELine* from = (*fLines)[startLine];
STELine* to = endLine == maxLine ? NULL : (*fLines)[endLine + 1]; STELine* to = endLine == maxLine ? NULL : (*fLines)[endLine + 1];
BRect invalidRect(Bounds().left, from->origin + fTextRect.top, BRect invalidRect(Bounds().left, from->origin + fAlignedTextRect.top,
Bounds().right, Bounds().right,
to != NULL ? to->origin + fTextRect.top : fTextRect.bottom); to != NULL ? to->origin + fAlignedTextRect.top
: fAlignedTextRect.bottom);
Invalidate(invalidRect); Invalidate(invalidRect);
Window()->UpdateIfNeeded(); Window()->UpdateIfNeeded();
} }
@@ -4463,7 +4577,7 @@ BTextView::_DrawCaret(int32 offset, bool visible)
{ {
float lineHeight; float lineHeight;
BPoint caretPoint = PointAt(offset, &lineHeight); BPoint caretPoint = PointAt(offset, &lineHeight);
caretPoint.x = min_c(caretPoint.x, fTextRect.right); caretPoint.x = std::min(caretPoint.x, fAlignedTextRect.right);
BRect caretRect; BRect caretRect;
caretRect.left = caretRect.right = caretPoint.x; caretRect.left = caretRect.right = caretPoint.x;
@@ -4794,15 +4908,15 @@ BTextView::_PerformAutoScrolling()
// R5 does a pretty soft auto-scroll, we try to do the same by // R5 does a pretty soft auto-scroll, we try to do the same by
// simply scrolling the distance between cursor and border // simply scrolling the distance between cursor and border
if (fWhere.x > bounds.right) { if (fWhere.x > bounds.right)
scrollBy.x = fWhere.x - bounds.right; scrollBy.x = fWhere.x - bounds.right;
} else if (fWhere.x < bounds.left) { else if (fWhere.x < bounds.left)
scrollBy.x = fWhere.x - bounds.left; // negative value scrollBy.x = fWhere.x - bounds.left; // negative value
}
// prevent from scrolling out of view // prevent from scrolling out of view
if (scrollBy.x != 0.0) { if (scrollBy.x != 0.0) {
float rightMax = floorf(fTextRect.right + fLayoutData->rightInset); float rightMax = floorf(fAlignedTextRect.right
+ fLayoutData->rightInset);
if (bounds.right + scrollBy.x > rightMax) if (bounds.right + scrollBy.x > rightMax)
scrollBy.x = rightMax - bounds.right; scrollBy.x = rightMax - bounds.right;
if (bounds.left + scrollBy.x < 0) if (bounds.left + scrollBy.x < 0)
@@ -4811,15 +4925,14 @@ BTextView::_PerformAutoScrolling()
if (CountLines() > 1) { if (CountLines() > 1) {
// scroll in Y only if multiple lines! // scroll in Y only if multiple lines!
if (fWhere.y > bounds.bottom) { if (fWhere.y > bounds.bottom)
scrollBy.y = fWhere.y - bounds.bottom; scrollBy.y = fWhere.y - bounds.bottom;
} else if (fWhere.y < bounds.top) { else if (fWhere.y < bounds.top)
scrollBy.y = fWhere.y - bounds.top; // negative value scrollBy.y = fWhere.y - bounds.top; // negative value
}
// prevent from scrolling out of view // prevent from scrolling out of view
if (scrollBy.y != 0.0) { if (scrollBy.y != 0.0) {
float bottomMax = floorf(fTextRect.bottom float bottomMax = floorf(fAlignedTextRect.bottom
+ fLayoutData->bottomInset); + fLayoutData->bottomInset);
if (bounds.bottom + scrollBy.y > bottomMax) if (bounds.bottom + scrollBy.y > bottomMax)
scrollBy.y = bottomMax - bounds.bottom; scrollBy.y = bottomMax - bounds.bottom;
@@ -4844,11 +4957,11 @@ BTextView::_UpdateScrollbars()
// do we have a horizontal scroll bar? // do we have a horizontal scroll bar?
if (horizontalScrollBar != NULL) { if (horizontalScrollBar != NULL) {
long viewWidth = bounds.IntegerWidth(); long viewWidth = bounds.IntegerWidth();
long dataWidth = (long)ceilf(fTextRect.IntegerWidth() long dataWidth = (long)ceilf(fAlignedTextRect.IntegerWidth()
+ fLayoutData->leftInset + fLayoutData->rightInset); + fLayoutData->leftInset + fLayoutData->rightInset);
long maxRange = dataWidth - viewWidth; long maxRange = dataWidth - viewWidth;
maxRange = max_c(maxRange, 0); maxRange = std::max(maxRange, 0l);
horizontalScrollBar->SetRange(0, (float)maxRange); horizontalScrollBar->SetRange(0, (float)maxRange);
horizontalScrollBar->SetProportion((float)viewWidth / (float)dataWidth); horizontalScrollBar->SetProportion((float)viewWidth / (float)dataWidth);
@@ -4858,11 +4971,11 @@ BTextView::_UpdateScrollbars()
// how about a vertical scroll bar? // how about a vertical scroll bar?
if (verticalScrollBar != NULL) { if (verticalScrollBar != NULL) {
long viewHeight = bounds.IntegerHeight(); long viewHeight = bounds.IntegerHeight();
long dataHeight = (long)ceilf(fTextRect.IntegerHeight() long dataHeight = (long)ceilf(fLayoutData->topInset
+ fLayoutData->topInset + fLayoutData->bottomInset); + fAlignedTextRect.IntegerHeight() + fLayoutData->bottomInset);
long maxRange = dataHeight - viewHeight; long maxRange = dataHeight - viewHeight;
maxRange = max_c(maxRange, 0); maxRange = std::max(maxRange, 0L);
verticalScrollBar->SetRange(0, maxRange); verticalScrollBar->SetRange(0, maxRange);
verticalScrollBar->SetProportion((float)viewHeight / (float)dataHeight); verticalScrollBar->SetProportion((float)viewHeight / (float)dataHeight);
@@ -4888,13 +5001,13 @@ BTextView::_ScrollTo(float x, float y)
long viewWidth = bounds.IntegerWidth(); long viewWidth = bounds.IntegerWidth();
long viewHeight = bounds.IntegerHeight(); long viewHeight = bounds.IntegerHeight();
if (x > fTextRect.right - viewWidth) if (x > fAlignedTextRect.right - viewWidth)
x = fTextRect.right - viewWidth; x = fAlignedTextRect.right - viewWidth;
if (x < 0.0) if (x < 0.0)
x = 0.0; x = 0.0;
if (y > fTextRect.bottom + fLayoutData->bottomInset - viewHeight) if (y > fAlignedTextRect.bottom + fLayoutData->bottomInset - viewHeight)
y = fTextRect.bottom + fLayoutData->bottomInset - viewHeight; y = fAlignedTextRect.bottom + fLayoutData->bottomInset - viewHeight;
if (y < 0.0) if (y < 0.0)
y = 0.0; y = 0.0;
@@ -4910,13 +5023,13 @@ BTextView::_AutoResize(bool redraw)
return; return;
BRect bounds = Bounds(); BRect bounds = Bounds();
float oldWidth = bounds.Width();
float newWidth = ceilf(fLayoutData->leftInset + fTextRect.Width()
+ fLayoutData->rightInset);
if (fContainerView != NULL) { if (fContainerView != NULL) {
// NOTE: This container view thing is only used by Tracker. // NOTE: This container view thing is only used by Tracker.
// move container view if not left aligned // move container view if not left aligned
float oldWidth = bounds.Width();
float newWidth = ceilf(fLayoutData->leftInset
+ fAlignedTextRect.Width() + fLayoutData->rightInset);
if (fAlignment == B_ALIGN_CENTER) { if (fAlignment == B_ALIGN_CENTER) {
if (fmod(ceilf(newWidth - oldWidth), 2.0) != 0.0) if (fmod(ceilf(newWidth - oldWidth), 2.0) != 0.0)
newWidth += 1; newWidth += 1;
@@ -4934,8 +5047,8 @@ BTextView::_AutoResize(bool redraw)
// erase any potential left over outside the text rect // erase any potential left over outside the text rect
// (can only be on right hand side) // (can only be on right hand side)
BRect dirty(fTextRect.right + 1, fTextRect.top, bounds.right, BRect dirty(fAlignedTextRect.right + 1, fAlignedTextRect.top,
fTextRect.bottom); bounds.right, fAlignedTextRect.bottom);
if (dirty.IsValid()) { if (dirty.IsValid()) {
SetLowColor(ViewColor()); SetLowColor(ViewColor());
FillRect(dirty, B_SOLID_LOW); FillRect(dirty, B_SOLID_LOW);
@@ -4951,8 +5064,9 @@ BTextView::_NewOffscreen(float padding)
_DeleteOffscreen(); _DeleteOffscreen();
#if USE_DOUBLEBUFFERING #if USE_DOUBLEBUFFERING
BRect bitmapRect(0, 0, fTextRect.Width() + padding, fTextRect.Height()); BRect bitmapRect(0, 0, fAlignedTextRect.Width() + padding,
fOffscreen = new BBitmap(bitmapRect, fColorSpace, true, false); fAlignedTextRect.Height());
fOffscreen = new BBitmap(bitm->Rect, fColorSpace, true, false);
if (fOffscreen != NULL && fOffscreen->Lock()) { if (fOffscreen != NULL && fOffscreen->Lock()) {
BView* bufferView = new BView(bitmapRect, "drawing view", 0, 0); BView* bufferView = new BView(bitmapRect, "drawing view", 0, 0);
fOffscreen->AddChild(bufferView); fOffscreen->AddChild(bufferView);
@@ -5666,7 +5780,7 @@ BTextView::_LineAt(int32 offset) const
int32 int32
BTextView::_LineAt(const BPoint& point) const BTextView::_LineAt(const BPoint& point) const
{ {
return fLines->PixelToLine(point.y - fTextRect.top); return fLines->PixelToLine(point.y - fAlignedTextRect.top);
} }
+1
View File
@@ -379,6 +379,7 @@ BTextWidget::StartEdit(BRect bounds, BPoseView* view, BPose* pose)
textView->SetWordWrap(false); textView->SetWordWrap(false);
DisallowMetaKeys(textView); DisallowMetaKeys(textView);
textView->SetInsets(0, 0, 0, 0);
fText->SetUpEditing(textView); fText->SetUpEditing(textView);
textView->AddFilter(new BMessageFilter(B_KEY_DOWN, TextViewFilter)); textView->AddFilter(new BMessageFilter(B_KEY_DOWN, TextViewFilter));
@@ -302,7 +302,6 @@ HeaderView::Draw(BRect)
// Font information // Font information
font_height fontMetrics; font_height fontMetrics;
BFont currentFont; BFont currentFont;
float lineHeight = 0;
float lineBase = 0; float lineBase = 0;
// Draw the main title if the user is not currently editing it // Draw the main title if the user is not currently editing it
@@ -311,7 +310,6 @@ HeaderView::Draw(BRect)
SetFontSize(be_bold_font->Size()); SetFontSize(be_bold_font->Size());
GetFont(&currentFont); GetFont(&currentFont);
currentFont.GetHeight(&fontMetrics); currentFont.GetHeight(&fontMetrics);
lineHeight = CurrentFontHeight() + 5;
lineBase = fTitleRect.bottom - fontMetrics.descent; lineBase = fTitleRect.bottom - fontMetrics.descent;
SetHighColor(labelColor); SetHighColor(labelColor);
MovePenTo(BPoint(fIconRect.right + 6, lineBase)); MovePenTo(BPoint(fIconRect.right + 6, lineBase));
@@ -146,6 +146,7 @@ PreviewView::AddPreview()
fNoPreview->SetExplicitSize(BSize(previewWidth, previewHeight)); fNoPreview->SetExplicitSize(BSize(previewWidth, previewHeight));
fNoPreview->ResizeTo(previewWidth, previewHeight); fNoPreview->ResizeTo(previewWidth, previewHeight);
fNoPreview->SetTextRect(BRect(0, 0, previewWidth, previewHeight));
fNoPreview->SetInsets(0, previewHeight / 3, 0 , 0); fNoPreview->SetInsets(0, previewHeight / 3, 0 , 0);
return fSaverView; return fSaverView;