diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index b914f833b4..86bc4deffe 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2017, Haiku, Inc. All rights reserved. + * Copyright 2009-2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CONTROL_LOOK_H @@ -90,6 +90,12 @@ public: B_BLEND_FRAME = 1 << 16, }; + enum { + B_KNOB_NONE = 0, + B_KNOB_DOTS, + B_KNOB_LINES + }; + virtual BAlignment DefaultLabelAlignment() const = 0; virtual float DefaultLabelSpacing() const = 0; @@ -401,11 +407,24 @@ public: uint32 borders = B_ALL_BORDERS, border_style borderStyle = B_FANCY_BORDER, uint32 side = B_TOP_BORDER) = 0; + + virtual void DrawScrollBarButton(BView* view, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + int32 direction, orientation orientation, + bool down = false) = 0; + virtual void DrawScrollBarThumb(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation, + uint32 knobStyle = B_KNOB_NONE) = 0; + virtual void DrawScrollBarBorder(BView* view, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation) = 0; + private: // FBC padding - virtual void _ReservedControlLook2(); - virtual void _ReservedControlLook3(); - virtual void _ReservedControlLook4(); virtual void _ReservedControlLook5(); virtual void _ReservedControlLook6(); virtual void _ReservedControlLook7(); diff --git a/headers/os/interface/ScrollBar.h b/headers/os/interface/ScrollBar.h index 873ab84535..557d11c118 100644 --- a/headers/os/interface/ScrollBar.h +++ b/headers/os/interface/ScrollBar.h @@ -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. */ #ifndef _SCROLL_BAR_H @@ -121,14 +121,6 @@ private: BRect _ButtonRectFor(int32 button) const; void _UpdateTargetValue(BPoint where); void _UpdateArrowButtons(); - void _DrawDisabledBackground(BRect area, - const rgb_color& light, - const rgb_color& dark, - const rgb_color& fill); - void _DrawArrowButton(int32 direction, - bool doubleArrows, BRect frame, - const BRect& updateRect, - bool enabled, bool down); BSize _MinSize() const; diff --git a/headers/private/interface/HaikuControlLook.h b/headers/private/interface/HaikuControlLook.h index ef995c12fa..c813cbcca5 100644 --- a/headers/private/interface/HaikuControlLook.h +++ b/headers/private/interface/HaikuControlLook.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2017, Haiku, Inc. All rights reserved. + * Copyright 2009-2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _HAIKU_CONTROL_LOOK_H @@ -157,6 +157,15 @@ public: const rgb_color& base, uint32 flags = 0); + virtual void DrawScrollBarBorder(BView* view, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation); + virtual void DrawScrollBarButton(BView* view, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + int32 direction, orientation orientation, + bool down = false); virtual void DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, const BRect& updateRect, @@ -166,6 +175,11 @@ public: BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation); + virtual void DrawScrollBarThumb(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation, + uint32 knobStyle = B_KNOB_NONE); virtual void DrawScrollViewFrame(BView* view, BRect& rect, const BRect& updateRect, diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index 740f23332e..94fd4cc39d 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2012-2017 Haiku, Inc. All rights reserved. + * Copyright 2012-2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ @@ -91,9 +91,42 @@ B_IF_GCC_2(_ReservedControlLook1__Q28BPrivate12BControlLook, } -void BControlLook::_ReservedControlLook2() {} -void BControlLook::_ReservedControlLook3() {} -void BControlLook::_ReservedControlLook4() {} +extern "C" void +B_IF_GCC_2(_ReservedControlLook2__Q28BPrivate12BControlLook, + _ZN8BPrivate12BControlLook21_ReservedControlLook2Ev)( + BControlLook* controlLook, BView* view, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + int32 direction, orientation orientation, bool down) +{ + controlLook->DrawScrollBarButton(view, rect, updateRect, base, flags, + direction, orientation, down); +} + + +extern "C" void +B_IF_GCC_2(_ReservedControlLook3__Q28BPrivate12BControlLook, + _ZN8BPrivate12BControlLook21_ReservedControlLook3Ev)( + BControlLook* controlLook, BView* view, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + int32 direction, orientation orientation, uint32 knobStyle) +{ + controlLook->DrawScrollBarThumb(view, rect, updateRect, base, flags, + orientation, knobStyle); +} + + +extern "C" void +B_IF_GCC_2(_ReservedControlLook4__Q28BPrivate12BControlLook, + _ZN8BPrivate12BControlLook21_ReservedControlLook4Ev)( + BControlLook* controlLook, BView* view, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + orientation orientation) +{ + controlLook->DrawScrollBarBorder(view, rect, updateRect, base, flags, + orientation); +} + + void BControlLook::_ReservedControlLook5() {} void BControlLook::_ReservedControlLook6() {} void BControlLook::_ReservedControlLook7() {} diff --git a/src/kits/interface/HaikuControlLook.cpp b/src/kits/interface/HaikuControlLook.cpp index f680618efa..a43edb409a 100644 --- a/src/kits/interface/HaikuControlLook.cpp +++ b/src/kits/interface/HaikuControlLook.cpp @@ -1,6 +1,6 @@ /* * Copyright 2009, Stephan Aßmus - * Copyright 2012-2017 Haiku, Inc. All rights reserved. + * Copyright 2012-2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -28,7 +28,6 @@ namespace BPrivate { - static const float kEdgeBevelLightTint = 0.59; static const float kEdgeBevelShadowTint = 1.0735; static const float kHoverTintFactor = 0.85; @@ -563,9 +562,93 @@ HaikuControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateR void -HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, +HaikuControlLook::DrawScrollBarBorder(BView* view, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + bool isEnabled = (flags & B_DISABLED) == 0; + bool isFocused = (flags & B_FOCUSED) != 0; + + view->SetHighColor(tint_color(base, B_DARKEN_2_TINT)); + + // stroke a line around the entire scrollbar + // take care of border highlighting, scroll target is focus view + if (isEnabled && isFocused) { + rgb_color borderColor = view->HighColor(); + rgb_color highlightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + view->BeginLineArray(4); + + view->AddLine(BPoint(rect.left + 1, rect.bottom), + BPoint(rect.right, rect.bottom), borderColor); + view->AddLine(BPoint(rect.right, rect.top + 1), + BPoint(rect.right, rect.bottom - 1), borderColor); + + if (orientation == B_HORIZONTAL) { + view->AddLine(BPoint(rect.left, rect.top + 1), + BPoint(rect.left, rect.bottom), borderColor); + } else { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), highlightColor); + } + + if (orientation == B_HORIZONTAL) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), highlightColor); + } else { + view->AddLine(BPoint(rect.left + 1, rect.top), + BPoint(rect.right, rect.top), borderColor); + } + + view->EndLineArray(); + } else + view->StrokeRect(rect); + + view->PopState(); +} + + +void +HaikuControlLook::DrawScrollBarButton(BView* view, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + int32 direction, orientation orientation, bool down) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // clip to button + BRegion buttonRegion(rect); + view->ConstrainClippingRegion(&buttonRegion); + + bool isEnabled = (flags & B_DISABLED) == 0; + + rgb_color buttonColor = isEnabled ? base + : tint_color(base, B_LIGHTEN_1_TINT); + DrawButtonBackground(view, rect, updateRect, buttonColor, flags, + BControlLook::B_ALL_BORDERS, orientation); + + rect.InsetBy(-1, -1); + DrawArrowShape(view, rect, updateRect, base, direction, flags, 1.9f); + // almost but not quite B_DARKEN_MAX_TINT + + // revert clipping constraints + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); +} + +void +HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, + BRect& rect2, const BRect& updateRect, const rgb_color& base, uint32 flags, + orientation orientation) { DrawScrollBarBackground(view, rect1, updateRect, base, flags, orientation); DrawScrollBarBackground(view, rect2, updateRect, base, flags, orientation); @@ -580,24 +663,35 @@ HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect, if (!rect.IsValid() || !rect.Intersects(updateRect)) return; + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + bool isEnabled = (flags & B_DISABLED) == 0; + + // fill background, we'll draw arrows and thumb on top + view->SetDrawingMode(B_OP_COPY); + float gradient1Tint; float gradient2Tint; float darkEdge1Tint; float darkEdge2Tint; float shadowTint; - if ((flags & B_DISABLED) != 0) { - gradient1Tint = 0.9; - gradient2Tint = 0.8; - darkEdge1Tint = B_DARKEN_2_TINT; - darkEdge2Tint = B_DARKEN_2_TINT; - shadowTint = gradient1Tint; - } else { + if (isEnabled) { gradient1Tint = 1.10; gradient2Tint = 1.05; darkEdge1Tint = B_DARKEN_3_TINT; darkEdge2Tint = B_DARKEN_2_TINT; shadowTint = gradient1Tint; + } else { + gradient1Tint = 0.9; + gradient2Tint = 0.8; + darkEdge1Tint = B_DARKEN_2_TINT; + darkEdge2Tint = B_DARKEN_2_TINT; + shadowTint = gradient1Tint; } rgb_color darkEdge1 = tint_color(base, darkEdge1Tint); @@ -653,6 +747,198 @@ HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect, orientation); } } + + view->PopState(); +} + + +void +HaikuControlLook::DrawScrollBarThumb(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + orientation orientation, uint32 knobStyle) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + // flags + bool isEnabled = (flags & B_DISABLED) == 0; + + // colors + rgb_color thumbColor = ui_color(B_SCROLL_BAR_THUMB_COLOR); + const float bgTint = 1.06; + + rgb_color light, dark, dark1, dark2; + if (isEnabled) { + light = tint_color(base, B_LIGHTEN_MAX_TINT); + dark = tint_color(base, B_DARKEN_3_TINT); + dark1 = tint_color(base, B_DARKEN_1_TINT); + dark2 = tint_color(base, B_DARKEN_2_TINT); + } else { + light = tint_color(base, B_LIGHTEN_MAX_TINT); + dark = tint_color(base, B_DARKEN_2_TINT); + dark1 = tint_color(base, B_LIGHTEN_2_TINT); + dark2 = tint_color(base, B_LIGHTEN_1_TINT); + } + + // draw thumb over background + view->SetDrawingMode(B_OP_OVER); + view->SetHighColor(dark1); + + // draw scroll thumb + if (isEnabled) { + // fill the clickable surface of the thumb + DrawButtonBackground(view, rect, updateRect, thumbColor, 0, + B_ALL_BORDERS, orientation); + } else { + // thumb bevel + view->BeginLineArray(4); + view->AddLine(BPoint(rect.left, rect.bottom), + BPoint(rect.left, rect.top), light); + view->AddLine(BPoint(rect.left + 1, rect.top), + BPoint(rect.right, rect.top), light); + view->AddLine(BPoint(rect.right, rect.top + 1), + BPoint(rect.right, rect.bottom), dark2); + view->AddLine(BPoint(rect.right - 1, rect.bottom), + BPoint(rect.left + 1, rect.bottom), dark2); + view->EndLineArray(); + + // thumb fill + rect.InsetBy(1, 1); + view->SetHighColor(dark1); + view->FillRect(rect); + } + + // draw knob style + if (knobStyle != B_KNOB_NONE) { + rgb_color knobLight = isEnabled + ? tint_color(thumbColor, B_LIGHTEN_MAX_TINT) + : tint_color(dark1, bgTint); + rgb_color knobDark = isEnabled + ? tint_color(thumbColor, 1.22) + : tint_color(knobLight, B_DARKEN_1_TINT); + + if (knobStyle == B_KNOB_DOTS) { + // draw dots on the scroll bar thumb + float hcenter = rect.left + rect.Width() / 2; + float vmiddle = rect.top + rect.Height() / 2; + BRect knob(hcenter, vmiddle, hcenter, vmiddle); + + if (orientation == B_HORIZONTAL) { + view->SetHighColor(knobDark); + view->FillRect(knob); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(1, 1)); + + float spacer = rect.Height(); + + if (rect.left + 3 < hcenter - spacer) { + view->SetHighColor(knobDark); + view->FillRect(knob.OffsetByCopy(-spacer, 0)); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(-spacer + 1, 1)); + } + + if (rect.right - 3 > hcenter + spacer) { + view->SetHighColor(knobDark); + view->FillRect(knob.OffsetByCopy(spacer, 0)); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(spacer + 1, 1)); + } + } else { + // B_VERTICAL + view->SetHighColor(knobDark); + view->FillRect(knob); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(1, 1)); + + float spacer = rect.Width(); + + if (rect.top + 3 < vmiddle - spacer) { + view->SetHighColor(knobDark); + view->FillRect(knob.OffsetByCopy(0, -spacer)); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(1, -spacer + 1)); + } + + if (rect.bottom - 3 > vmiddle + spacer) { + view->SetHighColor(knobDark); + view->FillRect(knob.OffsetByCopy(0, spacer)); + view->SetHighColor(knobLight); + view->FillRect(knob.OffsetByCopy(1, spacer + 1)); + } + } + } else if (knobStyle == B_KNOB_LINES) { + // draw lines on the scroll bar thumb + if (orientation == B_HORIZONTAL) { + float middle = rect.Width() / 2; + + view->BeginLineArray(6); + view->AddLine( + BPoint(rect.left + middle - 3, rect.top + 2), + BPoint(rect.left + middle - 3, rect.bottom - 2), + knobDark); + view->AddLine( + BPoint(rect.left + middle, rect.top + 2), + BPoint(rect.left + middle, rect.bottom - 2), + knobDark); + view->AddLine( + BPoint(rect.left + middle + 3, rect.top + 2), + BPoint(rect.left + middle + 3, rect.bottom - 2), + knobDark); + view->AddLine( + BPoint(rect.left + middle - 2, rect.top + 2), + BPoint(rect.left + middle - 2, rect.bottom - 2), + knobLight); + view->AddLine( + BPoint(rect.left + middle + 1, rect.top + 2), + BPoint(rect.left + middle + 1, rect.bottom - 2), + knobLight); + view->AddLine( + BPoint(rect.left + middle + 4, rect.top + 2), + BPoint(rect.left + middle + 4, rect.bottom - 2), + knobLight); + view->EndLineArray(); + } else { + // B_VERTICAL + float middle = rect.Height() / 2; + + view->BeginLineArray(6); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle - 3), + BPoint(rect.right - 2, rect.top + middle - 3), + knobDark); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle), + BPoint(rect.right - 2, rect.top + middle), + knobDark); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle + 3), + BPoint(rect.right - 2, rect.top + middle + 3), + knobDark); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle - 2), + BPoint(rect.right - 2, rect.top + middle - 2), + knobLight); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle + 1), + BPoint(rect.right - 2, rect.top + middle + 1), + knobLight); + view->AddLine( + BPoint(rect.left + 2, rect.top + middle + 4), + BPoint(rect.right - 2, rect.top + middle + 4), + knobLight); + view->EndLineArray(); + } + } + } + + view->PopState(); } @@ -741,8 +1027,9 @@ HaikuControlLook::DrawScrollViewFrame(BView* view, BRect& rect, void -HaikuControlLook::DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 direction, uint32 flags, float tint) +HaikuControlLook::DrawArrowShape(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 direction, + uint32 flags, float tint) { BPoint tri1, tri2, tri3; float hInset = rect.Width() / 3; @@ -1005,20 +1292,24 @@ HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect view->BeginLineArray(4); if (orientation == B_HORIZONTAL) { - view->AddLine(barRect.LeftTop(), barRect.RightTop(), edgeShadowColor); + view->AddLine(barRect.LeftTop(), barRect.RightTop(), + edgeShadowColor); view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), edgeLightColor); barRect.InsetBy(0, 1); - view->AddLine(barRect.LeftTop(), barRect.RightTop(), frameShadowColor); + view->AddLine(barRect.LeftTop(), barRect.RightTop(), + frameShadowColor); view->AddLine(barRect.LeftBottom(), barRect.RightBottom(), frameLightColor); barRect.InsetBy(0, 1); } else { - view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), edgeShadowColor); + view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), + edgeShadowColor); view->AddLine(barRect.RightTop(), barRect.RightBottom(), edgeLightColor); barRect.InsetBy(1, 0); - view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), frameShadowColor); + view->AddLine(barRect.LeftTop(), barRect.LeftBottom(), + frameShadowColor); view->AddLine(barRect.RightTop(), barRect.RightBottom(), frameLightColor); barRect.InsetBy(1, 0); @@ -3607,7 +3898,6 @@ HaikuControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect, } - bool HaikuControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, rgb_color& color, uint32 flags) const @@ -3646,5 +3936,4 @@ HaikuControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, return true; } - } // namespace BPrivate diff --git a/src/kits/interface/ScrollBar.cpp b/src/kits/interface/ScrollBar.cpp index b5a066d28f..963d7beffe 100644 --- a/src/kits/interface/ScrollBar.cpp +++ b/src/kits/interface/ScrollBar.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2014 Haiku, Inc. All rights reserved. + * Copyright 2001-2020 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT license. * * Authors: @@ -379,205 +379,120 @@ BScrollBar::DetachedFromWindow() void BScrollBar::Draw(BRect updateRect) { - BRect bounds = Bounds(); - - rgb_color normal = ui_color(B_PANEL_BACKGROUND_COLOR); - - // stroke a dark frame around the entire scrollbar - // (independent of enabled state) - // take care of border highlighting (scroll target is focus view) - SetHighColor(tint_color(normal, B_DARKEN_2_TINT)); - if (fPrivateData->fBorderHighlighted && fPrivateData->fEnabled) { - rgb_color borderColor = HighColor(); - rgb_color highlightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - BeginLineArray(4); - AddLine(BPoint(bounds.left + 1, bounds.bottom), - BPoint(bounds.right, bounds.bottom), borderColor); - AddLine(BPoint(bounds.right, bounds.top + 1), - BPoint(bounds.right, bounds.bottom - 1), borderColor); - if (fOrientation == B_HORIZONTAL) { - AddLine(BPoint(bounds.left, bounds.top + 1), - BPoint(bounds.left, bounds.bottom), borderColor); - } else { - AddLine(BPoint(bounds.left, bounds.top), - BPoint(bounds.left, bounds.bottom), highlightColor); - } - if (fOrientation == B_HORIZONTAL) { - AddLine(BPoint(bounds.left, bounds.top), - BPoint(bounds.right, bounds.top), highlightColor); - } else { - AddLine(BPoint(bounds.left + 1, bounds.top), - BPoint(bounds.right, bounds.top), borderColor); - } - EndLineArray(); - } else - StrokeRect(bounds); - - bounds.InsetBy(1.0f, 1.0f); - - bool enabled = fPrivateData->fEnabled && fMin < fMax - && fProportion < 1.0f && fProportion >= 0.0f; - - rgb_color light, dark, dark1, dark2; - if (enabled) { - light = tint_color(normal, B_LIGHTEN_MAX_TINT); - dark = tint_color(normal, B_DARKEN_3_TINT); - dark1 = tint_color(normal, B_DARKEN_1_TINT); - dark2 = tint_color(normal, B_DARKEN_2_TINT); - } else { - light = tint_color(normal, B_LIGHTEN_MAX_TINT); - dark = tint_color(normal, B_DARKEN_2_TINT); - dark1 = tint_color(normal, B_LIGHTEN_2_TINT); - dark2 = tint_color(normal, B_LIGHTEN_1_TINT); - } - - SetDrawingMode(B_OP_OVER); - - BRect thumbBG = bounds; - bool doubleArrows = _DoubleArrows(); - - // Draw arrows - if (fOrientation == B_HORIZONTAL) { - BRect buttonFrame(bounds.left, bounds.top, - bounds.left + bounds.Height(), bounds.bottom); - - _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW1); - - if (doubleArrows) { - buttonFrame.OffsetBy(bounds.Height() + 1, 0.0f); - _DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW2); - - buttonFrame.OffsetTo(bounds.right - ((bounds.Height() * 2) + 1), - bounds.top); - _DrawArrowButton(ARROW_LEFT, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW3); - - thumbBG.left += bounds.Height() * 2 + 2; - thumbBG.right -= bounds.Height() * 2 + 2; - } else { - thumbBG.left += bounds.Height() + 1; - thumbBG.right -= bounds.Height() + 1; - } - - buttonFrame.OffsetTo(bounds.right - bounds.Height(), bounds.top); - _DrawArrowButton(ARROW_RIGHT, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW4); - } else { - BRect buttonFrame(bounds.left, bounds.top, bounds.right, - bounds.top + bounds.Width()); - - _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW1); - - if (doubleArrows) { - buttonFrame.OffsetBy(0.0f, bounds.Width() + 1); - _DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW2); - - buttonFrame.OffsetTo(bounds.left, bounds.bottom - - ((bounds.Width() * 2) + 1)); - _DrawArrowButton(ARROW_UP, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW3); - - thumbBG.top += bounds.Width() * 2 + 2; - thumbBG.bottom -= bounds.Width() * 2 + 2; - } else { - thumbBG.top += bounds.Width() + 1; - thumbBG.bottom -= bounds.Width() + 1; - } - - buttonFrame.OffsetTo(bounds.left, bounds.bottom - bounds.Width()); - _DrawArrowButton(ARROW_DOWN, doubleArrows, buttonFrame, updateRect, - enabled, fPrivateData->fButtonDown == ARROW4); - } - - SetDrawingMode(B_OP_COPY); - - // background for thumb area - BRect rect(fPrivateData->fThumbFrame); - - SetHighColor(dark1); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); uint32 flags = 0; - if (!enabled) + bool scrollingEnabled = fMin < fMax + && fProportion >= 0.0f && fProportion < 1.0f; + if (scrollingEnabled) + flags |= BControlLook::B_PARTIALLY_ACTIVATED; + + if (!fPrivateData->fEnabled || !scrollingEnabled) flags |= BControlLook::B_DISABLED; - // fill background besides the thumb - if (fOrientation == B_HORIZONTAL) { - BRect leftOfThumb(thumbBG.left, thumbBG.top, rect.left - 1, - thumbBG.bottom); - BRect rightOfThumb(rect.right + 1, thumbBG.top, thumbBG.right, - thumbBG.bottom); + bool isFocused = fPrivateData->fBorderHighlighted; + if (isFocused) + flags |= BControlLook::B_FOCUSED; + bool doubleArrows = _DoubleArrows(); + + // draw border + BRect rect = Bounds(); + be_control_look->DrawScrollBarBorder(this, rect, updateRect, base, flags, + fOrientation); + + // inset past border + rect.InsetBy(1, 1); + + // draw arrows buttons + BRect thumbBG = rect; + if (fOrientation == B_HORIZONTAL) { + BRect buttonFrame(rect.left, rect.top, + rect.left + rect.Height(), rect.bottom); + + be_control_look->DrawScrollBarButton(this, buttonFrame, updateRect, + base, flags, BControlLook::B_LEFT_ARROW, fOrientation, + fPrivateData->fButtonDown == ARROW1); + + if (doubleArrows) { + buttonFrame.OffsetBy(rect.Height() + 1, 0.0f); + be_control_look->DrawScrollBarButton(this, buttonFrame, + updateRect, base, flags, BControlLook::B_RIGHT_ARROW, + fOrientation, fPrivateData->fButtonDown == ARROW2); + + buttonFrame.OffsetTo(rect.right - ((rect.Height() * 2) + 1), + rect.top); + be_control_look->DrawScrollBarButton(this, buttonFrame, + updateRect, base, flags, BControlLook::B_LEFT_ARROW, + fOrientation, fPrivateData->fButtonDown == ARROW3); + + thumbBG.left += rect.Height() * 2 + 2; + thumbBG.right -= rect.Height() * 2 + 2; + } else { + thumbBG.left += rect.Height() + 1; + thumbBG.right -= rect.Height() + 1; + } + + buttonFrame.OffsetTo(rect.right - rect.Height(), rect.top); + be_control_look->DrawScrollBarButton(this, buttonFrame, updateRect, + base, flags, BControlLook::B_RIGHT_ARROW, fOrientation, + fPrivateData->fButtonDown == ARROW4); + } else { + BRect buttonFrame(rect.left, rect.top, rect.right, + rect.top + rect.Width()); + + be_control_look->DrawScrollBarButton(this, buttonFrame, updateRect, + base, flags, BControlLook::B_UP_ARROW, fOrientation, + fPrivateData->fButtonDown == ARROW1); + + if (doubleArrows) { + buttonFrame.OffsetBy(0, rect.Width() + 1); + be_control_look->DrawScrollBarButton(this, buttonFrame, + updateRect, base, flags, BControlLook::B_DOWN_ARROW, + fOrientation, fPrivateData->fButtonDown == ARROW2); + + buttonFrame.OffsetTo(rect.left, rect.bottom + - ((rect.Width() * 2) + 1)); + be_control_look->DrawScrollBarButton(this, buttonFrame, + updateRect, base, flags, BControlLook::B_UP_ARROW, + fOrientation, fPrivateData->fButtonDown == ARROW3); + + thumbBG.top += rect.Width() * 2 + 2; + thumbBG.bottom -= rect.Width() * 2 + 2; + } else { + thumbBG.top += rect.Width() + 1; + thumbBG.bottom -= rect.Width() + 1; + } + + buttonFrame.OffsetTo(rect.left, rect.bottom - rect.Width()); + be_control_look->DrawScrollBarButton(this, buttonFrame, updateRect, + base, flags, BControlLook::B_DOWN_ARROW, fOrientation, + fPrivateData->fButtonDown == ARROW4); + } + + // fill background besides the thumb + rect = fPrivateData->fThumbFrame; + if (fOrientation == B_HORIZONTAL) { + BRect leftOfThumb(thumbBG.left, thumbBG.top, + rect.left - 1, thumbBG.bottom); + BRect rightOfThumb(rect.right + 1, thumbBG.top, + thumbBG.right, thumbBG.bottom); be_control_look->DrawScrollBarBackground(this, leftOfThumb, - rightOfThumb, updateRect, normal, flags, fOrientation); + rightOfThumb, updateRect, base, flags, fOrientation); } else { BRect topOfThumb(thumbBG.left, thumbBG.top, thumbBG.right, rect.top - 1); - BRect bottomOfThumb(thumbBG.left, rect.bottom + 1, thumbBG.right, thumbBG.bottom); - be_control_look->DrawScrollBarBackground(this, topOfThumb, - bottomOfThumb, updateRect, normal, flags, fOrientation); + bottomOfThumb, updateRect, base, flags, fOrientation); } - rgb_color thumbColor = ui_color(B_SCROLL_BAR_THUMB_COLOR); - - // Draw scroll thumb - if (enabled) { - // fill the clickable surface of the thumb - be_control_look->DrawButtonBackground(this, rect, updateRect, - thumbColor, 0, BControlLook::B_ALL_BORDERS, fOrientation); - // TODO: Add the other thumb styles - dots and lines - } else { - if (fMin >= fMax || fProportion >= 1.0f || fProportion < 0.0f) { - // we cannot scroll at all - _DrawDisabledBackground(thumbBG, light, dark, dark1); - } else { - // we could scroll, but we're simply disabled - float bgTint = 1.06; - rgb_color bgLight = tint_color(light, bgTint * 3); - rgb_color bgShadow = tint_color(dark, bgTint); - rgb_color bgFill = tint_color(dark1, bgTint); - if (fOrientation == B_HORIZONTAL) { - // left of thumb - BRect besidesThumb(thumbBG); - besidesThumb.right = rect.left - 1; - _DrawDisabledBackground(besidesThumb, bgLight, bgShadow, bgFill); - // right of thumb - besidesThumb.left = rect.right + 1; - besidesThumb.right = thumbBG.right; - _DrawDisabledBackground(besidesThumb, bgLight, bgShadow, bgFill); - } else { - // above thumb - BRect besidesThumb(thumbBG); - besidesThumb.bottom = rect.top - 1; - _DrawDisabledBackground(besidesThumb, bgLight, bgShadow, bgFill); - // below thumb - besidesThumb.top = rect.bottom + 1; - besidesThumb.bottom = thumbBG.bottom; - _DrawDisabledBackground(besidesThumb, bgLight, bgShadow, bgFill); - } - // thumb bevel - BeginLineArray(4); - AddLine(BPoint(rect.left, rect.bottom), - BPoint(rect.left, rect.top), light); - AddLine(BPoint(rect.left + 1, rect.top), - BPoint(rect.right, rect.top), light); - AddLine(BPoint(rect.right, rect.top + 1), - BPoint(rect.right, rect.bottom), dark2); - AddLine(BPoint(rect.right - 1, rect.bottom), - BPoint(rect.left + 1, rect.bottom), dark2); - EndLineArray(); - // thumb fill - rect.InsetBy(1.0, 1.0); - SetHighColor(dark1); - FillRect(rect); - } - } + // draw thumb + rect = fPrivateData->fThumbFrame; + be_control_look->DrawScrollBarThumb(this, rect, updateRect, + ui_color(B_SCROLL_BAR_THUMB_COLOR), flags, fOrientation, + fPrivateData->fScrollBarInfo.knob); } @@ -649,11 +564,15 @@ BScrollBar::MouseDown(BPoint where) if (buttons & B_SECONDARY_MOUSE_BUTTON) { // special absolute scrolling: move thumb to where we clicked fPrivateData->fButtonDown = THUMB; - fPrivateData->fClickOffset = fPrivateData->fThumbFrame.LeftTop() - where; - if (Orientation() == B_HORIZONTAL) - fPrivateData->fClickOffset.x = -fPrivateData->fThumbFrame.Width() / 2; - else - fPrivateData->fClickOffset.y = -fPrivateData->fThumbFrame.Height() / 2; + fPrivateData->fClickOffset + = fPrivateData->fThumbFrame.LeftTop() - where; + if (Orientation() == B_HORIZONTAL) { + fPrivateData->fClickOffset.x + = -fPrivateData->fThumbFrame.Width() / 2; + } else { + fPrivateData->fClickOffset.y + = -fPrivateData->fThumbFrame.Height() / 2; + } SetValue(_ValueFor(where + fPrivateData->fClickOffset)); return; @@ -662,7 +581,8 @@ BScrollBar::MouseDown(BPoint where) // hit test for the thumb if (fPrivateData->fThumbFrame.Contains(where)) { fPrivateData->fButtonDown = THUMB; - fPrivateData->fClickOffset = fPrivateData->fThumbFrame.LeftTop() - where; + fPrivateData->fClickOffset + = fPrivateData->fThumbFrame.LeftTop() - where; Invalidate(fPrivateData->fThumbFrame); return; } @@ -1553,101 +1473,6 @@ control_scrollbar(scroll_bar_info* info, BScrollBar* bar) } -void -BScrollBar::_DrawDisabledBackground(BRect area, const rgb_color& light, - const rgb_color& dark, const rgb_color& fill) -{ - if (!area.IsValid()) - return; - - if (fOrientation == B_VERTICAL) { - int32 height = area.IntegerHeight(); - if (height == 0) { - SetHighColor(dark); - StrokeLine(area.LeftTop(), area.RightTop()); - } else if (height == 1) { - SetHighColor(dark); - FillRect(area); - } else { - BeginLineArray(4); - AddLine(BPoint(area.left, area.top), - BPoint(area.right, area.top), dark); - AddLine(BPoint(area.left, area.bottom - 1), - BPoint(area.left, area.top + 1), light); - AddLine(BPoint(area.left + 1, area.top + 1), - BPoint(area.right, area.top + 1), light); - AddLine(BPoint(area.right, area.bottom), - BPoint(area.left, area.bottom), dark); - EndLineArray(); - area.left++; - area.top += 2; - area.bottom--; - if (area.IsValid()) { - SetHighColor(fill); - FillRect(area); - } - } - } else { - int32 width = area.IntegerWidth(); - if (width == 0) { - SetHighColor(dark); - StrokeLine(area.LeftBottom(), area.LeftTop()); - } else if (width == 1) { - SetHighColor(dark); - FillRect(area); - } else { - BeginLineArray(4); - AddLine(BPoint(area.left, area.bottom), - BPoint(area.left, area.top), dark); - AddLine(BPoint(area.left + 1, area.bottom), - BPoint(area.left + 1, area.top + 1), light); - AddLine(BPoint(area.left + 1, area.top), - BPoint(area.right - 1, area.top), light); - AddLine(BPoint(area.right, area.top), - BPoint(area.right, area.bottom), dark); - EndLineArray(); - area.left += 2; - area.top ++; - area.right--; - if (area.IsValid()) { - SetHighColor(fill); - FillRect(area); - } - } - } -} - - -void -BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect rect, - const BRect& updateRect, bool enabled, bool down) -{ - if (!updateRect.Intersects(rect)) - return; - - uint32 flags = 0; - if (!enabled) - flags |= BControlLook::B_DISABLED; - - if (down && fPrivateData->fDoRepeat) - flags |= BControlLook::B_ACTIVATED; - - // TODO: Why does BControlLook need this as the base color for the - // scrollbar to look right? - rgb_color baseColor = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), - B_LIGHTEN_1_TINT); - - be_control_look->DrawButtonBackground(this, rect, updateRect, baseColor, - flags, BControlLook::B_ALL_BORDERS, fOrientation); - - // TODO: Why does BControlLook need this negative inset for the arrow to - // look right? - rect.InsetBy(-1.0f, -1.0f); - be_control_look->DrawArrowShape(this, rect, updateRect, - baseColor, direction, flags, B_DARKEN_MAX_TINT); -} - - BSize BScrollBar::_MinSize() const {