* Added optional tracing to ScrollBar.cpp.

* Fixed line breaks to not exceed 80 char limit.
* Removed any trailing spaces.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24836 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-04-06 16:22:10 +00:00
parent 49df4099d1
commit c2234e0598

View File

@ -21,7 +21,13 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
//#define TEST_MODE //#define TRACE_SCROLLBAR
#ifdef TRACE_SCROLLBAR
# define TRACE(x...) printf(x)
#else
# define TRACE(x...)
#endif
typedef enum { typedef enum {
ARROW_LEFT = 0, ARROW_LEFT = 0,
@ -38,7 +44,7 @@ typedef enum {
// Quick constants for determining which arrow is down and are defined with respect // Quick constants for determining which arrow is down and are defined with respect
// to double arrow mode. ARROW1 and ARROW4 refer to the outer pair of arrows and // to double arrow mode. ARROW1 and ARROW4 refer to the outer pair of arrows and
// ARROW2 and ARROW3 refer to the inner ones. ARROW1 points left/up and ARROW4 // ARROW2 and ARROW3 refer to the inner ones. ARROW1 points left/up and ARROW4
// points right/down. // points right/down.
#define ARROW1 0 #define ARROW1 0
#define ARROW2 1 #define ARROW2 1
@ -64,7 +70,7 @@ public:
fStopValue(0.0), fStopValue(0.0),
fUpArrowsEnabled(true), fUpArrowsEnabled(true),
fDownArrowsEnabled(true), fDownArrowsEnabled(true),
fButtonDown(NOARROW) fButtonDown(NOARROW)
{ {
#ifdef TEST_MODE #ifdef TEST_MODE
fScrollBarInfo.proportional = true; fScrollBarInfo.proportional = true;
@ -75,7 +81,7 @@ public:
get_scroll_bar_info(&fScrollBarInfo); get_scroll_bar_info(&fScrollBarInfo);
#endif #endif
} }
~Private() ~Private()
{ {
if (fRepeaterThread >= 0) { if (fRepeaterThread >= 0) {
@ -84,18 +90,18 @@ public:
wait_for_thread(fRepeaterThread, &dummy); wait_for_thread(fRepeaterThread, &dummy);
} }
} }
void DrawScrollBarButton(BScrollBar *owner, arrow_direction direction, void DrawScrollBarButton(BScrollBar *owner, arrow_direction direction,
BRect frame, bool down = false); BRect frame, bool down = false);
static int32 button_repeater_thread(void* data); static int32 button_repeater_thread(void* data);
int32 ButtonRepeaterThread(); int32 ButtonRepeaterThread();
BScrollBar* fScrollBar; BScrollBar* fScrollBar;
bool fEnabled; bool fEnabled;
// TODO: This should be a static, initialized by // TODO: This should be a static, initialized by
// _init_interface_kit() at application startup-time, // _init_interface_kit() at application startup-time,
// like BMenu::sMenuInfo // like BMenu::sMenuInfo
scroll_bar_info fScrollBarInfo; scroll_bar_info fScrollBarInfo;
@ -159,7 +165,7 @@ BScrollBar::Private::ButtonRepeaterThread()
fRepeaterThread = -1; fRepeaterThread = -1;
fScrollBar->UnlockLooper(); fScrollBar->UnlockLooper();
} }
return 0; return 0;
} }
@ -279,32 +285,32 @@ BScrollBar::AttachedToWindow()
/* /*
From the BeBook (on ValueChanged()): From the BeBook (on ValueChanged()):
Responds to a notification that the value of the scroll bar has changed to
newValue. For a horizontal scroll bar, this function interprets newValue
as the coordinate value that should be at the left side of the target
view's bounds rectangle. For a vertical scroll bar, it interprets
newValue as the coordinate value that should be at the top of the rectangle.
It calls ScrollTo() to scroll the target's contents into position, unless
they have already been scrolled.
ValueChanged() is called as the result both of user actions Responds to a notification that the value of the scroll bar has changed to
(B_VALUE_CHANGED messages received from the Application Server) and of newValue. For a horizontal scroll bar, this function interprets newValue
programmatic ones. Programmatically, scrolling can be initiated by the as the coordinate value that should be at the left side of the target
target view (calling ScrollTo()) or by the BScrollBar view's bounds rectangle. For a vertical scroll bar, it interprets
(calling SetValue() or SetRange()). newValue as the coordinate value that should be at the top of the rectangle.
It calls ScrollTo() to scroll the target's contents into position, unless
they have already been scrolled.
In all these cases, the target view and the scroll bars need to be kept ValueChanged() is called as the result both of user actions
in synch. This is done by a chain of function calls: ValueChanged() calls (B_VALUE_CHANGED messages received from the Application Server) and of
ScrollTo(), which in turn calls SetValue(), which then calls programmatic ones. Programmatically, scrolling can be initiated by the
ValueChanged() again. It's up to ValueChanged() to get off this target view (calling ScrollTo()) or by the BScrollBar
merry-go-round, which it does by checking the target view's bounds (calling SetValue() or SetRange()).
rectangle. If newValue already matches the left or top side of the
bounds rectangle, if forgoes calling ScrollTo().
ValueChanged() does nothing if a target BView hasn't been setor In all these cases, the target view and the scroll bars need to be kept
if the target has been set by name, but the name doesn't correspond to in synch. This is done by a chain of function calls: ValueChanged() calls
an actual BView within the scroll bar's window. ScrollTo(), which in turn calls SetValue(), which then calls
ValueChanged() again. It's up to ValueChanged() to get off this
merry-go-round, which it does by checking the target view's bounds
rectangle. If newValue already matches the left or top side of the
bounds rectangle, if forgoes calling ScrollTo().
ValueChanged() does nothing if a target BView hasn't been setor
if the target has been set by name, but the name doesn't correspond to
an actual BView within the scroll bar's window.
*/ */
@ -312,6 +318,8 @@ an actual BView within the scroll bar's window.
void void
BScrollBar::SetValue(float value) BScrollBar::SetValue(float value)
{ {
TRACE("BScrollBar(%s)::SetValue(%.1f)\n", Name(), value);
if (value > fMax) if (value > fMax)
value = fMax; value = fMax;
else if (value < fMin) else if (value < fMin)
@ -341,6 +349,8 @@ BScrollBar::Value() const
void void
BScrollBar::ValueChanged(float newValue) BScrollBar::ValueChanged(float newValue)
{ {
TRACE("BScrollBar(%s)::ValueChanged(%.1f)\n", Name(), newValue);
if (fTarget) { if (fTarget) {
// cache target bounds // cache target bounds
BRect targetBounds = fTarget->Bounds(); BRect targetBounds = fTarget->Bounds();
@ -354,6 +364,8 @@ BScrollBar::ValueChanged(float newValue)
} }
} }
TRACE(" -> %.1f\n", newValue);
SetValue(newValue); SetValue(newValue);
} }
@ -361,6 +373,8 @@ BScrollBar::ValueChanged(float newValue)
void void
BScrollBar::SetProportion(float value) BScrollBar::SetProportion(float value)
{ {
TRACE("BScrollBar(%s)::SetProportion(%.1f)\n", Name(), value);
if (value < 0.0) if (value < 0.0)
value = 0.0; value = 0.0;
if (value > 1.0) if (value > 1.0)
@ -374,7 +388,7 @@ BScrollBar::SetProportion(float value)
bool newEnabled = fPrivateData->fEnabled && fMin < fMax bool newEnabled = fPrivateData->fEnabled && fMin < fMax
&& fProportion < 1.0 && fProportion >= 0.0; && fProportion < 1.0 && fProportion >= 0.0;
_UpdateThumbFrame(); _UpdateThumbFrame();
if (oldEnabled != newEnabled) if (oldEnabled != newEnabled)
@ -393,6 +407,8 @@ BScrollBar::Proportion() const
void void
BScrollBar::SetRange(float min, float max) BScrollBar::SetRange(float min, float max)
{ {
TRACE("BScrollBar(%s)::SetRange(min=%.1f, max=%.1f)\n", Name(), min, max);
if (min > max || isnanf(min) || isnanf(max) || isinff(min) || isinff(max)) { if (min > max || isnanf(min) || isnanf(max) || isinff(min) || isinff(max)) {
min = 0; min = 0;
max = 0; max = 0;
@ -431,7 +447,7 @@ BScrollBar::SetSteps(float smallStep, float largeStep)
{ {
// Under R5, steps can be set only after being attached to a window, probably because // Under R5, steps can be set only after being attached to a window, probably because
// the data is kept server-side. We'll just remove that limitation... :P // the data is kept server-side. We'll just remove that limitation... :P
// The BeBook also says that we need to specify an integer value even though the step // The BeBook also says that we need to specify an integer value even though the step
// values are floats. For the moment, we'll just make sure that they are integers // values are floats. For the moment, we'll just make sure that they are integers
fSmallStep = roundf(smallStep); fSmallStep = roundf(smallStep);
@ -456,10 +472,10 @@ BScrollBar::SetTarget(BView *target)
{ {
fTarget = target; fTarget = target;
free(fTargetName); free(fTargetName);
if (fTarget) { if (fTarget) {
fTargetName = strdup(target->Name()); fTargetName = strdup(target->Name());
if (fOrientation == B_VERTICAL) if (fOrientation == B_VERTICAL)
fTarget->fVerScroller = this; fTarget->fVerScroller = this;
else else
@ -474,10 +490,10 @@ BScrollBar::SetTarget(const char *targetName)
{ {
if (!targetName) if (!targetName)
return; return;
if (!Window()) if (!Window())
debugger("Method requires window and doesn't have one"); debugger("Method requires window and doesn't have one");
BView *target = Window()->FindView(targetName); BView *target = Window()->FindView(targetName);
if (target) if (target)
SetTarget(target); SetTarget(target);
@ -682,7 +698,7 @@ BScrollBar::Draw(BRect updateRect)
dark2 = tint_color(normal, B_LIGHTEN_1_TINT); dark2 = tint_color(normal, B_LIGHTEN_1_TINT);
dark4 = tint_color(normal, B_DARKEN_3_TINT); dark4 = tint_color(normal, B_DARKEN_3_TINT);
} }
SetDrawingMode(B_OP_OVER); SetDrawingMode(B_OP_OVER);
BRect thumbBG = bounds; BRect thumbBG = bounds;
@ -690,7 +706,8 @@ BScrollBar::Draw(BRect updateRect)
// Draw arrows // Draw arrows
if (fOrientation == B_HORIZONTAL) { if (fOrientation == B_HORIZONTAL) {
BRect buttonFrame(bounds.left, bounds.top, bounds.left + bounds.Height(), bounds.bottom); BRect buttonFrame(bounds.left, bounds.top,
bounds.left + bounds.Height(), bounds.bottom);
_DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW1); enabled, fPrivateData->fButtonDown == ARROW1);
@ -703,7 +720,7 @@ BScrollBar::Draw(BRect updateRect)
buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top); buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), bounds.top);
_DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW3); enabled, fPrivateData->fButtonDown == ARROW3);
thumbBG.left += bounds.Height() * 2 + 2; thumbBG.left += bounds.Height() * 2 + 2;
thumbBG.right -= bounds.Height() * 2 + 2; thumbBG.right -= bounds.Height() * 2 + 2;
} else { } else {
@ -715,20 +732,22 @@ BScrollBar::Draw(BRect updateRect)
_DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW4); enabled, fPrivateData->fButtonDown == ARROW4);
} else { } else {
BRect buttonFrame(bounds.left, bounds.top, bounds.right, bounds.top + bounds.Width()); BRect buttonFrame(bounds.left, bounds.top, bounds.right,
bounds.top + bounds.Width());
_DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW1); enabled, fPrivateData->fButtonDown == ARROW1);
if (doubleArrows) { if (doubleArrows) {
buttonFrame.OffsetBy(0.0, bounds.Width() + 1); buttonFrame.OffsetBy(0.0, bounds.Width() + 1);
_DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW2); enabled, fPrivateData->fButtonDown == ARROW2);
buttonFrame.OffsetTo(bounds.left, bounds.bottom - ((bounds.Width() * 2) + 1)); buttonFrame.OffsetTo(bounds.left, bounds.bottom
- ((bounds.Width() * 2) + 1));
_DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect, _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect,
enabled, fPrivateData->fButtonDown == ARROW3); enabled, fPrivateData->fButtonDown == ARROW3);
thumbBG.top += bounds.Width() * 2 + 2; thumbBG.top += bounds.Width() * 2 + 2;
thumbBG.bottom -= bounds.Width() * 2 + 2; thumbBG.bottom -= bounds.Width() * 2 + 2;
} else { } else {
@ -773,7 +792,7 @@ BScrollBar::Draw(BRect updateRect)
AddLine(BPoint(rect.left - 1, thumbBG.bottom), AddLine(BPoint(rect.left - 1, thumbBG.bottom),
BPoint(thumbBG.left + 2, thumbBG.bottom), normal); BPoint(thumbBG.left + 2, thumbBG.bottom), normal);
} }
if (rect.right < thumbBG.right - 1) { if (rect.right < thumbBG.right - 1) {
AddLine(BPoint(rect.right + 2, thumbBG.top + 1), AddLine(BPoint(rect.right + 2, thumbBG.top + 1),
BPoint(rect.right + 2, thumbBG.bottom), dark2); BPoint(rect.right + 2, thumbBG.bottom), dark2);
@ -814,7 +833,7 @@ BScrollBar::Draw(BRect updateRect)
AddLine(BPoint(thumbBG.right, rect.top - 1), AddLine(BPoint(thumbBG.right, rect.top - 1),
BPoint(thumbBG.right, thumbBG.top + 2), normal); BPoint(thumbBG.right, thumbBG.top + 2), normal);
} }
if (rect.bottom < thumbBG.bottom - 1) { if (rect.bottom < thumbBG.bottom - 1) {
AddLine(BPoint(thumbBG.left + 1, rect.bottom + 2), AddLine(BPoint(thumbBG.left + 1, rect.bottom + 2),
BPoint(thumbBG.right, rect.bottom + 2), dark2); BPoint(thumbBG.right, rect.bottom + 2), dark2);
@ -841,7 +860,7 @@ BScrollBar::Draw(BRect updateRect)
BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, thumbBG.bottom); BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, thumbBG.bottom);
if (leftOfThumb.IsValid()) if (leftOfThumb.IsValid())
FillRect(leftOfThumb); FillRect(leftOfThumb);
BRect rightOfThumb(rect.right + 3, thumbBG.top, thumbBG.right, thumbBG.bottom); BRect rightOfThumb(rect.right + 3, thumbBG.top, thumbBG.right, thumbBG.bottom);
if (rightOfThumb.IsValid()) if (rightOfThumb.IsValid())
FillRect(rightOfThumb); FillRect(rightOfThumb);
@ -849,29 +868,35 @@ BScrollBar::Draw(BRect updateRect)
// dark lines before and after thumb // dark lines before and after thumb
if (rect.left > thumbBG.left) { if (rect.left > thumbBG.left) {
SetHighColor(dark); SetHighColor(dark);
StrokeLine(BPoint(rect.left - 1, rect.top), BPoint(rect.left - 1, rect.bottom)); StrokeLine(BPoint(rect.left - 1, rect.top),
BPoint(rect.left - 1, rect.bottom));
} }
if (rect.right < thumbBG.right) { if (rect.right < thumbBG.right) {
SetHighColor(dark4); SetHighColor(dark4);
StrokeLine(BPoint(rect.right + 1, rect.top), BPoint(rect.right + 1, rect.bottom)); StrokeLine(BPoint(rect.right + 1, rect.top),
BPoint(rect.right + 1, rect.bottom));
} }
} else { } else {
BRect topOfThumb(thumbBG.left, thumbBG.top + 1, thumbBG.right, rect.top - 1); BRect topOfThumb(thumbBG.left, thumbBG.top + 1,
thumbBG.right, rect.top - 1);
if (topOfThumb.IsValid()) if (topOfThumb.IsValid())
FillRect(topOfThumb); FillRect(topOfThumb);
BRect bottomOfThumb(thumbBG.left, rect.bottom + 3, thumbBG.right, thumbBG.bottom); BRect bottomOfThumb(thumbBG.left, rect.bottom + 3,
thumbBG.right, thumbBG.bottom);
if (bottomOfThumb.IsValid()) if (bottomOfThumb.IsValid())
FillRect(bottomOfThumb); FillRect(bottomOfThumb);
// dark lines before and after thumb // dark lines before and after thumb
if (rect.top > thumbBG.top) { if (rect.top > thumbBG.top) {
SetHighColor(dark); SetHighColor(dark);
StrokeLine(BPoint(rect.left, rect.top - 1), BPoint(rect.right, rect.top - 1)); StrokeLine(BPoint(rect.left, rect.top - 1),
BPoint(rect.right, rect.top - 1));
} }
if (rect.bottom < thumbBG.bottom) { if (rect.bottom < thumbBG.bottom) {
SetHighColor(dark4); SetHighColor(dark4);
StrokeLine(BPoint(rect.left, rect.bottom + 1), BPoint(rect.right, rect.bottom + 1)); StrokeLine(BPoint(rect.left, rect.bottom + 1),
BPoint(rect.right, rect.bottom + 1));
} }
} }
@ -892,7 +917,7 @@ BScrollBar::Draw(BRect updateRect)
SetHighColor(tint_color(normal, (B_NO_TINT + B_DARKEN_1_TINT) / 2)); SetHighColor(tint_color(normal, (B_NO_TINT + B_DARKEN_1_TINT) / 2));
else*/ else*/
SetHighColor(normal); SetHighColor(normal);
FillRect(rect); FillRect(rect);
// TODO: Add the other thumb styles - dots and lines // TODO: Add the other thumb styles - dots and lines
@ -1286,10 +1311,13 @@ BScrollBar::_ButtonRectFor(int32 button) const
void void
BScrollBar::_UpdateTargetValue(BPoint where) BScrollBar::_UpdateTargetValue(BPoint where)
{ {
if (fOrientation == B_VERTICAL) if (fOrientation == B_VERTICAL) {
fPrivateData->fStopValue = _ValueFor(BPoint(where.x, where.y - fPrivateData->fThumbFrame.Height() / 2.0)); fPrivateData->fStopValue = _ValueFor(BPoint(where.x, where.y
else - fPrivateData->fThumbFrame.Height() / 2.0));
fPrivateData->fStopValue = _ValueFor(BPoint(where.x - fPrivateData->fThumbFrame.Width() / 2.0, where.y)); } else {
fPrivateData->fStopValue = _ValueFor(BPoint(where.x
- fPrivateData->fThumbFrame.Width() / 2.0, where.y));
}
} }
// _UpdateArrowButtons // _UpdateArrowButtons
@ -1322,9 +1350,9 @@ control_scrollbar(scroll_bar_info *info, BScrollBar *bar)
if (bar->fPrivateData->fScrollBarInfo.double_arrows != info->double_arrows) { if (bar->fPrivateData->fScrollBarInfo.double_arrows != info->double_arrows) {
bar->fPrivateData->fScrollBarInfo.double_arrows = info->double_arrows; bar->fPrivateData->fScrollBarInfo.double_arrows = info->double_arrows;
int8 multiplier = (info->double_arrows) ? 1 : -1; int8 multiplier = (info->double_arrows) ? 1 : -1;
if (bar->fOrientation == B_VERTICAL) if (bar->fOrientation == B_VERTICAL)
bar->fPrivateData->fThumbFrame.OffsetBy(0, multiplier * B_H_SCROLL_BAR_HEIGHT); bar->fPrivateData->fThumbFrame.OffsetBy(0, multiplier * B_H_SCROLL_BAR_HEIGHT);
else else
@ -1334,15 +1362,16 @@ control_scrollbar(scroll_bar_info *info, BScrollBar *bar)
bar->fPrivateData->fScrollBarInfo.proportional = info->proportional; bar->fPrivateData->fScrollBarInfo.proportional = info->proportional;
// TODO: Figure out how proportional relates to the size of the thumb // TODO: Figure out how proportional relates to the size of the thumb
// TODO: Add redraw code to reflect the changes // TODO: Add redraw code to reflect the changes
if (info->knob >= 0 && info->knob <= 2) if (info->knob >= 0 && info->knob <= 2)
bar->fPrivateData->fScrollBarInfo.knob = info->knob; bar->fPrivateData->fScrollBarInfo.knob = info->knob;
else else
return B_BAD_VALUE; return B_BAD_VALUE;
if (info->min_knob_size >= SCROLL_BAR_MINIMUM_KNOB_SIZE && info->min_knob_size <= SCROLL_BAR_MAXIMUM_KNOB_SIZE) if (info->min_knob_size >= SCROLL_BAR_MINIMUM_KNOB_SIZE
&& info->min_knob_size <= SCROLL_BAR_MAXIMUM_KNOB_SIZE)
bar->fPrivateData->fScrollBarInfo.min_knob_size = info->min_knob_size; bar->fPrivateData->fScrollBarInfo.min_knob_size = info->min_knob_size;
else else
return B_BAD_VALUE; return B_BAD_VALUE;
@ -1428,14 +1457,14 @@ BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r,
rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color c = ui_color(B_PANEL_BACKGROUND_COLOR);
rgb_color light, dark, darker, normal, arrow; rgb_color light, dark, darker, normal, arrow;
if (down && fPrivateData->fDoRepeat) { if (down && fPrivateData->fDoRepeat) {
light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0); light = tint_color(c, (B_DARKEN_1_TINT + B_DARKEN_2_TINT) / 2.0);
dark = darker = c; dark = darker = c;
normal = tint_color(c, B_DARKEN_1_TINT); normal = tint_color(c, B_DARKEN_1_TINT);
arrow = tint_color(c, B_DARKEN_MAX_TINT); arrow = tint_color(c, B_DARKEN_MAX_TINT);
} else { } else {
// Add a usability perk - disable buttons if they would not do anything - // Add a usability perk - disable buttons if they would not do anything -
// like a left arrow if the value==fMin // like a left arrow if the value==fMin
// NOTE: disabled because of too much visual noise/distraction // NOTE: disabled because of too much visual noise/distraction
/* if ((direction == ARROW_LEFT || direction == ARROW_UP) && (fValue == fMin) ) /* if ((direction == ARROW_LEFT || direction == ARROW_UP) && (fValue == fMin) )
@ -1457,10 +1486,10 @@ BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r,
arrow = tint_color(c, B_DARKEN_1_TINT); arrow = tint_color(c, B_DARKEN_1_TINT);
} }
} }
BPoint tri1, tri2, tri3; BPoint tri1, tri2, tri3;
r.InsetBy(4, 4); r.InsetBy(4, 4);
switch (direction) { switch (direction) {
case ARROW_LEFT: case ARROW_LEFT:
tri1.Set(r.right, r.top); tri1.Set(r.right, r.top);
@ -1494,7 +1523,7 @@ BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r,
r.InsetBy(-3, -3); r.InsetBy(-3, -3);
SetHighColor(normal); SetHighColor(normal);
FillRect(r); FillRect(r);
BShape arrowShape; BShape arrowShape;
arrowShape.MoveTo(tri1); arrowShape.MoveTo(tri1);
arrowShape.LineTo(tri2); arrowShape.LineTo(tri2);