From db68ff23c6506fa5b0871c594c46043342de3fae Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sun, 10 Sep 2017 22:15:07 -0400 Subject: [PATCH] Interface Kit: Make BControlLook a proper pure-virtual base class. All of its prior functionality has been moved into HaikuControlLook. This paves the way for customizeable control looks, which I intend to implement in the future as part of decorators. This is being pushed now because libbe ABI was already broken due to the Notifications changes, so this is riding that so we only have to do a mass rebuild once. --- headers/os/interface/ControlLook.h | 345 +- headers/private/interface/HaikuControlLook.h | 569 +++ src/kits/interface/ControlLook.cpp | 3582 +---------------- src/kits/interface/HaikuControlLook.cpp | 3601 ++++++++++++++++++ src/kits/interface/InterfaceDefs.cpp | 3 +- src/kits/interface/Jamfile | 1 + 6 files changed, 4227 insertions(+), 3874 deletions(-) create mode 100644 headers/private/interface/HaikuControlLook.h create mode 100644 src/kits/interface/HaikuControlLook.cpp diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h index 126624bafa..2f7af32d19 100644 --- a/headers/os/interface/ControlLook.h +++ b/headers/os/interface/ControlLook.h @@ -1,5 +1,5 @@ /* - * Copyright 2009-2015, Haiku, Inc. All rights reserved. + * Copyright 2009-2017, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef _CONTROL_LOOK_H @@ -90,28 +90,28 @@ public: B_BLEND_FRAME = 1 << 16, }; - virtual BAlignment DefaultLabelAlignment() const; - virtual float DefaultLabelSpacing() const; + virtual BAlignment DefaultLabelAlignment() const = 0; + virtual float DefaultLabelSpacing() const = 0; - virtual float DefaultItemSpacing() const; + virtual float DefaultItemSpacing() const = 0; static float ComposeSpacing(float spacing); - virtual uint32 Flags(BControl* control) const; + virtual uint32 Flags(BControl* control) const = 0; virtual void DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, float radius, const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, float leftTopRadius, @@ -121,21 +121,21 @@ public: const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawButtonBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; virtual void DrawButtonBackground(BView* view, BRect& rect, const BRect& updateRect, float radius, const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; virtual void DrawButtonBackground(BView* view, BRect& rect, const BRect& updateRect, float leftTopRadius, @@ -145,27 +145,27 @@ public: const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; virtual void DrawMenuBarBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuFieldFrame(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuFieldFrame(BView* view, BRect& rect, const BRect& updateRect, float radius, const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuFieldFrame(BView* view, BRect& rect, const BRect& updateRect, float leftTopRadius, @@ -175,16 +175,16 @@ public: const rgb_color& base, const rgb_color& background, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuFieldBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, bool popupIndicator, - uint32 flags = 0); + uint32 flags = 0) = 0; virtual void DrawMenuFieldBackground(BView* view, BRect& rect, const BRect& updateRect, float radius, const rgb_color& base, - bool popupIndicator, uint32 flags = 0); + bool popupIndicator, uint32 flags = 0) = 0; virtual void DrawMenuFieldBackground(BView* view, BRect& rect, const BRect& updateRect, float leftTopRadius, @@ -192,47 +192,47 @@ public: float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - bool popupIndicator, uint32 flags = 0); + bool popupIndicator, uint32 flags = 0) = 0; virtual void DrawMenuFieldBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawMenuItemBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& barColor, - float progressPosition); + float progressPosition) = 0; virtual void DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, - uint32 flags = 0); + uint32 flags = 0) = 0; virtual void DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, - uint32 flags = 0); + uint32 flags = 0) = 0; virtual void DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawScrollBarBackground(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawScrollViewFrame(BView* view, BRect& rect, const BRect& updateRect, @@ -241,15 +241,15 @@ public: const rgb_color& base, border_style borderStyle, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawArrowShape(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 direction, uint32 flags = 0, - float tint = B_DARKEN_MAX_TINT); + float tint = B_DARKEN_MAX_TINT) = 0; - virtual rgb_color SliderBarColor(const rgb_color& base); + virtual rgb_color SliderBarColor(const rgb_color& base) = 0; virtual void DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, @@ -257,51 +257,51 @@ public: rgb_color leftFillColor, rgb_color rightFillColor, float sliderScale, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, const rgb_color& base, rgb_color fillColor, - uint32 flags, orientation orientation); + uint32 flags, orientation orientation) = 0; virtual void DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawSliderTriangle(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawSliderTriangle(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, const rgb_color& fill, uint32 flags, - orientation orientation); + orientation orientation) = 0; virtual void DrawSliderHashMarks(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, int32 count, hash_mark_location location, - uint32 flags, orientation orientation); + uint32 flags, orientation orientation) = 0; virtual void DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - uint32 side = B_TOP_BORDER); + uint32 side = B_TOP_BORDER) = 0; virtual void DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - uint32 side = B_TOP_BORDER); + uint32 side = B_TOP_BORDER) = 0; virtual void DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, orientation orientation, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; // various borders @@ -309,41 +309,41 @@ public: const BRect& updateRect, const rgb_color& base, border_style borderStyle, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawRaisedBorder(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; virtual void DrawTextControlBorder(BView* view, BRect& rect, const BRect& updateRect, const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); + uint32 borders = B_ALL_BORDERS) = 0; // aligned labels virtual void DrawLabel(BView* view, const char* label, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - const rgb_color* textColor = NULL); + const rgb_color* textColor = NULL) = 0; virtual void DrawLabel(BView* view, const char* label, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, const BAlignment& alignment, - const rgb_color* textColor = NULL); + const rgb_color* textColor = NULL) = 0; // TODO: Would be nice to have a (non-virtual) version of this method // which takes an array of labels and locations. That would save some // setup with the view graphics state. virtual void DrawLabel(BView* view, const char* label, const rgb_color& base, uint32 flags, const BPoint& where, - const rgb_color* textColor = NULL); + const rgb_color* textColor = NULL) = 0; void DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, @@ -355,15 +355,15 @@ public: const BRect& updateRect, const rgb_color& base, uint32 flags, const BAlignment& alignment, - const rgb_color* textColor = NULL); + const rgb_color* textColor = NULL) = 0; virtual void GetFrameInsets(frame_type frameType, uint32 flags, float& _left, float& _top, - float& _right, float& _bottom); + float& _right, float& _bottom) = 0; virtual void GetBackgroundInsets( background_type backgroundType, uint32 flags, float& _left, float& _top, - float& _right, float& _bottom); + float& _right, float& _bottom) = 0; void GetInsets(frame_type frameType, background_type backgroundType, uint32 flags, float& _left, float& _top, @@ -374,14 +374,14 @@ public: const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; virtual void DrawButtonWithPopUpBackground(BView* view, BRect& rect, const BRect& updateRect, float radius, const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; virtual void DrawButtonWithPopUpBackground(BView* view, BRect& rect, const BRect& updateRect, float leftTopRadius, @@ -391,255 +391,12 @@ public: const rgb_color& base, uint32 flags = 0, uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); + orientation orientation = B_HORIZONTAL) = 0; void SetBackgroundInfo( const BMessage& backgroundInfo); protected: - void _DrawButtonFrame(BView* view, BRect& rect, - const BRect& updateRect, - float leftTopRadius, - float rightTopRadius, - float leftBottomRadius, - float rightBottomRadius, - const rgb_color& base, - const rgb_color& background, - float contrast, float brightness = 1.0, - uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); - - void _DrawOuterResessedFrame(BView* view, - BRect& rect, const rgb_color& base, - float contrast = 1.0f, - float brightness = 1.0f, - uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); - - void _DrawFrame(BView* view, BRect& rect, - const rgb_color& left, - const rgb_color& top, - const rgb_color& right, - const rgb_color& bottom, - uint32 borders = B_ALL_BORDERS); - void _DrawFrame(BView* view, BRect& rect, - const rgb_color& left, - const rgb_color& top, - const rgb_color& right, - const rgb_color& bottom, - const rgb_color& rightTop, - const rgb_color& leftBottom, - uint32 borders = B_ALL_BORDERS); - - void _DrawButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, - float leftTopRadius, - float rightTopRadius, - float leftBottomRadius, - float rightBottomRadius, - const rgb_color& base, - bool popupIndicator = false, - uint32 flags = 0, - uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); - void _DrawFlatButtonBackground(BView* view, - BRect& rect, const BRect& updateRect, - const rgb_color& base, - bool popupIndicator = false, - uint32 flags = 0, - uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); - void _DrawNonFlatButtonBackground(BView* view, - BRect& rect, const BRect& updateRect, - BRegion& clipping, - float leftTopRadius, - float rightTopRadius, - float leftBottomRadius, - float rightBottomRadius, - const rgb_color& base, - bool popupIndicator = false, - uint32 flags = 0, - uint32 borders = B_ALL_BORDERS, - orientation orientation = B_HORIZONTAL); - - void _DrawPopUpMarker(BView* view, const BRect& rect, - const rgb_color& base, uint32 flags); - - void _DrawMenuFieldBackgroundOutside(BView* view, - BRect& rect, const BRect& updateRect, - float leftTopRadius, - float rightTopRadius, - float leftBottomRadius, - float rightBottomRadius, - const rgb_color& base, - bool popupIndicator = false, - uint32 flags = 0); - - void _DrawMenuFieldBackgroundInside(BView* view, - BRect& rect, const BRect& updateRect, - float leftTopRadius, - float rightTopRadius, - float leftBottomRadius, - float rightBottomRadius, - const rgb_color& base, uint32 flags = 0, - uint32 borders = B_ALL_BORDERS); - - // Rounded corner methods - void _DrawRoundCornerLeftTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeColor, - const rgb_color& frameColor, - const rgb_color& bevelColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerFrameLeftTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeColor, - const rgb_color& frameColor); - - void _DrawRoundCornerBackgroundLeftTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& bevelColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerRightTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeTopColor, - const rgb_color& edgeRightColor, - const rgb_color& frameTopColor, - const rgb_color& frameRightColor, - const rgb_color& bevelTopColor, - const rgb_color& bevelRightColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerFrameRightTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeTopColor, - const rgb_color& edgeRightColor, - const rgb_color& frameTopColor, - const rgb_color& frameRightColor); - - void _DrawRoundCornerBackgroundRightTop(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& bevelTopColor, - const rgb_color& bevelRightColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerLeftBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeLeftColor, - const rgb_color& edgeBottomColor, - const rgb_color& frameLeftColor, - const rgb_color& frameBottomColor, - const rgb_color& bevelLeftColor, - const rgb_color& bevelBottomColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerFrameLeftBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeLeftColor, - const rgb_color& edgeBottomColor, - const rgb_color& frameLeftColor, - const rgb_color& frameBottomColor); - - void _DrawRoundCornerBackgroundLeftBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& bevelLeftColor, - const rgb_color& bevelBottomColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerRightBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeColor, - const rgb_color& frameColor, - const rgb_color& bevelColor, - const BGradientLinear& fillGradient); - - void _DrawRoundCornerFrameRightBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& background, - const rgb_color& edgeColor, - const rgb_color& frameColor); - - void _DrawRoundCornerBackgroundRightBottom( - BView* view, - BRect& cornerRect, const BRect& updateRect, - const rgb_color& bevelColor, - const BGradientLinear& fillGradient); - - void _DrawRoundBarCorner(BView* view, BRect& rect, - const BRect& updateRect, - const rgb_color& edgeLightColor, - const rgb_color& edgeShadowColor, - const rgb_color& frameLightColor, - const rgb_color& frameShadowColor, - const rgb_color& fillLightColor, - const rgb_color& fillShadowColor, - float leftInset, float topInset, - float rightInset, float bottomInset, - orientation orientation); - - // Border color methods - rgb_color _EdgeLightColor(const rgb_color& base, - float contrast, float brightness, - uint32 flags); - - rgb_color _EdgeShadowColor(const rgb_color& base, - float contrast, float brightness, - uint32 flags); - - rgb_color _FrameLightColor(const rgb_color& base, - uint32 flags); - - rgb_color _FrameShadowColor(const rgb_color& base, - uint32 flags); - - rgb_color _BevelLightColor(const rgb_color& base, - uint32 flags); - - rgb_color _BevelShadowColor(const rgb_color& base, - uint32 flags); - - // Background gradient methods - void _FillGradient(BView* view, const BRect& rect, - const rgb_color& base, float topTint, - float bottomTint, - orientation orientation = B_HORIZONTAL); - - void _FillGlossyGradient(BView* view, - const BRect& rect, const rgb_color& base, - float topTint, float middle1Tint, - float middle2Tint, float bottomTint, - orientation orientation = B_HORIZONTAL); - - void _MakeGradient(BGradientLinear& gradient, - const BRect& rect, const rgb_color& base, - float topTint, float bottomTint, - orientation orientation = B_HORIZONTAL) const; - - void _MakeGlossyGradient(BGradientLinear& gradient, - const BRect& rect, const rgb_color& base, - float topTint, float middle1Tint, - float middle2Tint, float bottomTint, - orientation orientation = B_HORIZONTAL) const; - - void _MakeButtonGradient(BGradientLinear& gradient, - BRect& rect, const rgb_color& base, - uint32 flags, orientation orientation = B_HORIZONTAL) const; - - bool _RadioButtonAndCheckBoxMarkColor( - const rgb_color& base, rgb_color& color, - uint32 flags) const; - -private: - bool fCachedOutline; int32 fCachedWorkspace; BMessage fBackgroundInfo; diff --git a/headers/private/interface/HaikuControlLook.h b/headers/private/interface/HaikuControlLook.h new file mode 100644 index 0000000000..09d8e69614 --- /dev/null +++ b/headers/private/interface/HaikuControlLook.h @@ -0,0 +1,569 @@ +/* + * Copyright 2009-2017, Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + */ +#ifndef _HAIKU_CONTROL_LOOK_H +#define _HAIKU_CONTROL_LOOK_H + + +#include + + +class BBitmap; +class BControl; +class BGradientLinear; +class BView; + + +namespace BPrivate { + + +class HaikuControlLook : public BControlLook { +public: + HaikuControlLook(); + virtual ~HaikuControlLook(); + + virtual BAlignment DefaultLabelAlignment() const; + virtual float DefaultLabelSpacing() const; + + virtual float DefaultItemSpacing() const; + + static float ComposeSpacing(float spacing); + + virtual uint32 Flags(BControl* control) const; + + virtual void DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + virtual void DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, + float radius, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + virtual void DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + virtual void DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, + float radius, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + virtual void DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + + virtual void DrawMenuBarBackground(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + virtual void DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, + float radius, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + virtual void DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + const rgb_color& background, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawMenuFieldBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, bool popupIndicator, + uint32 flags = 0); + virtual void DrawMenuFieldBackground(BView* view, + BRect& rect, const BRect& updateRect, + float radius, const rgb_color& base, + bool popupIndicator, uint32 flags = 0); + virtual void DrawMenuFieldBackground(BView* view, + BRect& rect, const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + bool popupIndicator, uint32 flags = 0); + virtual void DrawMenuFieldBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawMenuBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawMenuItemBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawStatusBar(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + const rgb_color& barColor, + float progressPosition); + + virtual void DrawCheckBox(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + uint32 flags = 0); + + virtual void DrawRadioButton(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + uint32 flags = 0); + + virtual void DrawScrollBarBackground(BView* view, + BRect& rect1, BRect& rect2, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation); + virtual void DrawScrollBarBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation); + + virtual void DrawScrollViewFrame(BView* view, + BRect& rect, const BRect& updateRect, + BRect verticalScrollBarFrame, + BRect horizontalScrollBarFrame, + const rgb_color& base, + border_style borderStyle, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawArrowShape(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 direction, + uint32 flags = 0, + float tint = B_DARKEN_MAX_TINT); + + virtual rgb_color SliderBarColor(const rgb_color& base); + + virtual void DrawSliderBar(BView* view, BRect rect, + const BRect& updateRect, + const rgb_color& base, + rgb_color leftFillColor, + rgb_color rightFillColor, + float sliderScale, uint32 flags, + orientation orientation); + virtual void DrawSliderBar(BView* view, BRect rect, + const BRect& updateRect, + const rgb_color& base, rgb_color fillColor, + uint32 flags, orientation orientation); + + virtual void DrawSliderThumb(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation); + + virtual void DrawSliderTriangle(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + orientation orientation); + virtual void DrawSliderTriangle(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + const rgb_color& fill, uint32 flags, + orientation orientation); + + virtual void DrawSliderHashMarks(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, int32 count, + hash_mark_location location, + uint32 flags, orientation orientation); + + virtual void DrawActiveTab(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + uint32 side = B_TOP_BORDER); + + virtual void DrawInactiveTab(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + uint32 side = B_TOP_BORDER); + + virtual void DrawSplitter(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + orientation orientation, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + // various borders + + virtual void DrawBorder(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + border_style borderStyle, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawRaisedBorder(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawGroupFrame(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawTextControlBorder(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + // aligned labels + + virtual void DrawLabel(BView* view, const char* label, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + const rgb_color* textColor = NULL); + virtual void DrawLabel(BView* view, const char* label, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + const BAlignment& alignment, + const rgb_color* textColor = NULL); + // TODO: Would be nice to have a (non-virtual) version of this method + // which takes an array of labels and locations. That would save some + // setup with the view graphics state. + virtual void DrawLabel(BView* view, const char* label, + const rgb_color& base, uint32 flags, + const BPoint& where, + const rgb_color* textColor = NULL); + + virtual void DrawLabel(BView* view, const char* label, + const BBitmap* icon, BRect rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + const BAlignment& alignment, + const rgb_color* textColor = NULL); + + virtual void GetFrameInsets(frame_type frameType, + uint32 flags, float& _left, float& _top, + float& _right, float& _bottom); + virtual void GetBackgroundInsets( + background_type backgroundType, + uint32 flags, float& _left, float& _top, + float& _right, float& _bottom); + + virtual void DrawButtonWithPopUpBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + virtual void DrawButtonWithPopUpBackground(BView* view, + BRect& rect, const BRect& updateRect, + float radius, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + virtual void DrawButtonWithPopUpBackground(BView* view, + BRect& rect, const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + +protected: + void _DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + const rgb_color& background, + float contrast, float brightness = 1.0, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + void _DrawOuterResessedFrame(BView* view, + BRect& rect, const rgb_color& base, + float contrast = 1.0f, + float brightness = 1.0f, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + void _DrawFrame(BView* view, BRect& rect, + const rgb_color& left, + const rgb_color& top, + const rgb_color& right, + const rgb_color& bottom, + uint32 borders = B_ALL_BORDERS); + void _DrawFrame(BView* view, BRect& rect, + const rgb_color& left, + const rgb_color& top, + const rgb_color& right, + const rgb_color& bottom, + const rgb_color& rightTop, + const rgb_color& leftBottom, + uint32 borders = B_ALL_BORDERS); + + void _DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + bool popupIndicator = false, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + void _DrawFlatButtonBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, + bool popupIndicator = false, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + void _DrawNonFlatButtonBackground(BView* view, + BRect& rect, const BRect& updateRect, + BRegion& clipping, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + bool popupIndicator = false, + uint32 flags = 0, + uint32 borders = B_ALL_BORDERS, + orientation orientation = B_HORIZONTAL); + + void _DrawPopUpMarker(BView* view, const BRect& rect, + const rgb_color& base, uint32 flags); + + void _DrawMenuFieldBackgroundOutside(BView* view, + BRect& rect, const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, + bool popupIndicator = false, + uint32 flags = 0); + + void _DrawMenuFieldBackgroundInside(BView* view, + BRect& rect, const BRect& updateRect, + float leftTopRadius, + float rightTopRadius, + float leftBottomRadius, + float rightBottomRadius, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + // Rounded corner methods + void _DrawRoundCornerLeftTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeColor, + const rgb_color& frameColor, + const rgb_color& bevelColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerFrameLeftTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeColor, + const rgb_color& frameColor); + + void _DrawRoundCornerBackgroundLeftTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& bevelColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerRightTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeTopColor, + const rgb_color& edgeRightColor, + const rgb_color& frameTopColor, + const rgb_color& frameRightColor, + const rgb_color& bevelTopColor, + const rgb_color& bevelRightColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerFrameRightTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeTopColor, + const rgb_color& edgeRightColor, + const rgb_color& frameTopColor, + const rgb_color& frameRightColor); + + void _DrawRoundCornerBackgroundRightTop(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& bevelTopColor, + const rgb_color& bevelRightColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerLeftBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeLeftColor, + const rgb_color& edgeBottomColor, + const rgb_color& frameLeftColor, + const rgb_color& frameBottomColor, + const rgb_color& bevelLeftColor, + const rgb_color& bevelBottomColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerFrameLeftBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeLeftColor, + const rgb_color& edgeBottomColor, + const rgb_color& frameLeftColor, + const rgb_color& frameBottomColor); + + void _DrawRoundCornerBackgroundLeftBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& bevelLeftColor, + const rgb_color& bevelBottomColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerRightBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeColor, + const rgb_color& frameColor, + const rgb_color& bevelColor, + const BGradientLinear& fillGradient); + + void _DrawRoundCornerFrameRightBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& background, + const rgb_color& edgeColor, + const rgb_color& frameColor); + + void _DrawRoundCornerBackgroundRightBottom( + BView* view, + BRect& cornerRect, const BRect& updateRect, + const rgb_color& bevelColor, + const BGradientLinear& fillGradient); + + void _DrawRoundBarCorner(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& edgeLightColor, + const rgb_color& edgeShadowColor, + const rgb_color& frameLightColor, + const rgb_color& frameShadowColor, + const rgb_color& fillLightColor, + const rgb_color& fillShadowColor, + float leftInset, float topInset, + float rightInset, float bottomInset, + orientation orientation); + + // Border color methods + rgb_color _EdgeLightColor(const rgb_color& base, + float contrast, float brightness, + uint32 flags); + + rgb_color _EdgeShadowColor(const rgb_color& base, + float contrast, float brightness, + uint32 flags); + + rgb_color _FrameLightColor(const rgb_color& base, + uint32 flags); + + rgb_color _FrameShadowColor(const rgb_color& base, + uint32 flags); + + rgb_color _BevelLightColor(const rgb_color& base, + uint32 flags); + + rgb_color _BevelShadowColor(const rgb_color& base, + uint32 flags); + + // Background gradient methods + void _FillGradient(BView* view, const BRect& rect, + const rgb_color& base, float topTint, + float bottomTint, + orientation orientation = B_HORIZONTAL); + + void _FillGlossyGradient(BView* view, + const BRect& rect, const rgb_color& base, + float topTint, float middle1Tint, + float middle2Tint, float bottomTint, + orientation orientation = B_HORIZONTAL); + + void _MakeGradient(BGradientLinear& gradient, + const BRect& rect, const rgb_color& base, + float topTint, float bottomTint, + orientation orientation = B_HORIZONTAL) const; + + void _MakeGlossyGradient(BGradientLinear& gradient, + const BRect& rect, const rgb_color& base, + float topTint, float middle1Tint, + float middle2Tint, float bottomTint, + orientation orientation = B_HORIZONTAL) const; + + void _MakeButtonGradient(BGradientLinear& gradient, + BRect& rect, const rgb_color& base, + uint32 flags, orientation orientation = B_HORIZONTAL) const; + + bool _RadioButtonAndCheckBoxMarkColor( + const rgb_color& base, rgb_color& color, + uint32 flags) const; + +private: + bool fCachedOutline; +}; + + +} // namespace BPrivate + +#endif // _HAIKU_CONTROL_LOOK_H diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp index f1dd1a0506..3b0283fe5e 100644 --- a/src/kits/interface/ControlLook.cpp +++ b/src/kits/interface/ControlLook.cpp @@ -1,42 +1,17 @@ /* - * Copyright 2009, Stephan Aßmus - * Copyright 2012-2015 Haiku, Inc. All rights reserved. + * Copyright 2012-2017 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. - * - * Authors: - * Stephan Aßmus, superstippi@gmx.de - * John Scipione, jscipione@gmail.com */ #include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - namespace BPrivate { -static const float kEdgeBevelLightTint = 0.59; -static const float kEdgeBevelShadowTint = 1.0735; -static const float kHoverTintFactor = 0.85; - -static const float kButtonPopUpIndicatorWidth = 11; - - -BControlLook::BControlLook(): - fCachedOutline(false), +BControlLook::BControlLook() + : fCachedWorkspace(-1) { } @@ -47,27 +22,6 @@ BControlLook::~BControlLook() } -BAlignment -BControlLook::DefaultLabelAlignment() const -{ - return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); -} - - -float -BControlLook::DefaultLabelSpacing() const -{ - return ceilf(be_plain_font->Size() / 2.0); -} - - -float -BControlLook::DefaultItemSpacing() const -{ - return ceilf(be_plain_font->Size() * 0.85); -} - - float BControlLook::ComposeSpacing(float spacing) { @@ -89,1926 +43,6 @@ BControlLook::ComposeSpacing(float spacing) } -uint32 -BControlLook::Flags(BControl* control) const -{ - uint32 flags = B_IS_CONTROL; - - if (!control->IsEnabled()) - flags |= B_DISABLED; - - if (control->IsFocus() && control->Window() != NULL - && control->Window()->IsActive()) { - flags |= B_FOCUSED; - } - - switch (control->Value()) { - case B_CONTROL_ON: - flags |= B_ACTIVATED; - break; - case B_CONTROL_PARTIALLY_ON: - flags |= B_PARTIALLY_ACTIVATED; - break; - } - - if (control->Parent() != NULL - && (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) { - // In this constellation, assume we want to render the control - // against the already existing view contents of the parent view. - flags |= B_BLEND_FRAME; - } - - return flags; -} - - -// #pragma mark - - - -void -BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, const rgb_color& background, uint32 flags, - uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, - background, 1.0, 1.0, flags, borders); -} - - -void -BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, - float radius, const rgb_color& base, const rgb_color& background, uint32 flags, - uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, - base, background, 1.0, 1.0, flags, borders); -} - - -void -BControlLook::DrawButtonFrame(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - const rgb_color& background, uint32 flags, - uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, - leftBottomRadius, rightBottomRadius, base, background, - 1.0, 1.0, flags, borders); -} - - -void -BControlLook::DrawButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, - base, false, flags, borders, orientation); -} - - -void -BControlLook::DrawButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, - uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, - radius, base, false, flags, borders, orientation); -} - - -void -BControlLook::DrawButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - uint32 flags, uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, leftTopRadius, - rightTopRadius, leftBottomRadius, rightBottomRadius, base, false, flags, - borders, orientation); -} - - -void -BControlLook::DrawMenuBarBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // the surface edges - - // colors - float topTint; - float bottomTint; - - if ((flags & B_ACTIVATED) != 0) { - rgb_color bevelColor1 = tint_color(base, 1.40); - rgb_color bevelColor2 = tint_color(base, 1.25); - - topTint = 1.25; - bottomTint = 1.20; - - _DrawFrame(view, rect, - bevelColor1, bevelColor1, - bevelColor2, bevelColor2, - borders & B_TOP_BORDER); - } else { - rgb_color cornerColor = tint_color(base, 0.9); - rgb_color bevelColorTop = tint_color(base, 0.5); - rgb_color bevelColorLeft = tint_color(base, 0.7); - rgb_color bevelColorRightBottom = tint_color(base, 1.08); - - topTint = 0.69; - bottomTint = 1.03; - - _DrawFrame(view, rect, - bevelColorLeft, bevelColorTop, - bevelColorRightBottom, bevelColorRightBottom, - cornerColor, cornerColor, - borders); - } - - // draw surface top - _FillGradient(view, rect, base, topTint, bottomTint); -} - - -void -BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, - const rgb_color& background, uint32 flags, uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, - background, 0.6, 1.0, flags, borders); -} - - -void -BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, - const BRect& updateRect, float radius, const rgb_color& base, - const rgb_color& background, uint32 flags, uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, - base, background, 0.6, 1.0, flags, borders); -} - - -void -BControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, - float rightTopRadius, float leftBottomRadius, - float rightBottomRadius, const rgb_color& base, - const rgb_color& background, uint32 flags, uint32 borders) -{ - _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, - leftBottomRadius, rightBottomRadius, base, background, 0.6, 1.0, - flags, borders); -} - - -void -BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, bool popupIndicator, - uint32 flags) -{ - _DrawMenuFieldBackgroundOutside(view, rect, updateRect, - 0.0f, 0.0f, 0.0f, 0.0f, base, popupIndicator, flags); -} - - -void -BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - _DrawMenuFieldBackgroundInside(view, rect, updateRect, - 0.0f, 0.0f, 0.0f, 0.0f, base, flags, borders); -} - - -void -BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, - const BRect& updateRect, float radius, const rgb_color& base, - bool popupIndicator, uint32 flags) -{ - _DrawMenuFieldBackgroundOutside(view, rect, updateRect, radius, radius, - radius, radius, base, popupIndicator, flags); -} - - -void -BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - bool popupIndicator, uint32 flags) -{ - _DrawMenuFieldBackgroundOutside(view, rect, updateRect, leftTopRadius, - rightTopRadius, leftBottomRadius, rightBottomRadius, base, - popupIndicator, flags); -} - - -void -BControlLook::DrawMenuBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // surface top color - rgb_color background = tint_color(base, 0.75); - - // inner bevel colors - rgb_color bevelLightColor; - rgb_color bevelShadowColor; - - if ((flags & B_DISABLED) != 0) { - bevelLightColor = tint_color(background, 0.80); - bevelShadowColor = tint_color(background, 1.07); - } else { - bevelLightColor = tint_color(background, 0.6); - bevelShadowColor = tint_color(background, 1.12); - } - - // draw inner bevel - _DrawFrame(view, rect, - bevelLightColor, bevelLightColor, - bevelShadowColor, bevelShadowColor, - borders); - - // draw surface top - view->SetHighColor(background); - view->FillRect(rect); -} - - -void -BControlLook::DrawMenuItemBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // surface edges - float topTint; - float bottomTint; - rgb_color selectedColor = base; - - if ((flags & B_ACTIVATED) != 0) { - topTint = 0.9; - bottomTint = 1.05; - } else if ((flags & B_DISABLED) != 0) { - topTint = 0.80; - bottomTint = 1.07; - } else { - topTint = 0.6; - bottomTint = 1.12; - } - - rgb_color bevelLightColor = tint_color(selectedColor, topTint); - rgb_color bevelShadowColor = tint_color(selectedColor, bottomTint); - - // draw surface edges - _DrawFrame(view, rect, - bevelLightColor, bevelLightColor, - bevelShadowColor, bevelShadowColor, - borders); - - // draw surface top - view->SetLowColor(selectedColor); -// _FillGradient(view, rect, selectedColor, topTint, bottomTint); - _FillGradient(view, rect, selectedColor, bottomTint, topTint); -} - - -void -BControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, const rgb_color& barColor, float progressPosition) -{ - if (!rect.Intersects(updateRect)) - return; - - _DrawOuterResessedFrame(view, rect, base, 0.6); - - // colors - rgb_color dark1BorderColor = tint_color(base, 1.3); - rgb_color dark2BorderColor = tint_color(base, 1.2); - rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20); - rgb_color dark2FilledBorderColor = tint_color(barColor, 1.45); - - BRect filledRect(rect); - filledRect.right = progressPosition - 1; - - BRect nonfilledRect(rect); - nonfilledRect.left = progressPosition; - - bool filledSurface = filledRect.Width() > 0; - bool nonfilledSurface = nonfilledRect.Width() > 0; - - if (filledSurface) { - _DrawFrame(view, filledRect, - dark1FilledBorderColor, dark1FilledBorderColor, - dark2FilledBorderColor, dark2FilledBorderColor); - - _FillGlossyGradient(view, filledRect, barColor, 0.55, 0.68, 0.76, 0.90); - } - - if (nonfilledSurface) { - _DrawFrame(view, nonfilledRect, dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor, - B_TOP_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); - - if (nonfilledRect.left < nonfilledRect.right) { - // shadow from fill bar, or left border - rgb_color leftBorder = dark1BorderColor; - if (filledSurface) - leftBorder = tint_color(base, 0.50); - view->SetHighColor(leftBorder); - view->StrokeLine(nonfilledRect.LeftTop(), - nonfilledRect.LeftBottom()); - nonfilledRect.left++; - } - - _FillGradient(view, nonfilledRect, base, 0.25, 0.06); - } -} - - -void -BControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 flags) -{ - if (!rect.Intersects(updateRect)) - return; - - rgb_color dark1BorderColor; - rgb_color dark2BorderColor; - rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - if ((flags & B_DISABLED) != 0) { - _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags); - - dark1BorderColor = tint_color(base, 1.15); - dark2BorderColor = tint_color(base, 1.15); - } else if ((flags & B_CLICKED) != 0) { - dark1BorderColor = tint_color(base, 1.50); - dark2BorderColor = tint_color(base, 1.48); - - _DrawFrame(view, rect, - dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor); - - dark2BorderColor = dark1BorderColor; - } else { - _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags); - - dark1BorderColor = tint_color(base, 1.40); - dark2BorderColor = tint_color(base, 1.38); - } - - if ((flags & B_FOCUSED) != 0) { - dark1BorderColor = navigationColor; - dark2BorderColor = navigationColor; - } - - _DrawFrame(view, rect, - dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor); - - if ((flags & B_DISABLED) != 0) - _FillGradient(view, rect, base, 0.4, 0.2); - else - _FillGradient(view, rect, base, 0.15, 0.0); - - rgb_color markColor; - if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { - view->SetHighColor(markColor); - - BFont font; - view->GetFont(&font); - float inset = std::max(2.0f, roundf(font.Size() / 6)); - rect.InsetBy(inset, inset); - - float penSize = std::max(1.0f, ceilf(rect.Width() / 3.5f)); - if (penSize > 1.0f && fmodf(penSize, 2.0f) == 0.0f) { - // Tweak ends to "include" the pixel at the index, - // we need to do this in order to produce results like R5, - // where coordinates were inclusive - rect.right++; - rect.bottom++; - } - - view->SetPenSize(penSize); - view->SetDrawingMode(B_OP_OVER); - view->StrokeLine(rect.LeftTop(), rect.RightBottom()); - view->StrokeLine(rect.LeftBottom(), rect.RightTop()); - } -} - - -void -BControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 flags) -{ - if (!rect.Intersects(updateRect)) - return; - - rgb_color borderColor; - rgb_color bevelLight; - rgb_color bevelShadow; - rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - if ((flags & B_DISABLED) != 0) { - borderColor = tint_color(base, 1.15); - bevelLight = base; - bevelShadow = base; - } else if ((flags & B_CLICKED) != 0) { - borderColor = tint_color(base, 1.50); - bevelLight = borderColor; - bevelShadow = borderColor; - } else { - borderColor = tint_color(base, 1.45); - bevelLight = tint_color(base, 0.55); - bevelShadow = tint_color(base, 1.11); - } - - if ((flags & B_FOCUSED) != 0) { - borderColor = navigationColor; - } - - BGradientLinear bevelGradient; - bevelGradient.AddColor(bevelShadow, 0); - bevelGradient.AddColor(bevelLight, 255); - bevelGradient.SetStart(rect.LeftTop()); - bevelGradient.SetEnd(rect.RightBottom()); - - view->FillEllipse(rect, bevelGradient); - rect.InsetBy(1, 1); - - bevelGradient.MakeEmpty(); - bevelGradient.AddColor(borderColor, 0); - bevelGradient.AddColor(tint_color(borderColor, 0.8), 255); - view->FillEllipse(rect, bevelGradient); - rect.InsetBy(1, 1); - - float topTint; - float bottomTint; - if ((flags & B_DISABLED) != 0) { - topTint = 0.4; - bottomTint = 0.2; - } else { - topTint = 0.15; - bottomTint = 0.0; - } - - BGradientLinear gradient; - _MakeGradient(gradient, rect, base, topTint, bottomTint); - view->FillEllipse(rect, gradient); - - rgb_color markColor; - if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { - view->SetHighColor(markColor); - BFont font; - view->GetFont(&font); - float inset = roundf(font.Size() / 4); - rect.InsetBy(inset, inset); - view->FillEllipse(rect); - } -} - - -void -BControlLook::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); -} - - -void -BControlLook::DrawScrollBarBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - 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 { - gradient1Tint = 1.10; - gradient2Tint = 1.05; - darkEdge1Tint = B_DARKEN_3_TINT; - darkEdge2Tint = B_DARKEN_2_TINT; - shadowTint = gradient1Tint; - } - - rgb_color darkEdge1 = tint_color(base, darkEdge1Tint); - rgb_color darkEdge2 = tint_color(base, darkEdge2Tint); - rgb_color shadow = tint_color(base, shadowTint); - - if (orientation == B_HORIZONTAL) { - // dark vertical line on left edge - if (rect.Width() > 0) { - view->SetHighColor(darkEdge1); - view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); - rect.left++; - } - // dark vertical line on right edge - if (rect.Width() >= 0) { - view->SetHighColor(darkEdge2); - view->StrokeLine(rect.RightTop(), rect.RightBottom()); - rect.right--; - } - // vertical shadow line after left edge - if (rect.Width() >= 0) { - view->SetHighColor(shadow); - view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); - rect.left++; - } - // fill - if (rect.Width() >= 0) { - _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, - orientation); - } - } else { - // dark vertical line on top edge - if (rect.Height() > 0) { - view->SetHighColor(darkEdge1); - view->StrokeLine(rect.LeftTop(), rect.RightTop()); - rect.top++; - } - // dark vertical line on bottom edge - if (rect.Height() >= 0) { - view->SetHighColor(darkEdge2); - view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); - rect.bottom--; - } - // horizontal shadow line after top edge - if (rect.Height() >= 0) { - view->SetHighColor(shadow); - view->StrokeLine(rect.LeftTop(), rect.RightTop()); - rect.top++; - } - // fill - if (rect.Height() >= 0) { - _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, - orientation); - } - } -} - - -void -BControlLook::DrawScrollViewFrame(BView* view, BRect& rect, - const BRect& updateRect, BRect verticalScrollBarFrame, - BRect horizontalScrollBarFrame, const rgb_color& base, - border_style borderStyle, uint32 flags, uint32 _borders) -{ - // calculate scroll corner rect before messing with the "rect" - BRect scrollCornerFillRect(rect.right, rect.bottom, - rect.right, rect.bottom); - - if (horizontalScrollBarFrame.IsValid()) - scrollCornerFillRect.left = horizontalScrollBarFrame.right + 1; - - if (verticalScrollBarFrame.IsValid()) - scrollCornerFillRect.top = verticalScrollBarFrame.bottom + 1; - - if (borderStyle == B_NO_BORDER) { - if (scrollCornerFillRect.IsValid()) { - view->SetHighColor(base); - view->FillRect(scrollCornerFillRect); - } - return; - } - - bool excludeScrollCorner = borderStyle == B_FANCY_BORDER - && horizontalScrollBarFrame.IsValid() - && verticalScrollBarFrame.IsValid(); - - uint32 borders = _borders; - if (excludeScrollCorner) { - rect.bottom = horizontalScrollBarFrame.top; - rect.right = verticalScrollBarFrame.left; - borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER); - } - - rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); - - if (borderStyle == B_FANCY_BORDER) - _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); - - if ((flags & B_FOCUSED) != 0) { - rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - _DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor, - borders); - } else { - _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, - scrollbarFrameColor, scrollbarFrameColor, borders); - } - - if (excludeScrollCorner) { - horizontalScrollBarFrame.InsetBy(-1, -1); - // do not overdraw the top edge - horizontalScrollBarFrame.top += 2; - borders = _borders; - borders &= ~B_TOP_BORDER; - _DrawOuterResessedFrame(view, horizontalScrollBarFrame, base, - 1.0, 1.0, flags, borders); - _DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor, - scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, - borders); - - verticalScrollBarFrame.InsetBy(-1, -1); - // do not overdraw the left edge - verticalScrollBarFrame.left += 2; - borders = _borders; - borders &= ~B_LEFT_BORDER; - _DrawOuterResessedFrame(view, verticalScrollBarFrame, base, - 1.0, 1.0, flags, borders); - _DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor, - scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, - borders); - - // exclude recessed frame - scrollCornerFillRect.top++; - scrollCornerFillRect.left++; - } - - if (scrollCornerFillRect.IsValid()) { - view->SetHighColor(base); - view->FillRect(scrollCornerFillRect); - } -} - - -void -BControlLook::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; - float vInset = rect.Height() / 3; - rect.InsetBy(hInset, vInset); - - switch (direction) { - case B_LEFT_ARROW: - tri1.Set(rect.right, rect.top); - tri2.Set(rect.right - rect.Width() / 1.33, - (rect.top + rect.bottom + 1) / 2); - tri3.Set(rect.right, rect.bottom + 1); - break; - case B_RIGHT_ARROW: - tri1.Set(rect.left + 1, rect.bottom + 1); - tri2.Set(rect.left + 1 + rect.Width() / 1.33, - (rect.top + rect.bottom + 1) / 2); - tri3.Set(rect.left + 1, rect.top); - break; - case B_UP_ARROW: - tri1.Set(rect.left, rect.bottom); - tri2.Set((rect.left + rect.right + 1) / 2, - rect.bottom - rect.Height() / 1.33); - tri3.Set(rect.right + 1, rect.bottom); - break; - case B_DOWN_ARROW: - default: - tri1.Set(rect.left, rect.top + 1); - tri2.Set((rect.left + rect.right + 1) / 2, - rect.top + 1 + rect.Height() / 1.33); - tri3.Set(rect.right + 1, rect.top + 1); - break; - case B_LEFT_UP_ARROW: - tri1.Set(rect.left, rect.bottom); - tri2.Set(rect.left, rect.top); - tri3.Set(rect.right - 1, rect.top); - break; - case B_RIGHT_UP_ARROW: - tri1.Set(rect.left + 1, rect.top); - tri2.Set(rect.right, rect.top); - tri3.Set(rect.right, rect.bottom); - break; - case B_RIGHT_DOWN_ARROW: - tri1.Set(rect.right, rect.top); - tri2.Set(rect.right, rect.bottom); - tri3.Set(rect.left + 1, rect.bottom); - break; - case B_LEFT_DOWN_ARROW: - tri1.Set(rect.right - 1, rect.bottom); - tri2.Set(rect.left, rect.bottom); - tri3.Set(rect.left, rect.top); - break; - } - - BShape arrowShape; - arrowShape.MoveTo(tri1); - arrowShape.LineTo(tri2); - arrowShape.LineTo(tri3); - - if ((flags & B_DISABLED) != 0) - tint = (tint + B_NO_TINT + B_NO_TINT) / 3; - - view->SetHighColor(tint_color(base, tint)); - - float penSize = view->PenSize(); - drawing_mode mode = view->DrawingMode(); - - view->MovePenTo(BPoint(0, 0)); - - view->SetPenSize(ceilf(hInset / 2.0)); - view->SetDrawingMode(B_OP_OVER); - view->StrokeShape(&arrowShape); - - view->SetPenSize(penSize); - view->SetDrawingMode(mode); -} - - -rgb_color -BControlLook::SliderBarColor(const rgb_color& base) -{ - return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); -} - - -void -BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, - const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, - float sliderScale, uint32 flags, orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // save the clipping constraints of the view - view->PushState(); - - // separate the bar in two sides - float sliderPosition; - BRect leftBarSide = rect; - BRect rightBarSide = rect; - - if (orientation == B_HORIZONTAL) { - sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) - * sliderScale); - leftBarSide.right = sliderPosition - 1; - rightBarSide.left = sliderPosition; - } else { - // NOTE: position is reverse of coords - sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) - * (1.0 - sliderScale)); - leftBarSide.top = sliderPosition; - rightBarSide.bottom = sliderPosition - 1; - } - - // fill the background for the corners, exclude the middle bar for now - BRegion region(rect); - region.Exclude(rightBarSide); - view->ConstrainClippingRegion(®ion); - - view->PushState(); - - DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, - orientation); - - view->PopState(); - - region.Set(rect); - region.Exclude(leftBarSide); - view->ConstrainClippingRegion(®ion); - - view->PushState(); - - DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, - orientation); - - view->PopState(); - - // restore the clipping constraints of the view - view->PopState(); -} - - -void -BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, - const rgb_color& base, rgb_color fillColor, uint32 flags, - orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // separate the rect into corners - BRect leftCorner(rect); - BRect rightCorner(rect); - BRect barRect(rect); - - if (orientation == B_HORIZONTAL) { - leftCorner.right = leftCorner.left + leftCorner.Height(); - rightCorner.left = rightCorner.right - rightCorner.Height(); - barRect.left += ceilf(barRect.Height() / 2); - barRect.right -= ceilf(barRect.Height() / 2); - } else { - leftCorner.bottom = leftCorner.top + leftCorner.Width(); - rightCorner.top = rightCorner.bottom - rightCorner.Width(); - barRect.top += ceilf(barRect.Width() / 2); - barRect.bottom -= ceilf(barRect.Width() / 2); - } - - // fill the background for the corners, exclude the middle bar for now - BRegion region(rect); - region.Exclude(barRect); - view->ConstrainClippingRegion(®ion); - - if ((flags & B_BLEND_FRAME) == 0) { - view->SetHighColor(base); - view->FillRect(rect); - } - - // figure out the tints to be used - float edgeLightTint; - float edgeShadowTint; - float frameLightTint; - float frameShadowTint; - float fillLightTint; - float fillShadowTint; - uint8 edgeLightAlpha; - uint8 edgeShadowAlpha; - uint8 frameLightAlpha; - uint8 frameShadowAlpha; - - if ((flags & B_DISABLED) != 0) { - edgeLightTint = 1.0; - edgeShadowTint = 1.0; - frameLightTint = 1.20; - frameShadowTint = 1.25; - fillLightTint = 0.9; - fillShadowTint = 1.05; - edgeLightAlpha = 12; - edgeShadowAlpha = 12; - frameLightAlpha = 40; - frameShadowAlpha = 45; - - fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); - fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); - fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); - } else { - edgeLightTint = 0.65; - edgeShadowTint = 1.07; - frameLightTint = 1.40; - frameShadowTint = 1.50; - fillLightTint = 0.8; - fillShadowTint = 1.1; - edgeLightAlpha = 15; - edgeShadowAlpha = 15; - frameLightAlpha = 92; - frameShadowAlpha = 107; - } - - rgb_color edgeLightColor; - rgb_color edgeShadowColor; - rgb_color frameLightColor; - rgb_color frameShadowColor; - rgb_color fillLightColor = tint_color(fillColor, fillLightTint); - rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); - - drawing_mode oldMode = view->DrawingMode(); - - if ((flags & B_BLEND_FRAME) != 0) { - edgeLightColor = (rgb_color){ 255, 255, 255, edgeLightAlpha }; - edgeShadowColor = (rgb_color){ 0, 0, 0, edgeShadowAlpha }; - frameLightColor = (rgb_color){ 0, 0, 0, frameLightAlpha }; - frameShadowColor = (rgb_color){ 0, 0, 0, frameShadowAlpha }; - - view->SetDrawingMode(B_OP_ALPHA); - } else { - edgeLightColor = tint_color(base, edgeLightTint); - edgeShadowColor = tint_color(base, edgeShadowTint); - frameLightColor = tint_color(fillColor, frameLightTint); - frameShadowColor = tint_color(fillColor, frameShadowTint); - } - - if (orientation == B_HORIZONTAL) { - _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, - edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, - fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); - - _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, - edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, - fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); - } else { - _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, - edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, - fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); - - _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, - edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, - fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); - } - - view->ConstrainClippingRegion(NULL); - - view->BeginLineArray(4); - if (orientation == B_HORIZONTAL) { - 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.LeftBottom(), barRect.RightBottom(), - frameLightColor); - barRect.InsetBy(0, 1); - } else { - 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.RightTop(), barRect.RightBottom(), - frameLightColor); - barRect.InsetBy(1, 0); - } - view->EndLineArray(); - - view->SetDrawingMode(oldMode); - - _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, - orientation); -} - - -void -BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 flags, orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // figure out frame color - rgb_color frameLightColor; - rgb_color frameShadowColor; - rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; - - if ((flags & B_FOCUSED) != 0) { - // focused - frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - frameShadowColor = frameLightColor; - } else { - // figure out the tints to be used - float frameLightTint; - float frameShadowTint; - - if ((flags & B_DISABLED) != 0) { - frameLightTint = 1.30; - frameShadowTint = 1.35; - shadowColor.alpha = 30; - } else { - frameLightTint = 1.6; - frameShadowTint = 1.65; - } - - frameLightColor = tint_color(base, frameLightTint); - frameShadowColor = tint_color(base, frameShadowTint); - } - - BRect originalRect(rect); - rect.right--; - rect.bottom--; - - _DrawFrame(view, rect, frameLightColor, frameLightColor, - frameShadowColor, frameShadowColor); - - flags &= ~B_ACTIVATED; - DrawButtonBackground(view, rect, updateRect, base, flags); - - // thumb shadow - view->SetDrawingMode(B_OP_ALPHA); - view->SetHighColor(shadowColor); - originalRect.left++; - originalRect.top++; - view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); - originalRect.bottom--; - view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); - - // thumb edge - if (orientation == B_HORIZONTAL) { - rect.InsetBy(0, floorf(rect.Height() / 4)); - rect.left = floorf((rect.left + rect.right) / 2); - rect.right = rect.left + 1; - shadowColor = tint_color(base, B_DARKEN_2_TINT); - shadowColor.alpha = 128; - view->SetHighColor(shadowColor); - view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); - rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); - lightColor.alpha = 128; - view->SetHighColor(lightColor); - view->StrokeLine(rect.RightTop(), rect.RightBottom()); - } else { - rect.InsetBy(floorf(rect.Width() / 4), 0); - rect.top = floorf((rect.top + rect.bottom) / 2); - rect.bottom = rect.top + 1; - shadowColor = tint_color(base, B_DARKEN_2_TINT); - shadowColor.alpha = 128; - view->SetHighColor(shadowColor); - view->StrokeLine(rect.LeftTop(), rect.RightTop()); - rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); - lightColor.alpha = 128; - view->SetHighColor(lightColor); - view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); - } - - view->SetDrawingMode(B_OP_COPY); -} - - -void -BControlLook::DrawSliderTriangle(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - orientation orientation) -{ - DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); -} - - -void -BControlLook::DrawSliderTriangle(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, const rgb_color& fill, - uint32 flags, orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // figure out frame color - rgb_color frameLightColor; - rgb_color frameShadowColor; - rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; - - float topTint = 0.49; - float middleTint1 = 0.62; - float middleTint2 = 0.76; - float bottomTint = 0.90; - - if ((flags & B_DISABLED) != 0) { - topTint = (topTint + B_NO_TINT) / 2; - middleTint1 = (middleTint1 + B_NO_TINT) / 2; - middleTint2 = (middleTint2 + B_NO_TINT) / 2; - bottomTint = (bottomTint + B_NO_TINT) / 2; - } else if ((flags & B_HOVER) != 0) { - topTint *= kHoverTintFactor; - middleTint1 *= kHoverTintFactor; - middleTint2 *= kHoverTintFactor; - bottomTint *= kHoverTintFactor; - } - - if ((flags & B_FOCUSED) != 0) { - // focused - frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - frameShadowColor = frameLightColor; - } else { - // figure out the tints to be used - float frameLightTint; - float frameShadowTint; - - if ((flags & B_DISABLED) != 0) { - frameLightTint = 1.30; - frameShadowTint = 1.35; - shadowColor.alpha = 30; - } else { - frameLightTint = 1.6; - frameShadowTint = 1.65; - } - - frameLightColor = tint_color(base, frameLightTint); - frameShadowColor = tint_color(base, frameShadowTint); - } - - // make room for the shadow - rect.right--; - rect.bottom--; - - uint32 viewFlags = view->Flags(); - view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); - view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); - - float centerh = (rect.left + rect.right) / 2; - float centerv = (rect.top + rect.bottom) / 2; - - BShape shape; - if (orientation == B_HORIZONTAL) { - shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); - shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); - shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); - shape.LineTo(BPoint(centerh + 0.5, rect.top + 0.5)); - shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); - } else { - shape.MoveTo(BPoint(rect.right + 0.5, rect.top + 0.5)); - shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); - shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.bottom + 0.5)); - shape.LineTo(BPoint(rect.left + 0.5, centerv + 0.5)); - shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.top + 0.5)); - } - shape.Close(); - - view->MovePenTo(BPoint(1, 1)); - - view->SetDrawingMode(B_OP_ALPHA); - view->SetHighColor(shadowColor); - view->StrokeShape(&shape); - - view->MovePenTo(B_ORIGIN); - - view->SetDrawingMode(B_OP_COPY); - view->SetHighColor(frameLightColor); - view->StrokeShape(&shape); - - rect.InsetBy(1, 1); - shape.Clear(); - if (orientation == B_HORIZONTAL) { - shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); - shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); - shape.LineTo(BPoint(centerh + 0.5, rect.top)); - } else { - shape.MoveTo(BPoint(rect.right + 1, rect.top)); - shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); - shape.LineTo(BPoint(rect.left, centerv + 0.5)); - } - shape.Close(); - - BGradientLinear gradient; - if ((flags & B_DISABLED) != 0) { - _MakeGradient(gradient, rect, fill, topTint, bottomTint); - } else { - _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, - middleTint2, bottomTint); - } - - view->FillShape(&shape, gradient); - - view->SetFlags(viewFlags); -} - - -void -BControlLook::DrawSliderHashMarks(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, int32 count, - hash_mark_location location, uint32 flags, orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - rgb_color lightColor; - rgb_color darkColor; - - if ((flags & B_DISABLED) != 0) { - lightColor = tint_color(base, 0.9); - darkColor = tint_color(base, 1.07); - } else { - lightColor = tint_color(base, 0.8); - darkColor = tint_color(base, 1.14); - } - - int32 hashMarkCount = std::max(count, (int32)2); - // draw at least two hashmarks at min/max if - // fHashMarks != B_HASH_MARKS_NONE - float factor; - float startPos; - if (orientation == B_HORIZONTAL) { - factor = (rect.Width() - 2) / (hashMarkCount - 1); - startPos = rect.left + 1; - } else { - factor = (rect.Height() - 2) / (hashMarkCount - 1); - startPos = rect.top + 1; - } - - if (location & B_HASH_MARKS_TOP) { - view->BeginLineArray(hashMarkCount * 2); - - if (orientation == B_HORIZONTAL) { - float pos = startPos; - for (int32 i = 0; i < hashMarkCount; i++) { - view->AddLine(BPoint(pos, rect.top), - BPoint(pos, rect.top + 4), darkColor); - view->AddLine(BPoint(pos + 1, rect.top), - BPoint(pos + 1, rect.top + 4), lightColor); - - pos += factor; - } - } else { - float pos = startPos; - for (int32 i = 0; i < hashMarkCount; i++) { - view->AddLine(BPoint(rect.left, pos), - BPoint(rect.left + 4, pos), darkColor); - view->AddLine(BPoint(rect.left, pos + 1), - BPoint(rect.left + 4, pos + 1), lightColor); - - pos += factor; - } - } - - view->EndLineArray(); - } - - if ((location & B_HASH_MARKS_BOTTOM) != 0) { - view->BeginLineArray(hashMarkCount * 2); - - if (orientation == B_HORIZONTAL) { - float pos = startPos; - for (int32 i = 0; i < hashMarkCount; i++) { - view->AddLine(BPoint(pos, rect.bottom - 4), - BPoint(pos, rect.bottom), darkColor); - view->AddLine(BPoint(pos + 1, rect.bottom - 4), - BPoint(pos + 1, rect.bottom), lightColor); - - pos += factor; - } - } else { - float pos = startPos; - for (int32 i = 0; i < hashMarkCount; i++) { - view->AddLine(BPoint(rect.right - 4, pos), - BPoint(rect.right, pos), darkColor); - view->AddLine(BPoint(rect.right - 4, pos + 1), - BPoint(rect.right, pos + 1), lightColor); - - pos += factor; - } - } - - view->EndLineArray(); - } -} - - -void -BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 flags, uint32 borders, uint32 side) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // Snap the rectangle to pixels to avoid rounding errors. - rect.left = floorf(rect.left); - rect.right = floorf(rect.right); - rect.top = floorf(rect.top); - rect.bottom = floorf(rect.bottom); - - // save the clipping constraints of the view - view->PushState(); - - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); - - rgb_color edgeShadowColor; - rgb_color edgeLightColor; - rgb_color frameShadowColor; - rgb_color frameLightColor; - rgb_color bevelShadowColor; - rgb_color bevelLightColor; - BGradientLinear fillGradient; - fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); - fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); - - if ((flags & B_DISABLED) != 0) { - edgeLightColor = base; - edgeShadowColor = base; - frameLightColor = tint_color(base, 1.25); - frameShadowColor = tint_color(base, 1.30); - bevelLightColor = tint_color(base, 0.8); - bevelShadowColor = tint_color(base, 1.07); - fillGradient.AddColor(tint_color(base, 0.85), 0); - fillGradient.AddColor(base, 255); - } else { - edgeLightColor = tint_color(base, 0.80); - edgeShadowColor = tint_color(base, 1.03); - frameLightColor = tint_color(base, 1.30); - frameShadowColor = tint_color(base, 1.30); - bevelLightColor = tint_color(base, 0.6); - bevelShadowColor = tint_color(base, 1.07); - fillGradient.AddColor(tint_color(base, 0.75), 0); - fillGradient.AddColor(tint_color(base, 1.03), 255); - } - - static const float kRoundCornerRadius = 4.0f; - - // left top corner dimensions - BRect leftTopCorner(rect); - leftTopCorner.right = floorf(leftTopCorner.left + kRoundCornerRadius); - leftTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); - - // right top corner dimensions - BRect rightTopCorner(rect); - rightTopCorner.left = floorf(rightTopCorner.right - kRoundCornerRadius); - rightTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); - - // left bottom corner dimensions - BRect leftBottomCorner(rect); - leftBottomCorner.right = floorf(leftBottomCorner.left + kRoundCornerRadius); - leftBottomCorner.top = floorf(rect.bottom - kRoundCornerRadius); - - // right bottom corner dimensions - BRect rightBottomCorner(rect); - rightBottomCorner.left = floorf(rightBottomCorner.right - - kRoundCornerRadius); - rightBottomCorner.top = floorf(rect.bottom - kRoundCornerRadius); - - switch (side) { - case B_TOP_BORDER: - clipping.Exclude(leftTopCorner); - clipping.Exclude(rightTopCorner); - - // draw the left top corner - _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, - edgeShadowColor, frameLightColor, bevelLightColor, - fillGradient); - // draw the right top corner - _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, - edgeShadowColor, edgeLightColor, frameLightColor, - frameShadowColor, bevelLightColor, bevelShadowColor, - fillGradient); - break; - case B_BOTTOM_BORDER: - clipping.Exclude(leftBottomCorner); - clipping.Exclude(rightBottomCorner); - - // draw the left bottom corner - _DrawRoundCornerLeftBottom(view, leftBottomCorner, updateRect, base, - edgeShadowColor, edgeLightColor, frameLightColor, - frameShadowColor, bevelLightColor, bevelShadowColor, - fillGradient); - // draw the right bottom corner - _DrawRoundCornerRightBottom(view, rightBottomCorner, updateRect, - base, edgeLightColor, frameShadowColor, bevelShadowColor, - fillGradient); - break; - case B_LEFT_BORDER: - clipping.Exclude(leftTopCorner); - clipping.Exclude(leftBottomCorner); - - // draw the left top corner - _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, - edgeShadowColor, frameLightColor, bevelLightColor, - fillGradient); - // draw the left bottom corner - _DrawRoundCornerLeftBottom(view, leftBottomCorner, updateRect, base, - edgeShadowColor, edgeLightColor, frameLightColor, - frameShadowColor, bevelLightColor, bevelShadowColor, - fillGradient); - break; - case B_RIGHT_BORDER: - clipping.Exclude(rightTopCorner); - clipping.Exclude(rightBottomCorner); - - // draw the right top corner - _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, - edgeShadowColor, edgeLightColor, frameLightColor, - frameShadowColor, bevelLightColor, bevelShadowColor, - fillGradient); - // draw the right bottom corner - _DrawRoundCornerRightBottom(view, rightBottomCorner, updateRect, - base, edgeLightColor, frameShadowColor, bevelShadowColor, - fillGradient); - break; - } - - // clip out the corners - view->ConstrainClippingRegion(&clipping); - - uint32 bordersToDraw = 0; - switch (side) { - case B_TOP_BORDER: - bordersToDraw = (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); - break; - case B_BOTTOM_BORDER: - bordersToDraw = (B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); - break; - case B_LEFT_BORDER: - bordersToDraw = (B_LEFT_BORDER | B_BOTTOM_BORDER | B_TOP_BORDER); - break; - case B_RIGHT_BORDER: - bordersToDraw = (B_RIGHT_BORDER | B_BOTTOM_BORDER | B_TOP_BORDER); - break; - } - - // draw the rest of frame and fill - _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, - edgeLightColor, borders); - if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { - if ((borders & B_LEFT_BORDER) == 0) - rect.left++; - if ((borders & B_RIGHT_BORDER) == 0) - rect.right--; - } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { - if ((borders & B_TOP_BORDER) == 0) - rect.top++; - if ((borders & B_BOTTOM_BORDER) == 0) - rect.bottom--; - } - - _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, - frameShadowColor, bordersToDraw); - - _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, - bevelShadowColor); - - view->FillRect(rect, fillGradient); - - // restore the clipping constraints of the view - view->PopState(); -} - - -void -BControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 flags, uint32 borders, uint32 side) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - rgb_color edgeShadowColor; - rgb_color edgeLightColor; - rgb_color frameShadowColor; - rgb_color frameLightColor; - rgb_color bevelShadowColor; - rgb_color bevelLightColor; - BGradientLinear fillGradient; - fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); - fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); - - if ((flags & B_DISABLED) != 0) { - edgeLightColor = base; - edgeShadowColor = base; - frameLightColor = tint_color(base, 1.25); - frameShadowColor = tint_color(base, 1.30); - bevelLightColor = tint_color(base, 0.8); - bevelShadowColor = tint_color(base, 1.07); - fillGradient.AddColor(tint_color(base, 0.85), 0); - fillGradient.AddColor(base, 255); - } else { - edgeLightColor = tint_color(base, 0.80); - edgeShadowColor = tint_color(base, 1.03); - frameLightColor = tint_color(base, 1.30); - frameShadowColor = tint_color(base, 1.30); - bevelLightColor = tint_color(base, 1.10); - bevelShadowColor = tint_color(base, 1.17); - fillGradient.AddColor(tint_color(base, 1.12), 0); - fillGradient.AddColor(tint_color(base, 1.08), 255); - } - - BRect background = rect; - switch (side) { - case B_TOP_BORDER: - rect.top += 4; - background.bottom = rect.top; - break; - case B_BOTTOM_BORDER: - rect.bottom -= 4; - background.top = rect.bottom; - break; - case B_LEFT_BORDER: - rect.left += 4; - background.right = rect.left; - break; - case B_RIGHT_BORDER: - rect.right -= 4; - background.left = rect.right; - break; - } - - // active tabs stand out at the top, but this is an inactive tab - view->SetHighColor(base); - view->FillRect(background); - - // frame and fill - _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, - edgeLightColor, borders); - - _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, - frameShadowColor, borders); - - if (rect.IsValid()) { - if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { - _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, - bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders); - } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { - _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, - bevelLightColor, bevelLightColor, B_TOP_BORDER & ~borders); - } - } else { - if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { - if ((B_LEFT_BORDER & ~borders) != 0) - rect.left++; - } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { - if ((B_TOP_BORDER & ~borders) != 0) - rect.top++; - } - } - - view->FillRect(rect, fillGradient); -} - - -void -BControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, orientation orientation, uint32 flags, - uint32 borders) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - rgb_color background; - if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) - background = tint_color(base, B_DARKEN_1_TINT); - else - background = base; - - rgb_color light = tint_color(background, 0.6); - rgb_color shadow = tint_color(background, 1.21); - - // frame - if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) - DrawRaisedBorder(view, rect, updateRect, background, flags, borders); - - // dots and rest of background - if (orientation == B_HORIZONTAL) { - if (rect.Width() > 2) { - // background on left/right - BRegion region(rect); - rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); - rect.right = rect.left + 1; - region.Exclude(rect); - view->SetHighColor(background); - view->FillRegion(®ion); - } - - BPoint dot = rect.LeftTop(); - BPoint stop = rect.LeftBottom(); - int32 num = 1; - while (dot.y <= stop.y) { - rgb_color col1; - rgb_color col2; - switch (num) { - case 1: - col1 = background; - col2 = background; - break; - case 2: - col1 = shadow; - col2 = background; - break; - case 3: - default: - col1 = background; - col2 = light; - num = 0; - break; - } - view->SetHighColor(col1); - view->StrokeLine(dot, dot, B_SOLID_HIGH); - view->SetHighColor(col2); - dot.x++; - view->StrokeLine(dot, dot, B_SOLID_HIGH); - dot.x -= 1.0; - // next pixel - num++; - dot.y++; - } - } else { - if (rect.Height() > 2) { - // background on left/right - BRegion region(rect); - rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); - rect.bottom = rect.top + 1; - region.Exclude(rect); - view->SetHighColor(background); - view->FillRegion(®ion); - } - - BPoint dot = rect.LeftTop(); - BPoint stop = rect.RightTop(); - int32 num = 1; - while (dot.x <= stop.x) { - rgb_color col1; - rgb_color col2; - switch (num) { - case 1: - col1 = background; - col2 = background; - break; - case 2: - col1 = shadow; - col2 = background; - break; - case 3: - default: - col1 = background; - col2 = light; - num = 0; - break; - } - view->SetHighColor(col1); - view->StrokeLine(dot, dot, B_SOLID_HIGH); - view->SetHighColor(col2); - dot.y++; - view->StrokeLine(dot, dot, B_SOLID_HIGH); - dot.y -= 1.0; - // next pixel - num++; - dot.x++; - } - } -} - - -// #pragma mark - - - -void -BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, border_style borderStyle, uint32 flags, - uint32 borders) -{ - if (borderStyle == B_NO_BORDER) - return; - - rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); - if ((flags & B_FOCUSED) != 0) - scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - if (borderStyle == B_FANCY_BORDER) - _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); - - _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, - scrollbarFrameColor, scrollbarFrameColor, borders); -} - - -void -BControlLook::DrawRaisedBorder(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - rgb_color lightColor; - rgb_color shadowColor; - - if ((flags & B_DISABLED) != 0) { - lightColor = base; - shadowColor = base; - } else { - lightColor = tint_color(base, 0.85); - shadowColor = tint_color(base, 1.07); - } - - _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, - borders); -} - - -void -BControlLook::DrawTextControlBorder(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders) -{ - if (!rect.Intersects(updateRect)) - return; - - rgb_color dark1BorderColor; - rgb_color dark2BorderColor; - rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - rgb_color invalidColor = ui_color(B_FAILURE_COLOR); - - if ((flags & B_DISABLED) != 0) { - _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); - - if ((flags & B_BLEND_FRAME) != 0) - dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; - else - dark1BorderColor = tint_color(base, 1.15); - dark2BorderColor = dark1BorderColor; - } else if ((flags & B_CLICKED) != 0) { - dark1BorderColor = tint_color(base, 1.50); - dark2BorderColor = tint_color(base, 1.49); - - // BCheckBox uses this to indicate the clicked state... - _DrawFrame(view, rect, - dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor); - - dark2BorderColor = dark1BorderColor; - } else { - _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); - - if ((flags & B_BLEND_FRAME) != 0) { - dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; - dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; - } else { - dark1BorderColor = tint_color(base, 1.40); - dark2BorderColor = tint_color(base, 1.38); - } - } - - if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED) != 0) { - dark1BorderColor = navigationColor; - dark2BorderColor = navigationColor; - } - - if ((flags & B_DISABLED) == 0 && (flags & B_INVALID) != 0) { - dark1BorderColor = invalidColor; - dark2BorderColor = invalidColor; - } - - if ((flags & B_BLEND_FRAME) != 0) { - drawing_mode oldMode = view->DrawingMode(); - view->SetDrawingMode(B_OP_ALPHA); - - _DrawFrame(view, rect, - dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor, borders); - - view->SetDrawingMode(oldMode); - } else { - _DrawFrame(view, rect, - dark1BorderColor, dark1BorderColor, - dark2BorderColor, dark2BorderColor, borders); - } -} - - -void -BControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, - const rgb_color& base, uint32 borders) -{ - rgb_color frameColor = tint_color(base, 1.30); - rgb_color bevelLight = tint_color(base, 0.8); - rgb_color bevelShadow = tint_color(base, 1.03); - - _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, - borders); - - _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, - borders); - - _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, - borders); -} - - -void -BControlLook::DrawLabel(BView* view, const char* label, BRect rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - const rgb_color* textColor) -{ - DrawLabel(view, label, NULL, rect, updateRect, base, flags, - DefaultLabelAlignment(), textColor); -} - - -void -BControlLook::DrawLabel(BView* view, const char* label, BRect rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - const BAlignment& alignment, const rgb_color* textColor) -{ - DrawLabel(view, label, NULL, rect, updateRect, base, flags, alignment, - textColor); -} - - -void -BControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base, - uint32 flags, const BPoint& where, const rgb_color* textColor) -{ - // setup the text color - - BWindow* window = view->Window(); - bool isDesktop = window - && window->Feel() == kDesktopWindowFeel - && window->Look() == kDesktopWindowLook - && view->Parent() - && view->Parent()->Parent() == NULL - && (flags & B_IGNORE_OUTLINE) == 0; - - rgb_color low; - rgb_color color; - rgb_color glowColor; - - if (textColor != NULL) - glowColor = *textColor; - else if ((flags & B_IS_CONTROL) != 0) - glowColor = ui_color(B_CONTROL_TEXT_COLOR); - else - glowColor = ui_color(B_PANEL_TEXT_COLOR); - - color = glowColor; - - if (isDesktop) - low = view->Parent()->ViewColor(); - else - low = base; - - if ((flags & B_DISABLED) != 0) { - color.red = (uint8)(((int32)low.red + color.red + 1) / 2); - color.green = (uint8)(((int32)low.green + color.green + 1) / 2); - color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2); - } - - drawing_mode oldMode = view->DrawingMode(); - - if (isDesktop) { - // enforce proper use of desktop label colors - if (low.Brightness() < 100) { - if (textColor == NULL) - color = make_color(255, 255, 255); - - glowColor = make_color(0, 0, 0); - } else { - if (textColor == NULL) - color = make_color(0, 0, 0); - - glowColor = make_color(255, 255, 255); - } - - // drawing occurs on the desktop - if (fCachedWorkspace != current_workspace()) { - int8 indice = 0; - int32 mask; - bool tmpOutline; - while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces", - indice, &mask) == B_OK - && fBackgroundInfo.FindBool("be:bgndimginfoerasetext", - indice, &tmpOutline) == B_OK) { - - if (((1 << current_workspace()) & mask) != 0) { - fCachedOutline = tmpOutline; - fCachedWorkspace = current_workspace(); - break; - } - indice++; - } - } - - if (fCachedOutline) { - BFont font; - view->GetFont(&font); - - view->SetDrawingMode(B_OP_ALPHA); - view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); - // Draw glow or outline - if (glowColor.Brightness() > 128) { - font.SetFalseBoldWidth(2.0); - view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); - - glowColor.alpha = 30; - view->SetHighColor(glowColor); - view->DrawString(label, where); - - font.SetFalseBoldWidth(1.0); - view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); - - glowColor.alpha = 65; - view->SetHighColor(glowColor); - view->DrawString(label, where); - - font.SetFalseBoldWidth(0.0); - view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); - } else { - font.SetFalseBoldWidth(1.0); - view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); - - glowColor.alpha = 30; - view->SetHighColor(glowColor); - view->DrawString(label, where); - - font.SetFalseBoldWidth(0.0); - view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); - - glowColor.alpha = 200; - view->SetHighColor(glowColor); - view->DrawString(label, BPoint(where.x + 1, where.y + 1)); - } - } - } - - view->SetHighColor(color); - view->SetDrawingMode(B_OP_OVER); - view->DrawString(label, where); - view->SetDrawingMode(oldMode); -} - - void BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, @@ -2019,149 +53,6 @@ BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, } -void -BControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, - BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, - const BAlignment& alignment, const rgb_color* textColor) -{ - if (!rect.Intersects(updateRect)) - return; - - if (label == NULL && icon == NULL) - return; - - if (label == NULL) { - // icon only - BRect alignedRect = BLayoutUtils::AlignInFrame(rect, - icon->Bounds().Size(), alignment); - drawing_mode oldMode = view->DrawingMode(); - view->SetDrawingMode(B_OP_OVER); - view->DrawBitmap(icon, alignedRect.LeftTop()); - view->SetDrawingMode(oldMode); - return; - } - - // label, possibly with icon - float availableWidth = rect.Width() + 1; - float width = 0; - float textOffset = 0; - float height = 0; - - if (icon != NULL) { - width = icon->Bounds().Width() + DefaultLabelSpacing() + 1; - height = icon->Bounds().Height() + 1; - textOffset = width; - availableWidth -= textOffset; - } - - // truncate the label if necessary and get the width and height - BString truncatedLabel(label); - - BFont font; - view->GetFont(&font); - - font.TruncateString(&truncatedLabel, B_TRUNCATE_END, availableWidth); - width += ceilf(font.StringWidth(truncatedLabel.String())); - - font_height fontHeight; - font.GetHeight(&fontHeight); - float textHeight = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); - height = std::max(height, textHeight); - - // handle alignment - BRect alignedRect(BLayoutUtils::AlignOnRect(rect, - BSize(width - 1, height - 1), alignment)); - - if (icon != NULL) { - BPoint location(alignedRect.LeftTop()); - if (icon->Bounds().Height() + 1 < height) - location.y += ceilf((height - icon->Bounds().Height() - 1) / 2); - - drawing_mode oldMode = view->DrawingMode(); - view->SetDrawingMode(B_OP_OVER); - view->DrawBitmap(icon, location); - view->SetDrawingMode(oldMode); - } - - BPoint location(alignedRect.left + textOffset, - alignedRect.top + ceilf(fontHeight.ascent)); - if (textHeight < height) - location.y += ceilf((height - textHeight) / 2); - - DrawLabel(view, truncatedLabel.String(), base, flags, location, textColor); -} - - -void -BControlLook::GetFrameInsets(frame_type frameType, uint32 flags, float& _left, - float& _top, float& _right, float& _bottom) -{ - // All frames have the same inset on each side. - float inset = 0; - - switch (frameType) { - case B_BUTTON_FRAME: - inset = (flags & B_DEFAULT_BUTTON) != 0 ? 5 : 2; - break; - case B_GROUP_FRAME: - case B_MENU_FIELD_FRAME: - inset = 3; - break; - case B_SCROLL_VIEW_FRAME: - case B_TEXT_CONTROL_FRAME: - inset = 2; - break; - } - - _left = inset; - _top = inset; - _right = inset; - _bottom = inset; -} - - -void -BControlLook::GetBackgroundInsets(background_type backgroundType, - uint32 flags, float& _left, float& _top, float& _right, float& _bottom) -{ - // Most backgrounds have the same inset on each side. - float inset = 0; - - switch (backgroundType) { - case B_BUTTON_BACKGROUND: - case B_MENU_BACKGROUND: - case B_MENU_BAR_BACKGROUND: - case B_MENU_FIELD_BACKGROUND: - case B_MENU_ITEM_BACKGROUND: - inset = 1; - break; - case B_BUTTON_WITH_POP_UP_BACKGROUND: - _left = 1; - _top = 1; - _right = 1 + kButtonPopUpIndicatorWidth; - _bottom = 1; - return; - case B_HORIZONTAL_SCROLL_BAR_BACKGROUND: - _left = 2; - _top = 0; - _right = 1; - _bottom = 0; - return; - case B_VERTICAL_SCROLL_BAR_BACKGROUND: - _left = 0; - _top = 2; - _right = 0; - _bottom = 1; - return; - } - - _left = inset; - _top = inset; - _right = inset; - _bottom = inset; -} - - void BControlLook::GetInsets(frame_type frameType, background_type backgroundType, uint32 flags, float& _left, float& _top, float& _right, float& _bottom) @@ -2178,38 +69,6 @@ BControlLook::GetInsets(frame_type frameType, background_type backgroundType, } -void -BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, uint32 flags, - uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, - base, true, flags, borders, orientation); -} - - -void -BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, - const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, - uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, - radius, base, true, flags, borders, orientation); -} - - -void -BControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - uint32 flags, uint32 borders, orientation orientation) -{ - _DrawButtonBackground(view, rect, updateRect, leftTopRadius, - rightTopRadius, leftBottomRadius, rightBottomRadius, base, true, flags, - borders, orientation); -} - - void BControlLook::SetBackgroundInfo(const BMessage& backgroundInfo) { @@ -2218,1441 +77,6 @@ BControlLook::SetBackgroundInfo(const BMessage& backgroundInfo) } -// #pragma mark - - - -void -BControlLook::_DrawButtonFrame(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - const rgb_color& background, float contrast, float brightness, - uint32 flags, uint32 borders) -{ - if (!rect.IsValid()) - return; - - // save the clipping constraints of the view - view->PushState(); - - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); - - // If the button is flat and neither activated nor otherwise highlighted - // (mouse hovering or focussed), draw it flat. - if ((flags & B_FLAT) != 0 - && (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0 - && ((flags & (B_HOVER | B_FOCUSED)) == 0 - || (flags & B_DISABLED) != 0)) { - _DrawFrame(view, rect, background, background, background, - background, borders); - _DrawFrame(view, rect, background, background, background, - background, borders); - view->PopState(); - return; - } - - // outer edge colors - rgb_color edgeLightColor; - rgb_color edgeShadowColor; - - // default button frame color - rgb_color defaultIndicatorColor = ui_color(B_CONTROL_BORDER_COLOR); - rgb_color cornerBgColor; - - if ((flags & B_DISABLED) != 0) { - defaultIndicatorColor = disable_color(defaultIndicatorColor, - background); - } - - drawing_mode oldMode = view->DrawingMode(); - - if ((flags & B_DEFAULT_BUTTON) != 0) { - cornerBgColor = defaultIndicatorColor; - edgeLightColor = _EdgeLightColor(defaultIndicatorColor, - contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), - brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); - edgeShadowColor = _EdgeShadowColor(defaultIndicatorColor, - contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), - brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); - - // draw default button indicator - // Allow a 1-pixel border of the background to come through. - rect.InsetBy(1, 1); - - view->SetHighColor(defaultIndicatorColor); - view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); - rect.InsetBy(1, 1); - - view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); - rect.InsetBy(1, 1); - } else { - cornerBgColor = background; - if ((flags & B_BLEND_FRAME) != 0) { - // set the background color to transparent for the case - // that we are on the desktop - cornerBgColor.alpha = 0; - view->SetDrawingMode(B_OP_ALPHA); - } - - edgeLightColor = _EdgeLightColor(background, - contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), - brightness * 1.0, flags); - edgeShadowColor = _EdgeShadowColor(background, - contrast * (flags & B_DISABLED) != 0 ? 0.0 : 1.0, - brightness * 1.0, flags); - } - - // frame colors - rgb_color frameLightColor = _FrameLightColor(base, flags); - rgb_color frameShadowColor = _FrameShadowColor(base, flags); - - // rounded corners - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 - && leftTopRadius > 0) { - // draw left top rounded corner - BRect leftTopCorner(floorf(rect.left), floorf(rect.top), - floorf(rect.left + leftTopRadius), - floorf(rect.top + leftTopRadius)); - clipping.Exclude(leftTopCorner); - _DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect, - cornerBgColor, edgeShadowColor, frameLightColor); - } - - if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 - && rightTopRadius > 0) { - // draw right top rounded corner - BRect rightTopCorner(floorf(rect.right - rightTopRadius), - floorf(rect.top), floorf(rect.right), - floorf(rect.top + rightTopRadius)); - clipping.Exclude(rightTopCorner); - _DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect, - cornerBgColor, edgeShadowColor, edgeLightColor, - frameLightColor, frameShadowColor); - } - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && leftBottomRadius > 0) { - // draw left bottom rounded corner - BRect leftBottomCorner(floorf(rect.left), - floorf(rect.bottom - leftBottomRadius), - floorf(rect.left + leftBottomRadius), floorf(rect.bottom)); - clipping.Exclude(leftBottomCorner); - _DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect, - cornerBgColor, edgeShadowColor, edgeLightColor, - frameLightColor, frameShadowColor); - } - - if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && rightBottomRadius > 0) { - // draw right bottom rounded corner - BRect rightBottomCorner(floorf(rect.right - rightBottomRadius), - floorf(rect.bottom - rightBottomRadius), floorf(rect.right), - floorf(rect.bottom)); - clipping.Exclude(rightBottomCorner); - _DrawRoundCornerFrameRightBottom(view, rightBottomCorner, - updateRect, cornerBgColor, edgeLightColor, frameShadowColor); - } - - // clip out the corners - view->ConstrainClippingRegion(&clipping); - - // draw outer edge - if ((flags & B_DEFAULT_BUTTON) != 0) { - _DrawOuterResessedFrame(view, rect, defaultIndicatorColor, - contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), - brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), - flags, borders); - } else { - _DrawOuterResessedFrame(view, rect, background, - contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), - brightness * 1.0, flags, borders); - } - - view->SetDrawingMode(oldMode); - - // draw frame - if ((flags & B_BLEND_FRAME) != 0) { - drawing_mode oldDrawingMode = view->DrawingMode(); - view->SetDrawingMode(B_OP_ALPHA); - - _DrawFrame(view, rect, frameLightColor, frameLightColor, - frameShadowColor, frameShadowColor, borders); - - view->SetDrawingMode(oldDrawingMode); - } else { - _DrawFrame(view, rect, frameLightColor, frameLightColor, - frameShadowColor, frameShadowColor, borders); - } - - // restore the clipping constraints of the view - view->PopState(); -} - - -void -BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, - const rgb_color& base, float contrast, float brightness, uint32 flags, - uint32 borders) -{ - rgb_color edgeLightColor = _EdgeLightColor(base, contrast, - brightness, flags); - rgb_color edgeShadowColor = _EdgeShadowColor(base, contrast, - brightness, flags); - - if ((flags & B_BLEND_FRAME) != 0) { - // assumes the background has already been painted - drawing_mode oldDrawingMode = view->DrawingMode(); - view->SetDrawingMode(B_OP_ALPHA); - - _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, - edgeLightColor, edgeLightColor, borders); - - view->SetDrawingMode(oldDrawingMode); - } else { - _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, - edgeLightColor, edgeLightColor, borders); - } -} - - -void -BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, - const rgb_color& top, const rgb_color& right, const rgb_color& bottom, - uint32 borders) -{ - view->BeginLineArray(4); - - if (borders & B_LEFT_BORDER) { - view->AddLine( - BPoint(rect.left, rect.bottom), - BPoint(rect.left, rect.top), left); - rect.left++; - } - if (borders & B_TOP_BORDER) { - view->AddLine( - BPoint(rect.left, rect.top), - BPoint(rect.right, rect.top), top); - rect.top++; - } - if (borders & B_RIGHT_BORDER) { - view->AddLine( - BPoint(rect.right, rect.top), - BPoint(rect.right, rect.bottom), right); - rect.right--; - } - if (borders & B_BOTTOM_BORDER) { - view->AddLine( - BPoint(rect.left, rect.bottom), - BPoint(rect.right, rect.bottom), bottom); - rect.bottom--; - } - - view->EndLineArray(); -} - - -void -BControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, - const rgb_color& top, const rgb_color& right, const rgb_color& bottom, - const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) -{ - view->BeginLineArray(6); - - if (borders & B_TOP_BORDER) { - if (borders & B_RIGHT_BORDER) { - view->AddLine( - BPoint(rect.left, rect.top), - BPoint(rect.right - 1, rect.top), top); - view->AddLine( - BPoint(rect.right, rect.top), - BPoint(rect.right, rect.top), rightTop); - } else { - view->AddLine( - BPoint(rect.left, rect.top), - BPoint(rect.right, rect.top), top); - } - rect.top++; - } - - if (borders & B_LEFT_BORDER) { - view->AddLine( - BPoint(rect.left, rect.top), - BPoint(rect.left, rect.bottom - 1), left); - view->AddLine( - BPoint(rect.left, rect.bottom), - BPoint(rect.left, rect.bottom), leftBottom); - rect.left++; - } - - if (borders & B_BOTTOM_BORDER) { - view->AddLine( - BPoint(rect.left, rect.bottom), - BPoint(rect.right, rect.bottom), bottom); - rect.bottom--; - } - - if (borders & B_RIGHT_BORDER) { - view->AddLine( - BPoint(rect.right, rect.bottom), - BPoint(rect.right, rect.top), right); - rect.right--; - } - - view->EndLineArray(); -} - - -void -BControlLook::_DrawButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - bool popupIndicator, uint32 flags, uint32 borders, orientation orientation) -{ - if (!rect.IsValid()) - return; - - // save the clipping constraints of the view - view->PushState(); - - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); - - // If the button is flat and neither activated nor otherwise highlighted - // (mouse hovering or focussed), draw it flat. - if ((flags & B_FLAT) != 0 - && (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0 - && ((flags & (B_HOVER | B_FOCUSED)) == 0 - || (flags & B_DISABLED) != 0)) { - _DrawFlatButtonBackground(view, rect, updateRect, base, popupIndicator, - flags, borders, orientation); - } else { - _DrawNonFlatButtonBackground(view, rect, updateRect, clipping, - leftTopRadius, rightTopRadius, leftBottomRadius, rightBottomRadius, - base, popupIndicator, flags, borders, orientation); - } - - // restore the clipping constraints of the view - view->PopState(); -} - - -void -BControlLook::_DrawFlatButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, const rgb_color& base, bool popupIndicator, - uint32 flags, uint32 borders, orientation orientation) -{ - _DrawFrame(view, rect, base, base, base, base, borders); - // Not an actual frame, but the method insets our rect as needed. - - view->SetHighColor(base); - view->FillRect(rect); - - if (popupIndicator) { - BRect indicatorRect(rect); - rect.right -= kButtonPopUpIndicatorWidth; - indicatorRect.left = rect.right + 3; - // 2 pixels for the separator - - view->SetHighColor(base); - view->FillRect(indicatorRect); - - _DrawPopUpMarker(view, indicatorRect, base, flags); - } -} - - -void -BControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, - const BRect& updateRect, BRegion& clipping, float leftTopRadius, - float rightTopRadius, float leftBottomRadius, float rightBottomRadius, - const rgb_color& base, bool popupIndicator, uint32 flags, uint32 borders, - orientation orientation) -{ - // inner bevel colors - rgb_color bevelLightColor = _BevelLightColor(base, flags); - rgb_color bevelShadowColor = _BevelShadowColor(base, flags); - - // button background color - rgb_color buttonBgColor; - if ((flags & B_DISABLED) != 0) - buttonBgColor = tint_color(base, 0.7); - else - buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); - - // surface top gradient - BGradientLinear fillGradient; - _MakeButtonGradient(fillGradient, rect, base, flags, orientation); - - // rounded corners - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 - && leftTopRadius > 0) { - // draw left top rounded corner - BRect leftTopCorner(floorf(rect.left), floorf(rect.top), - floorf(rect.left + leftTopRadius - 2.0), - floorf(rect.top + leftTopRadius - 2.0)); - clipping.Exclude(leftTopCorner); - _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, - bevelLightColor, fillGradient); - } - - if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 - && rightTopRadius > 0) { - // draw right top rounded corner - BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), - floorf(rect.top), floorf(rect.right), - floorf(rect.top + rightTopRadius - 2.0)); - clipping.Exclude(rightTopCorner); - _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, - updateRect, bevelLightColor, bevelShadowColor, fillGradient); - } - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && leftBottomRadius > 0) { - // draw left bottom rounded corner - BRect leftBottomCorner(floorf(rect.left), - floorf(rect.bottom - leftBottomRadius + 2.0), - floorf(rect.left + leftBottomRadius - 2.0), - floorf(rect.bottom)); - clipping.Exclude(leftBottomCorner); - _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, - updateRect, bevelLightColor, bevelShadowColor, fillGradient); - } - - if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && rightBottomRadius > 0) { - // draw right bottom rounded corner - BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), - floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), - floorf(rect.bottom)); - clipping.Exclude(rightBottomCorner); - _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, - updateRect, bevelShadowColor, fillGradient); - } - - // clip out the corners - view->ConstrainClippingRegion(&clipping); - - // draw inner bevel - - if ((flags & B_ACTIVATED) != 0) { - view->BeginLineArray(4); - - // shadow along left/top borders - if (borders & B_LEFT_BORDER) { - view->AddLine(BPoint(rect.left, rect.top), - BPoint(rect.left, rect.bottom), bevelLightColor); - rect.left++; - } - if (borders & B_TOP_BORDER) { - view->AddLine(BPoint(rect.left, rect.top), - BPoint(rect.right, rect.top), bevelLightColor); - rect.top++; - } - - // softer shadow along left/top borders - if (borders & B_LEFT_BORDER) { - view->AddLine(BPoint(rect.left, rect.top), - BPoint(rect.left, rect.bottom), bevelShadowColor); - rect.left++; - } - if (borders & B_TOP_BORDER) { - view->AddLine(BPoint(rect.left, rect.top), - BPoint(rect.right, rect.top), bevelShadowColor); - rect.top++; - } - - view->EndLineArray(); - } else { - _DrawFrame(view, rect, - bevelLightColor, bevelLightColor, - bevelShadowColor, bevelShadowColor, - buttonBgColor, buttonBgColor, borders); - } - - if (popupIndicator) { - BRect indicatorRect(rect); - rect.right -= kButtonPopUpIndicatorWidth; - indicatorRect.left = rect.right + 3; - // 2 pixels for the separator - - // Even when depressed we want the pop-up indicator background and - // separator to cover the area up to the top. - if ((flags & B_ACTIVATED) != 0) - indicatorRect.top--; - - // draw the separator - rgb_color separatorBaseColor = base; - if ((flags & B_ACTIVATED) != 0) - separatorBaseColor = tint_color(base, B_DARKEN_1_TINT); - - rgb_color separatorLightColor = _EdgeLightColor(separatorBaseColor, - (flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags); - rgb_color separatorShadowColor = _EdgeShadowColor(separatorBaseColor, - (flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags); - - view->BeginLineArray(2); - - view->AddLine(BPoint(indicatorRect.left - 2, indicatorRect.top), - BPoint(indicatorRect.left - 2, indicatorRect.bottom), - separatorShadowColor); - view->AddLine(BPoint(indicatorRect.left - 1, indicatorRect.top), - BPoint(indicatorRect.left - 1, indicatorRect.bottom), - separatorLightColor); - - view->EndLineArray(); - - // draw background and pop-up marker - _DrawMenuFieldBackgroundInside(view, indicatorRect, updateRect, - 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, 0); - - if ((flags & B_ACTIVATED) != 0) - indicatorRect.top++; - - _DrawPopUpMarker(view, indicatorRect, base, flags); - } - - // fill in the background - view->FillRect(rect, fillGradient); -} - - -void -BControlLook::_DrawPopUpMarker(BView* view, const BRect& rect, - const rgb_color& base, uint32 flags) -{ - BPoint center(roundf((rect.left + rect.right) / 2.0), - roundf((rect.top + rect.bottom) / 2.0)); - BPoint triangle[3]; - triangle[0] = center + BPoint(-2.5, -0.5); - triangle[1] = center + BPoint(2.5, -0.5); - triangle[2] = center + BPoint(0.0, 2.0); - - uint32 viewFlags = view->Flags(); - view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); - - rgb_color markColor; - if ((flags & B_DISABLED) != 0) - markColor = tint_color(base, 1.35); - else - markColor = tint_color(base, 1.65); - - view->SetHighColor(markColor); - view->FillTriangle(triangle[0], triangle[1], triangle[2]); - - view->SetFlags(viewFlags); -} - - -void -BControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - bool popupIndicator, uint32 flags) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - if (popupIndicator) { - BRect leftRect(rect); - leftRect.right -= 10; - - BRect rightRect(rect); - rightRect.left = rightRect.right - 9; - - _DrawMenuFieldBackgroundInside(view, leftRect, updateRect, - leftTopRadius, 0.0f, leftBottomRadius, 0.0f, base, flags, - B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); - - _DrawMenuFieldBackgroundInside(view, rightRect, updateRect, - 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, - B_TOP_BORDER | B_RIGHT_BORDER | B_BOTTOM_BORDER); - - _DrawPopUpMarker(view, rightRect, base, flags); - - // draw a line on the left of the popup frame - rgb_color bevelShadowColor = _BevelShadowColor(base, flags); - view->SetHighColor(bevelShadowColor); - BPoint leftTopCorner(floorf(rightRect.left - 1.0), - floorf(rightRect.top - 1.0)); - BPoint leftBottomCorner(floorf(rightRect.left - 1.0), - floorf(rightRect.bottom + 1.0)); - view->StrokeLine(leftTopCorner, leftBottomCorner); - - rect = leftRect; - } else { - _DrawMenuFieldBackgroundInside(view, rect, updateRect, leftTopRadius, - rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags); - } -} - - -void -BControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, - const BRect& updateRect, float leftTopRadius, float rightTopRadius, - float leftBottomRadius, float rightBottomRadius, const rgb_color& base, - uint32 flags, uint32 borders) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - // save the clipping constraints of the view - view->PushState(); - - // set clipping constraints to updateRect - BRegion clipping(updateRect); - view->ConstrainClippingRegion(&clipping); - - // frame colors - rgb_color frameLightColor = _FrameLightColor(base, flags); - rgb_color frameShadowColor = _FrameShadowColor(base, flags); - - // indicator background color - rgb_color indicatorBase; - if ((borders & B_LEFT_BORDER) != 0) - indicatorBase = base; - else { - if ((flags & B_DISABLED) != 0) - indicatorBase = tint_color(base, 1.05); - else - indicatorBase = tint_color(base, 1.12); - } - - // bevel colors - rgb_color cornerColor = tint_color(indicatorBase, 0.85); - rgb_color bevelColor1 = tint_color(indicatorBase, 0.3); - rgb_color bevelColor2 = tint_color(indicatorBase, 0.5); - rgb_color bevelColor3 = tint_color(indicatorBase, 1.03); - - if ((flags & B_DISABLED) != 0) { - cornerColor = tint_color(indicatorBase, 0.8); - bevelColor1 = tint_color(indicatorBase, 0.7); - bevelColor2 = tint_color(indicatorBase, 0.8); - bevelColor3 = tint_color(indicatorBase, 1.01); - } else { - cornerColor = tint_color(indicatorBase, 0.85); - bevelColor1 = tint_color(indicatorBase, 0.3); - bevelColor2 = tint_color(indicatorBase, 0.5); - bevelColor3 = tint_color(indicatorBase, 1.03); - } - - // surface top gradient - BGradientLinear fillGradient; - _MakeButtonGradient(fillGradient, rect, indicatorBase, flags); - - // rounded corners - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 - && leftTopRadius > 0) { - // draw left top rounded corner - BRect leftTopCorner(floorf(rect.left), floorf(rect.top), - floorf(rect.left + leftTopRadius - 2.0), - floorf(rect.top + leftTopRadius - 2.0)); - clipping.Exclude(leftTopCorner); - - BRegion cornerClipping(leftTopCorner); - view->ConstrainClippingRegion(&cornerClipping); - - BRect ellipseRect(leftTopCorner); - ellipseRect.InsetBy(-1.0, -1.0); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - // draw the frame (again) - view->SetHighColor(frameLightColor); - view->FillEllipse(ellipseRect); - - // draw the bevel and background - _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, - bevelColor1, fillGradient); - } - - if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 - && rightTopRadius > 0) { - // draw right top rounded corner - BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), - floorf(rect.top), floorf(rect.right), - floorf(rect.top + rightTopRadius - 2.0)); - clipping.Exclude(rightTopCorner); - - BRegion cornerClipping(rightTopCorner); - view->ConstrainClippingRegion(&cornerClipping); - - BRect ellipseRect(rightTopCorner); - ellipseRect.InsetBy(-1.0, -1.0); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - // draw the frame (again) - if (frameLightColor == frameShadowColor) { - view->SetHighColor(frameLightColor); - view->FillEllipse(ellipseRect); - } else { - BGradientLinear gradient; - gradient.AddColor(frameLightColor, 0); - gradient.AddColor(frameShadowColor, 255); - gradient.SetStart(rightTopCorner.LeftTop()); - gradient.SetEnd(rightTopCorner.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - } - - // draw the bevel and background - _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, - bevelColor1, bevelColor3, fillGradient); - } - - if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && leftBottomRadius > 0) { - // draw left bottom rounded corner - BRect leftBottomCorner(floorf(rect.left), - floorf(rect.bottom - leftBottomRadius + 2.0), - floorf(rect.left + leftBottomRadius - 2.0), - floorf(rect.bottom)); - clipping.Exclude(leftBottomCorner); - - BRegion cornerClipping(leftBottomCorner); - view->ConstrainClippingRegion(&cornerClipping); - - BRect ellipseRect(leftBottomCorner); - ellipseRect.InsetBy(-1.0, -1.0); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - // draw the frame (again) - if (frameLightColor == frameShadowColor) { - view->SetHighColor(frameLightColor); - view->FillEllipse(ellipseRect); - } else { - BGradientLinear gradient; - gradient.AddColor(frameLightColor, 0); - gradient.AddColor(frameShadowColor, 255); - gradient.SetStart(leftBottomCorner.LeftTop()); - gradient.SetEnd(leftBottomCorner.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - } - - // draw the bevel and background - _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, - updateRect, bevelColor2, bevelColor3, fillGradient); - } - - if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 - && rightBottomRadius > 0) { - // draw right bottom rounded corner - BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), - floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), - floorf(rect.bottom)); - clipping.Exclude(rightBottomCorner); - - BRegion cornerClipping(rightBottomCorner); - view->ConstrainClippingRegion(&cornerClipping); - - BRect ellipseRect(rightBottomCorner); - ellipseRect.InsetBy(-1.0, -1.0); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - // draw the frame (again) - view->SetHighColor(frameShadowColor); - view->FillEllipse(ellipseRect); - - // draw the bevel and background - _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, - updateRect, bevelColor3, fillGradient); - } - - // clip out the corners - view->ConstrainClippingRegion(&clipping); - - // draw the bevel - _DrawFrame(view, rect, - bevelColor2, bevelColor1, - bevelColor3, bevelColor3, - cornerColor, cornerColor, - borders); - - // fill in the background - view->FillRect(rect, fillGradient); - - // restore the clipping constraints of the view - view->PopState(); -} - - -void -BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeColor, const rgb_color& frameColor, - const rgb_color& bevelColor, const BGradientLinear& fillGradient) -{ - _DrawRoundCornerFrameLeftTop(view, cornerRect, updateRect, - background, edgeColor, frameColor); - _DrawRoundCornerBackgroundLeftTop(view, cornerRect, updateRect, - bevelColor, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeColor, const rgb_color& frameColor) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - // background - view->SetHighColor(background); - view->FillRect(cornerRect); - - // outer edge - BRect ellipseRect(cornerRect); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - view->SetHighColor(edgeColor); - view->FillEllipse(ellipseRect); - - // frame - ellipseRect.InsetBy(1, 1); - cornerRect.left++; - cornerRect.top++; - view->SetHighColor(frameColor); - view->FillEllipse(ellipseRect); - - // prepare for bevel - cornerRect.left++; - cornerRect.top++; -} - - -void -BControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& bevelColor, - const BGradientLinear& fillGradient) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - BRect ellipseRect(cornerRect); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - // bevel - view->SetHighColor(bevelColor); - view->FillEllipse(ellipseRect); - - // gradient - ellipseRect.InsetBy(1, 1); - view->FillEllipse(ellipseRect, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, - const rgb_color& frameTopColor, const rgb_color& frameRightColor, - const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, - const BGradientLinear& fillGradient) -{ - _DrawRoundCornerFrameRightTop(view, cornerRect, updateRect, - background, edgeTopColor, edgeRightColor, frameTopColor, - frameRightColor); - _DrawRoundCornerBackgroundRightTop(view, cornerRect, updateRect, - bevelTopColor, bevelRightColor, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, - const rgb_color& frameTopColor, const rgb_color& frameRightColor) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - // background - view->SetHighColor(background); - view->FillRect(cornerRect); - - // outer edge - BRect ellipseRect(cornerRect); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - BGradientLinear gradient; - gradient.AddColor(edgeTopColor, 0); - gradient.AddColor(edgeRightColor, 255); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - - // frame - ellipseRect.InsetBy(1, 1); - cornerRect.right--; - cornerRect.top++; - if (frameTopColor == frameRightColor) { - view->SetHighColor(frameTopColor); - view->FillEllipse(ellipseRect); - } else { - gradient.SetColor(0, frameTopColor); - gradient.SetColor(1, frameRightColor); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - } - - // prepare for bevel - cornerRect.right--; - cornerRect.top++; -} - - -void -BControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& bevelTopColor, - const rgb_color& bevelRightColor, const BGradientLinear& fillGradient) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - BRect ellipseRect(cornerRect); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; - - // bevel - BGradientLinear gradient; - gradient.AddColor(bevelTopColor, 0); - gradient.AddColor(bevelRightColor, 255); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - - // gradient - ellipseRect.InsetBy(1, 1); - view->FillEllipse(ellipseRect, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, - const rgb_color& frameLeftColor, const rgb_color& frameBottomColor, - const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor, - const BGradientLinear& fillGradient) -{ - _DrawRoundCornerFrameLeftBottom(view, cornerRect, updateRect, - background, edgeLeftColor, edgeBottomColor, frameLeftColor, - frameBottomColor); - _DrawRoundCornerBackgroundLeftBottom(view, cornerRect, updateRect, - bevelLeftColor, bevelBottomColor, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, - const rgb_color& frameLeftColor, const rgb_color& frameBottomColor) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - // background - view->SetHighColor(background); - view->FillRect(cornerRect); - - // outer edge - BRect ellipseRect(cornerRect); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - BGradientLinear gradient; - gradient.AddColor(edgeLeftColor, 0); - gradient.AddColor(edgeBottomColor, 255); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - - // frame - ellipseRect.InsetBy(1, 1); - cornerRect.left++; - cornerRect.bottom--; - if (frameLeftColor == frameBottomColor) { - view->SetHighColor(frameLeftColor); - view->FillEllipse(ellipseRect); - } else { - gradient.SetColor(0, frameLeftColor); - gradient.SetColor(1, frameBottomColor); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - } - - // prepare for bevel - cornerRect.left++; - cornerRect.bottom--; -} - - -void -BControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& bevelLeftColor, - const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - BRect ellipseRect(cornerRect); - ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - // bevel - BGradientLinear gradient; - gradient.AddColor(bevelLeftColor, 0); - gradient.AddColor(bevelBottomColor, 255); - gradient.SetStart(cornerRect.LeftTop()); - gradient.SetEnd(cornerRect.RightBottom()); - view->FillEllipse(ellipseRect, gradient); - - // gradient - ellipseRect.InsetBy(1, 1); - view->FillEllipse(ellipseRect, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeColor, const rgb_color& frameColor, - const rgb_color& bevelColor, const BGradientLinear& fillGradient) -{ - _DrawRoundCornerFrameRightBottom(view, cornerRect, updateRect, - background, edgeColor, frameColor); - _DrawRoundCornerBackgroundRightBottom(view, cornerRect, updateRect, - bevelColor, fillGradient); -} - - -void -BControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRect, - const BRect& updateRect, const rgb_color& background, - const rgb_color& edgeColor, const rgb_color& frameColor) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - // background - view->SetHighColor(background); - view->FillRect(cornerRect); - - // outer edge - BRect ellipseRect(cornerRect); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - view->SetHighColor(edgeColor); - view->FillEllipse(ellipseRect); - - // frame - ellipseRect.InsetBy(1, 1); - cornerRect.right--; - cornerRect.bottom--; - view->SetHighColor(frameColor); - view->FillEllipse(ellipseRect); - - // prepare for bevel - cornerRect.right--; - cornerRect.bottom--; -} - - -void -BControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, - BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor, - const BGradientLinear& fillGradient) -{ - // constrain clipping region to corner - BRegion clipping(cornerRect); - view->ConstrainClippingRegion(&clipping); - - BRect ellipseRect(cornerRect); - ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; - ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; - - // bevel - view->SetHighColor(bevelColor); - view->FillEllipse(ellipseRect); - - // gradient - ellipseRect.InsetBy(1, 1); - view->FillEllipse(ellipseRect, fillGradient); -} - - -void -BControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, - const BRect& updateRect, - const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, - const rgb_color& frameLightColor, const rgb_color& frameShadowColor, - const rgb_color& fillLightColor, const rgb_color& fillShadowColor, - float leftInset, float topInset, float rightInset, float bottomInset, - orientation orientation) -{ - if (!rect.IsValid() || !rect.Intersects(updateRect)) - return; - - BGradientLinear gradient; - gradient.AddColor(edgeShadowColor, 0); - gradient.AddColor(edgeLightColor, 255); - gradient.SetStart(rect.LeftTop()); - if (orientation == B_HORIZONTAL) - gradient.SetEnd(rect.LeftBottom()); - else - gradient.SetEnd(rect.RightTop()); - - view->FillEllipse(rect, gradient); - - rect.left += leftInset; - rect.top += topInset; - rect.right += rightInset; - rect.bottom += bottomInset; - - gradient.MakeEmpty(); - gradient.AddColor(frameShadowColor, 0); - gradient.AddColor(frameLightColor, 255); - gradient.SetStart(rect.LeftTop()); - if (orientation == B_HORIZONTAL) - gradient.SetEnd(rect.LeftBottom()); - else - gradient.SetEnd(rect.RightTop()); - - view->FillEllipse(rect, gradient); - - rect.left += leftInset; - rect.top += topInset; - rect.right += rightInset; - rect.bottom += bottomInset; - - gradient.MakeEmpty(); - gradient.AddColor(fillShadowColor, 0); - gradient.AddColor(fillLightColor, 255); - gradient.SetStart(rect.LeftTop()); - if (orientation == B_HORIZONTAL) - gradient.SetEnd(rect.LeftBottom()); - else - gradient.SetEnd(rect.RightTop()); - - view->FillEllipse(rect, gradient); -} - - -rgb_color -BControlLook::_EdgeLightColor(const rgb_color& base, float contrast, - float brightness, uint32 flags) -{ - rgb_color edgeLightColor; - - if ((flags & B_BLEND_FRAME) != 0) { - uint8 alpha = uint8(20 * contrast); - uint8 white = uint8(255 * brightness); - - edgeLightColor = (rgb_color){ white, white, white, alpha }; - } else { - // colors - float tintLight = kEdgeBevelLightTint; - - if (contrast == 0.0) - tintLight = B_NO_TINT; - else if (contrast != 1.0) - tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; - - edgeLightColor = tint_color(base, tintLight); - - if (brightness < 1.0) { - edgeLightColor.red = uint8(edgeLightColor.red * brightness); - edgeLightColor.green = uint8(edgeLightColor.green * brightness); - edgeLightColor.blue = uint8(edgeLightColor.blue * brightness); - } - } - - return edgeLightColor; -} - - -rgb_color -BControlLook::_EdgeShadowColor(const rgb_color& base, float contrast, - float brightness, uint32 flags) -{ - rgb_color edgeShadowColor; - - if ((flags & B_BLEND_FRAME) != 0) { - uint8 alpha = uint8(20 * contrast); - edgeShadowColor = (rgb_color){ 0, 0, 0, alpha }; - } else { - float tintShadow = kEdgeBevelShadowTint; - - if (contrast == 0.0) - tintShadow = B_NO_TINT; - else if (contrast != 1.0) - tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; - - edgeShadowColor = tint_color(base, tintShadow); - - if (brightness < 1.0) { - edgeShadowColor.red = uint8(edgeShadowColor.red * brightness); - edgeShadowColor.green = uint8(edgeShadowColor.green * brightness); - edgeShadowColor.blue = uint8(edgeShadowColor.blue * brightness); - } - } - - return edgeShadowColor; -} - - -rgb_color -BControlLook::_FrameLightColor(const rgb_color& base, uint32 flags) -{ - if ((flags & B_FOCUSED) != 0) - return ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - if ((flags & B_ACTIVATED) != 0) - return _FrameShadowColor(base, flags & ~B_ACTIVATED); - - rgb_color frameLightColor; - - if ((flags & B_DISABLED) != 0) { - // TODO: B_BLEND_FRAME - frameLightColor = tint_color(base, 1.145); - - if ((flags & B_DEFAULT_BUTTON) != 0) - frameLightColor = tint_color(frameLightColor, 1.14); - } else { - if ((flags & B_BLEND_FRAME) != 0) - frameLightColor = (rgb_color){ 0, 0, 0, 75 }; - else - frameLightColor = tint_color(base, 1.33); - - if ((flags & B_DEFAULT_BUTTON) != 0) - frameLightColor = tint_color(frameLightColor, 1.35); - } - - return frameLightColor; -} - - -rgb_color -BControlLook::_FrameShadowColor(const rgb_color& base, uint32 flags) -{ - if ((flags & B_FOCUSED) != 0) - return ui_color(B_KEYBOARD_NAVIGATION_COLOR); - - if ((flags & B_ACTIVATED) != 0) - return _FrameLightColor(base, flags & ~B_ACTIVATED); - - rgb_color frameShadowColor; - - if ((flags & B_DISABLED) != 0) { - // TODO: B_BLEND_FRAME - frameShadowColor = tint_color(base, 1.24); - - if ((flags & B_DEFAULT_BUTTON) != 0) { - frameShadowColor = tint_color(base, 1.145); - frameShadowColor = tint_color(frameShadowColor, 1.12); - } - } else { - if ((flags & B_DEFAULT_BUTTON) != 0) { - if ((flags & B_BLEND_FRAME) != 0) - frameShadowColor = (rgb_color){ 0, 0, 0, 75 }; - else - frameShadowColor = tint_color(base, 1.33); - - frameShadowColor = tint_color(frameShadowColor, 1.5); - } else { - if ((flags & B_BLEND_FRAME) != 0) - frameShadowColor = (rgb_color){ 0, 0, 0, 95 }; - else - frameShadowColor = tint_color(base, 1.47); - } - } - - return frameShadowColor; -} - - -rgb_color -BControlLook::_BevelLightColor(const rgb_color& base, uint32 flags) -{ - rgb_color bevelLightColor = tint_color(base, 0.2); - - if ((flags & B_DISABLED) != 0) - bevelLightColor = tint_color(base, B_LIGHTEN_1_TINT); - - if ((flags & B_ACTIVATED) != 0) - bevelLightColor = tint_color(base, B_DARKEN_1_TINT); - - return bevelLightColor; -} - - -rgb_color -BControlLook::_BevelShadowColor(const rgb_color& base, uint32 flags) -{ - rgb_color bevelShadowColor = tint_color(base, 1.08); - - if ((flags & B_DISABLED) != 0) - bevelShadowColor = base; - - if ((flags & B_ACTIVATED) != 0) - bevelShadowColor = tint_color(base, B_DARKEN_1_TINT); - - return bevelShadowColor; -} - - -void -BControlLook::_FillGradient(BView* view, const BRect& rect, - const rgb_color& base, float topTint, float bottomTint, - orientation orientation) -{ - BGradientLinear gradient; - _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); - view->FillRect(rect, gradient); -} - - -void -BControlLook::_FillGlossyGradient(BView* view, const BRect& rect, - const rgb_color& base, float topTint, float middle1Tint, - float middle2Tint, float bottomTint, orientation orientation) -{ - BGradientLinear gradient; - _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, - middle2Tint, bottomTint, orientation); - view->FillRect(rect, gradient); -} - - -void -BControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, - const rgb_color& base, float topTint, float bottomTint, - orientation orientation) const -{ - gradient.AddColor(tint_color(base, topTint), 0); - gradient.AddColor(tint_color(base, bottomTint), 255); - gradient.SetStart(rect.LeftTop()); - if (orientation == B_HORIZONTAL) - gradient.SetEnd(rect.LeftBottom()); - else - gradient.SetEnd(rect.RightTop()); -} - - -void -BControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, - const rgb_color& base, float topTint, float middle1Tint, - float middle2Tint, float bottomTint, - orientation orientation) const -{ - gradient.AddColor(tint_color(base, topTint), 0); - gradient.AddColor(tint_color(base, middle1Tint), 132); - gradient.AddColor(tint_color(base, middle2Tint), 136); - gradient.AddColor(tint_color(base, bottomTint), 255); - gradient.SetStart(rect.LeftTop()); - if (orientation == B_HORIZONTAL) - gradient.SetEnd(rect.LeftBottom()); - else - gradient.SetEnd(rect.RightTop()); -} - - -void -BControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect, - const rgb_color& base, uint32 flags, orientation orientation) const -{ - float topTint = 0.49; - float middleTint1 = 0.62; - float middleTint2 = 0.76; - float bottomTint = 0.90; - - if ((flags & B_ACTIVATED) != 0) { - topTint = 1.11; - bottomTint = 1.08; - } - - if ((flags & B_DISABLED) != 0) { - topTint = (topTint + B_NO_TINT) / 2; - middleTint1 = (middleTint1 + B_NO_TINT) / 2; - middleTint2 = (middleTint2 + B_NO_TINT) / 2; - bottomTint = (bottomTint + B_NO_TINT) / 2; - } else if ((flags & B_HOVER) != 0) { - topTint *= kHoverTintFactor; - middleTint1 *= kHoverTintFactor; - middleTint2 *= kHoverTintFactor; - bottomTint *= kHoverTintFactor; - } - - if ((flags & B_ACTIVATED) != 0) { - _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); - } else { - _MakeGlossyGradient(gradient, rect, base, topTint, middleTint1, - middleTint2, bottomTint, orientation); - } -} - - - -bool -BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, - rgb_color& color, uint32 flags) const -{ - if ((flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED | B_CLICKED)) == 0) { - // no mark to be drawn at all - return false; - } - - color = ui_color(B_CONTROL_MARK_COLOR); - - float mix = 1.0; - - if ((flags & B_DISABLED) != 0) { - // activated, but disabled - mix = 0.4; - } else if ((flags & B_CLICKED) != 0) { - if ((flags & B_ACTIVATED) != 0) { - // losing activation - mix = 0.7; - } else { - // becoming activated (or losing partial activation) - mix = 0.3; - } - } else if ((flags & B_PARTIALLY_ACTIVATED) != 0) { - // partially activated - mix = 0.5; - } else { - // simply activated - } - - color.red = uint8(color.red * mix + base.red * (1.0 - mix)); - color.green = uint8(color.green * mix + base.green * (1.0 - mix)); - color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); - - return true; -} - - // NOTE: May come from a add-on in the future. Initialized in // InterfaceDefs.cpp BControlLook* be_control_look = NULL; diff --git a/src/kits/interface/HaikuControlLook.cpp b/src/kits/interface/HaikuControlLook.cpp new file mode 100644 index 0000000000..cdbb1e1e30 --- /dev/null +++ b/src/kits/interface/HaikuControlLook.cpp @@ -0,0 +1,3601 @@ +/* + * Copyright 2009, Stephan Aßmus + * Copyright 2012-2017 Haiku, Inc. All rights reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stephan Aßmus, superstippi@gmx.de + * John Scipione, jscipione@gmail.com + */ + + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace BPrivate { + + +static const float kEdgeBevelLightTint = 0.59; +static const float kEdgeBevelShadowTint = 1.0735; +static const float kHoverTintFactor = 0.85; + +static const float kButtonPopUpIndicatorWidth = 11; + + +HaikuControlLook::HaikuControlLook() + : + fCachedOutline(false) +{ +} + + +HaikuControlLook::~HaikuControlLook() +{ +} + + +BAlignment +HaikuControlLook::DefaultLabelAlignment() const +{ + return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); +} + + +float +HaikuControlLook::DefaultLabelSpacing() const +{ + return ceilf(be_plain_font->Size() / 2.0); +} + + +float +HaikuControlLook::DefaultItemSpacing() const +{ + return ceilf(be_plain_font->Size() * 0.85); +} + + +uint32 +HaikuControlLook::Flags(BControl* control) const +{ + uint32 flags = B_IS_CONTROL; + + if (!control->IsEnabled()) + flags |= B_DISABLED; + + if (control->IsFocus() && control->Window() != NULL + && control->Window()->IsActive()) { + flags |= B_FOCUSED; + } + + switch (control->Value()) { + case B_CONTROL_ON: + flags |= B_ACTIVATED; + break; + case B_CONTROL_PARTIALLY_ON: + flags |= B_PARTIALLY_ACTIVATED; + break; + } + + if (control->Parent() != NULL + && (control->Parent()->Flags() & B_DRAW_ON_CHILDREN) != 0) { + // In this constellation, assume we want to render the control + // against the already existing view contents of the parent view. + flags |= B_BLEND_FRAME; + } + + return flags; +} + + +// #pragma mark - + + +void +HaikuControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, const rgb_color& background, uint32 flags, + uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, + background, 1.0, 1.0, flags, borders); +} + + +void +HaikuControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, + float radius, const rgb_color& base, const rgb_color& background, uint32 flags, + uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, + base, background, 1.0, 1.0, flags, borders); +} + + +void +HaikuControlLook::DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + const rgb_color& background, uint32 flags, + uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, + leftBottomRadius, rightBottomRadius, base, background, + 1.0, 1.0, flags, borders); +} + + +void +HaikuControlLook::DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, + base, false, flags, borders, orientation); +} + + +void +HaikuControlLook::DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, + uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, + radius, base, false, flags, borders, orientation); +} + + +void +HaikuControlLook::DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + uint32 flags, uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, leftTopRadius, + rightTopRadius, leftBottomRadius, rightBottomRadius, base, false, flags, + borders, orientation); +} + + +void +HaikuControlLook::DrawMenuBarBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // the surface edges + + // colors + float topTint; + float bottomTint; + + if ((flags & B_ACTIVATED) != 0) { + rgb_color bevelColor1 = tint_color(base, 1.40); + rgb_color bevelColor2 = tint_color(base, 1.25); + + topTint = 1.25; + bottomTint = 1.20; + + _DrawFrame(view, rect, + bevelColor1, bevelColor1, + bevelColor2, bevelColor2, + borders & B_TOP_BORDER); + } else { + rgb_color cornerColor = tint_color(base, 0.9); + rgb_color bevelColorTop = tint_color(base, 0.5); + rgb_color bevelColorLeft = tint_color(base, 0.7); + rgb_color bevelColorRightBottom = tint_color(base, 1.08); + + topTint = 0.69; + bottomTint = 1.03; + + _DrawFrame(view, rect, + bevelColorLeft, bevelColorTop, + bevelColorRightBottom, bevelColorRightBottom, + cornerColor, cornerColor, + borders); + } + + // draw surface top + _FillGradient(view, rect, base, topTint, bottomTint); +} + + +void +HaikuControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, + const rgb_color& background, uint32 flags, uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, base, + background, 0.6, 1.0, flags, borders); +} + + +void +HaikuControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, float radius, const rgb_color& base, + const rgb_color& background, uint32 flags, uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, radius, radius, radius, radius, + base, background, 0.6, 1.0, flags, borders); +} + + +void +HaikuControlLook::DrawMenuFieldFrame(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, + float rightTopRadius, float leftBottomRadius, + float rightBottomRadius, const rgb_color& base, + const rgb_color& background, uint32 flags, uint32 borders) +{ + _DrawButtonFrame(view, rect, updateRect, leftTopRadius, rightTopRadius, + leftBottomRadius, rightBottomRadius, base, background, 0.6, 1.0, + flags, borders); +} + + +void +HaikuControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, bool popupIndicator, + uint32 flags) +{ + _DrawMenuFieldBackgroundOutside(view, rect, updateRect, + 0.0f, 0.0f, 0.0f, 0.0f, base, popupIndicator, flags); +} + + +void +HaikuControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + _DrawMenuFieldBackgroundInside(view, rect, updateRect, + 0.0f, 0.0f, 0.0f, 0.0f, base, flags, borders); +} + + +void +HaikuControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, float radius, const rgb_color& base, + bool popupIndicator, uint32 flags) +{ + _DrawMenuFieldBackgroundOutside(view, rect, updateRect, radius, radius, + radius, radius, base, popupIndicator, flags); +} + + +void +HaikuControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + bool popupIndicator, uint32 flags) +{ + _DrawMenuFieldBackgroundOutside(view, rect, updateRect, leftTopRadius, + rightTopRadius, leftBottomRadius, rightBottomRadius, base, + popupIndicator, flags); +} + + +void +HaikuControlLook::DrawMenuBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // surface top color + rgb_color background = tint_color(base, 0.75); + + // inner bevel colors + rgb_color bevelLightColor; + rgb_color bevelShadowColor; + + if ((flags & B_DISABLED) != 0) { + bevelLightColor = tint_color(background, 0.80); + bevelShadowColor = tint_color(background, 1.07); + } else { + bevelLightColor = tint_color(background, 0.6); + bevelShadowColor = tint_color(background, 1.12); + } + + // draw inner bevel + _DrawFrame(view, rect, + bevelLightColor, bevelLightColor, + bevelShadowColor, bevelShadowColor, + borders); + + // draw surface top + view->SetHighColor(background); + view->FillRect(rect); +} + + +void +HaikuControlLook::DrawMenuItemBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // surface edges + float topTint; + float bottomTint; + rgb_color selectedColor = base; + + if ((flags & B_ACTIVATED) != 0) { + topTint = 0.9; + bottomTint = 1.05; + } else if ((flags & B_DISABLED) != 0) { + topTint = 0.80; + bottomTint = 1.07; + } else { + topTint = 0.6; + bottomTint = 1.12; + } + + rgb_color bevelLightColor = tint_color(selectedColor, topTint); + rgb_color bevelShadowColor = tint_color(selectedColor, bottomTint); + + // draw surface edges + _DrawFrame(view, rect, + bevelLightColor, bevelLightColor, + bevelShadowColor, bevelShadowColor, + borders); + + // draw surface top + view->SetLowColor(selectedColor); +// _FillGradient(view, rect, selectedColor, topTint, bottomTint); + _FillGradient(view, rect, selectedColor, bottomTint, topTint); +} + + +void +HaikuControlLook::DrawStatusBar(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, const rgb_color& barColor, float progressPosition) +{ + if (!rect.Intersects(updateRect)) + return; + + _DrawOuterResessedFrame(view, rect, base, 0.6); + + // colors + rgb_color dark1BorderColor = tint_color(base, 1.3); + rgb_color dark2BorderColor = tint_color(base, 1.2); + rgb_color dark1FilledBorderColor = tint_color(barColor, 1.20); + rgb_color dark2FilledBorderColor = tint_color(barColor, 1.45); + + BRect filledRect(rect); + filledRect.right = progressPosition - 1; + + BRect nonfilledRect(rect); + nonfilledRect.left = progressPosition; + + bool filledSurface = filledRect.Width() > 0; + bool nonfilledSurface = nonfilledRect.Width() > 0; + + if (filledSurface) { + _DrawFrame(view, filledRect, + dark1FilledBorderColor, dark1FilledBorderColor, + dark2FilledBorderColor, dark2FilledBorderColor); + + _FillGlossyGradient(view, filledRect, barColor, 0.55, 0.68, 0.76, 0.90); + } + + if (nonfilledSurface) { + _DrawFrame(view, nonfilledRect, dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor, + B_TOP_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); + + if (nonfilledRect.left < nonfilledRect.right) { + // shadow from fill bar, or left border + rgb_color leftBorder = dark1BorderColor; + if (filledSurface) + leftBorder = tint_color(base, 0.50); + view->SetHighColor(leftBorder); + view->StrokeLine(nonfilledRect.LeftTop(), + nonfilledRect.LeftBottom()); + nonfilledRect.left++; + } + + _FillGradient(view, nonfilledRect, base, 0.25, 0.06); + } +} + + +void +HaikuControlLook::DrawCheckBox(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags) +{ + if (!rect.Intersects(updateRect)) + return; + + rgb_color dark1BorderColor; + rgb_color dark2BorderColor; + rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if ((flags & B_DISABLED) != 0) { + _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags); + + dark1BorderColor = tint_color(base, 1.15); + dark2BorderColor = tint_color(base, 1.15); + } else if ((flags & B_CLICKED) != 0) { + dark1BorderColor = tint_color(base, 1.50); + dark2BorderColor = tint_color(base, 1.48); + + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor); + + dark2BorderColor = dark1BorderColor; + } else { + _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags); + + dark1BorderColor = tint_color(base, 1.40); + dark2BorderColor = tint_color(base, 1.38); + } + + if ((flags & B_FOCUSED) != 0) { + dark1BorderColor = navigationColor; + dark2BorderColor = navigationColor; + } + + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor); + + if ((flags & B_DISABLED) != 0) + _FillGradient(view, rect, base, 0.4, 0.2); + else + _FillGradient(view, rect, base, 0.15, 0.0); + + rgb_color markColor; + if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { + view->SetHighColor(markColor); + + BFont font; + view->GetFont(&font); + float inset = std::max(2.0f, roundf(font.Size() / 6)); + rect.InsetBy(inset, inset); + + float penSize = std::max(1.0f, ceilf(rect.Width() / 3.5f)); + if (penSize > 1.0f && fmodf(penSize, 2.0f) == 0.0f) { + // Tweak ends to "include" the pixel at the index, + // we need to do this in order to produce results like R5, + // where coordinates were inclusive + rect.right++; + rect.bottom++; + } + + view->SetPenSize(penSize); + view->SetDrawingMode(B_OP_OVER); + view->StrokeLine(rect.LeftTop(), rect.RightBottom()); + view->StrokeLine(rect.LeftBottom(), rect.RightTop()); + } +} + + +void +HaikuControlLook::DrawRadioButton(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags) +{ + if (!rect.Intersects(updateRect)) + return; + + rgb_color borderColor; + rgb_color bevelLight; + rgb_color bevelShadow; + rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if ((flags & B_DISABLED) != 0) { + borderColor = tint_color(base, 1.15); + bevelLight = base; + bevelShadow = base; + } else if ((flags & B_CLICKED) != 0) { + borderColor = tint_color(base, 1.50); + bevelLight = borderColor; + bevelShadow = borderColor; + } else { + borderColor = tint_color(base, 1.45); + bevelLight = tint_color(base, 0.55); + bevelShadow = tint_color(base, 1.11); + } + + if ((flags & B_FOCUSED) != 0) { + borderColor = navigationColor; + } + + BGradientLinear bevelGradient; + bevelGradient.AddColor(bevelShadow, 0); + bevelGradient.AddColor(bevelLight, 255); + bevelGradient.SetStart(rect.LeftTop()); + bevelGradient.SetEnd(rect.RightBottom()); + + view->FillEllipse(rect, bevelGradient); + rect.InsetBy(1, 1); + + bevelGradient.MakeEmpty(); + bevelGradient.AddColor(borderColor, 0); + bevelGradient.AddColor(tint_color(borderColor, 0.8), 255); + view->FillEllipse(rect, bevelGradient); + rect.InsetBy(1, 1); + + float topTint; + float bottomTint; + if ((flags & B_DISABLED) != 0) { + topTint = 0.4; + bottomTint = 0.2; + } else { + topTint = 0.15; + bottomTint = 0.0; + } + + BGradientLinear gradient; + _MakeGradient(gradient, rect, base, topTint, bottomTint); + view->FillEllipse(rect, gradient); + + rgb_color markColor; + if (_RadioButtonAndCheckBoxMarkColor(base, markColor, flags)) { + view->SetHighColor(markColor); + BFont font; + view->GetFont(&font); + float inset = roundf(font.Size() / 4); + rect.InsetBy(inset, inset); + view->FillEllipse(rect); + } +} + + +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); +} + + +void +HaikuControlLook::DrawScrollBarBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + 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 { + gradient1Tint = 1.10; + gradient2Tint = 1.05; + darkEdge1Tint = B_DARKEN_3_TINT; + darkEdge2Tint = B_DARKEN_2_TINT; + shadowTint = gradient1Tint; + } + + rgb_color darkEdge1 = tint_color(base, darkEdge1Tint); + rgb_color darkEdge2 = tint_color(base, darkEdge2Tint); + rgb_color shadow = tint_color(base, shadowTint); + + if (orientation == B_HORIZONTAL) { + // dark vertical line on left edge + if (rect.Width() > 0) { + view->SetHighColor(darkEdge1); + view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); + rect.left++; + } + // dark vertical line on right edge + if (rect.Width() >= 0) { + view->SetHighColor(darkEdge2); + view->StrokeLine(rect.RightTop(), rect.RightBottom()); + rect.right--; + } + // vertical shadow line after left edge + if (rect.Width() >= 0) { + view->SetHighColor(shadow); + view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); + rect.left++; + } + // fill + if (rect.Width() >= 0) { + _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, + orientation); + } + } else { + // dark vertical line on top edge + if (rect.Height() > 0) { + view->SetHighColor(darkEdge1); + view->StrokeLine(rect.LeftTop(), rect.RightTop()); + rect.top++; + } + // dark vertical line on bottom edge + if (rect.Height() >= 0) { + view->SetHighColor(darkEdge2); + view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); + rect.bottom--; + } + // horizontal shadow line after top edge + if (rect.Height() >= 0) { + view->SetHighColor(shadow); + view->StrokeLine(rect.LeftTop(), rect.RightTop()); + rect.top++; + } + // fill + if (rect.Height() >= 0) { + _FillGradient(view, rect, base, gradient1Tint, gradient2Tint, + orientation); + } + } +} + + +void +HaikuControlLook::DrawScrollViewFrame(BView* view, BRect& rect, + const BRect& updateRect, BRect verticalScrollBarFrame, + BRect horizontalScrollBarFrame, const rgb_color& base, + border_style borderStyle, uint32 flags, uint32 _borders) +{ + // calculate scroll corner rect before messing with the "rect" + BRect scrollCornerFillRect(rect.right, rect.bottom, + rect.right, rect.bottom); + + if (horizontalScrollBarFrame.IsValid()) + scrollCornerFillRect.left = horizontalScrollBarFrame.right + 1; + + if (verticalScrollBarFrame.IsValid()) + scrollCornerFillRect.top = verticalScrollBarFrame.bottom + 1; + + if (borderStyle == B_NO_BORDER) { + if (scrollCornerFillRect.IsValid()) { + view->SetHighColor(base); + view->FillRect(scrollCornerFillRect); + } + return; + } + + bool excludeScrollCorner = borderStyle == B_FANCY_BORDER + && horizontalScrollBarFrame.IsValid() + && verticalScrollBarFrame.IsValid(); + + uint32 borders = _borders; + if (excludeScrollCorner) { + rect.bottom = horizontalScrollBarFrame.top; + rect.right = verticalScrollBarFrame.left; + borders &= ~(B_RIGHT_BORDER | B_BOTTOM_BORDER); + } + + rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); + + if (borderStyle == B_FANCY_BORDER) + _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); + + if ((flags & B_FOCUSED) != 0) { + rgb_color focusColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + _DrawFrame(view, rect, focusColor, focusColor, focusColor, focusColor, + borders); + } else { + _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, + scrollbarFrameColor, scrollbarFrameColor, borders); + } + + if (excludeScrollCorner) { + horizontalScrollBarFrame.InsetBy(-1, -1); + // do not overdraw the top edge + horizontalScrollBarFrame.top += 2; + borders = _borders; + borders &= ~B_TOP_BORDER; + _DrawOuterResessedFrame(view, horizontalScrollBarFrame, base, + 1.0, 1.0, flags, borders); + _DrawFrame(view, horizontalScrollBarFrame, scrollbarFrameColor, + scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, + borders); + + verticalScrollBarFrame.InsetBy(-1, -1); + // do not overdraw the left edge + verticalScrollBarFrame.left += 2; + borders = _borders; + borders &= ~B_LEFT_BORDER; + _DrawOuterResessedFrame(view, verticalScrollBarFrame, base, + 1.0, 1.0, flags, borders); + _DrawFrame(view, verticalScrollBarFrame, scrollbarFrameColor, + scrollbarFrameColor, scrollbarFrameColor, scrollbarFrameColor, + borders); + + // exclude recessed frame + scrollCornerFillRect.top++; + scrollCornerFillRect.left++; + } + + if (scrollCornerFillRect.IsValid()) { + view->SetHighColor(base); + view->FillRect(scrollCornerFillRect); + } +} + + +void +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; + float vInset = rect.Height() / 3; + rect.InsetBy(hInset, vInset); + + switch (direction) { + case B_LEFT_ARROW: + tri1.Set(rect.right, rect.top); + tri2.Set(rect.right - rect.Width() / 1.33, + (rect.top + rect.bottom + 1) / 2); + tri3.Set(rect.right, rect.bottom + 1); + break; + case B_RIGHT_ARROW: + tri1.Set(rect.left + 1, rect.bottom + 1); + tri2.Set(rect.left + 1 + rect.Width() / 1.33, + (rect.top + rect.bottom + 1) / 2); + tri3.Set(rect.left + 1, rect.top); + break; + case B_UP_ARROW: + tri1.Set(rect.left, rect.bottom); + tri2.Set((rect.left + rect.right + 1) / 2, + rect.bottom - rect.Height() / 1.33); + tri3.Set(rect.right + 1, rect.bottom); + break; + case B_DOWN_ARROW: + default: + tri1.Set(rect.left, rect.top + 1); + tri2.Set((rect.left + rect.right + 1) / 2, + rect.top + 1 + rect.Height() / 1.33); + tri3.Set(rect.right + 1, rect.top + 1); + break; + case B_LEFT_UP_ARROW: + tri1.Set(rect.left, rect.bottom); + tri2.Set(rect.left, rect.top); + tri3.Set(rect.right - 1, rect.top); + break; + case B_RIGHT_UP_ARROW: + tri1.Set(rect.left + 1, rect.top); + tri2.Set(rect.right, rect.top); + tri3.Set(rect.right, rect.bottom); + break; + case B_RIGHT_DOWN_ARROW: + tri1.Set(rect.right, rect.top); + tri2.Set(rect.right, rect.bottom); + tri3.Set(rect.left + 1, rect.bottom); + break; + case B_LEFT_DOWN_ARROW: + tri1.Set(rect.right - 1, rect.bottom); + tri2.Set(rect.left, rect.bottom); + tri3.Set(rect.left, rect.top); + break; + } + + BShape arrowShape; + arrowShape.MoveTo(tri1); + arrowShape.LineTo(tri2); + arrowShape.LineTo(tri3); + + if ((flags & B_DISABLED) != 0) + tint = (tint + B_NO_TINT + B_NO_TINT) / 3; + + view->SetHighColor(tint_color(base, tint)); + + float penSize = view->PenSize(); + drawing_mode mode = view->DrawingMode(); + + view->MovePenTo(BPoint(0, 0)); + + view->SetPenSize(ceilf(hInset / 2.0)); + view->SetDrawingMode(B_OP_OVER); + view->StrokeShape(&arrowShape); + + view->SetPenSize(penSize); + view->SetDrawingMode(mode); +} + + +rgb_color +HaikuControlLook::SliderBarColor(const rgb_color& base) +{ + return tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_1_TINT); +} + + +void +HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, + const rgb_color& base, rgb_color leftFillColor, rgb_color rightFillColor, + float sliderScale, uint32 flags, orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // save the clipping constraints of the view + view->PushState(); + + // separate the bar in two sides + float sliderPosition; + BRect leftBarSide = rect; + BRect rightBarSide = rect; + + if (orientation == B_HORIZONTAL) { + sliderPosition = floorf(rect.left + 2 + (rect.Width() - 2) + * sliderScale); + leftBarSide.right = sliderPosition - 1; + rightBarSide.left = sliderPosition; + } else { + // NOTE: position is reverse of coords + sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) + * (1.0 - sliderScale)); + leftBarSide.top = sliderPosition; + rightBarSide.bottom = sliderPosition - 1; + } + + // fill the background for the corners, exclude the middle bar for now + BRegion region(rect); + region.Exclude(rightBarSide); + view->ConstrainClippingRegion(®ion); + + view->PushState(); + + DrawSliderBar(view, rect, updateRect, base, leftFillColor, flags, + orientation); + + view->PopState(); + + region.Set(rect); + region.Exclude(leftBarSide); + view->ConstrainClippingRegion(®ion); + + view->PushState(); + + DrawSliderBar(view, rect, updateRect, base, rightFillColor, flags, + orientation); + + view->PopState(); + + // restore the clipping constraints of the view + view->PopState(); +} + + +void +HaikuControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, + const rgb_color& base, rgb_color fillColor, uint32 flags, + orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // separate the rect into corners + BRect leftCorner(rect); + BRect rightCorner(rect); + BRect barRect(rect); + + if (orientation == B_HORIZONTAL) { + leftCorner.right = leftCorner.left + leftCorner.Height(); + rightCorner.left = rightCorner.right - rightCorner.Height(); + barRect.left += ceilf(barRect.Height() / 2); + barRect.right -= ceilf(barRect.Height() / 2); + } else { + leftCorner.bottom = leftCorner.top + leftCorner.Width(); + rightCorner.top = rightCorner.bottom - rightCorner.Width(); + barRect.top += ceilf(barRect.Width() / 2); + barRect.bottom -= ceilf(barRect.Width() / 2); + } + + // fill the background for the corners, exclude the middle bar for now + BRegion region(rect); + region.Exclude(barRect); + view->ConstrainClippingRegion(®ion); + + if ((flags & B_BLEND_FRAME) == 0) { + view->SetHighColor(base); + view->FillRect(rect); + } + + // figure out the tints to be used + float edgeLightTint; + float edgeShadowTint; + float frameLightTint; + float frameShadowTint; + float fillLightTint; + float fillShadowTint; + uint8 edgeLightAlpha; + uint8 edgeShadowAlpha; + uint8 frameLightAlpha; + uint8 frameShadowAlpha; + + if ((flags & B_DISABLED) != 0) { + edgeLightTint = 1.0; + edgeShadowTint = 1.0; + frameLightTint = 1.20; + frameShadowTint = 1.25; + fillLightTint = 0.9; + fillShadowTint = 1.05; + edgeLightAlpha = 12; + edgeShadowAlpha = 12; + frameLightAlpha = 40; + frameShadowAlpha = 45; + + fillColor.red = uint8(fillColor.red * 0.4 + base.red * 0.6); + fillColor.green = uint8(fillColor.green * 0.4 + base.green * 0.6); + fillColor.blue = uint8(fillColor.blue * 0.4 + base.blue * 0.6); + } else { + edgeLightTint = 0.65; + edgeShadowTint = 1.07; + frameLightTint = 1.40; + frameShadowTint = 1.50; + fillLightTint = 0.8; + fillShadowTint = 1.1; + edgeLightAlpha = 15; + edgeShadowAlpha = 15; + frameLightAlpha = 92; + frameShadowAlpha = 107; + } + + rgb_color edgeLightColor; + rgb_color edgeShadowColor; + rgb_color frameLightColor; + rgb_color frameShadowColor; + rgb_color fillLightColor = tint_color(fillColor, fillLightTint); + rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); + + drawing_mode oldMode = view->DrawingMode(); + + if ((flags & B_BLEND_FRAME) != 0) { + edgeLightColor = (rgb_color){ 255, 255, 255, edgeLightAlpha }; + edgeShadowColor = (rgb_color){ 0, 0, 0, edgeShadowAlpha }; + frameLightColor = (rgb_color){ 0, 0, 0, frameLightAlpha }; + frameShadowColor = (rgb_color){ 0, 0, 0, frameShadowAlpha }; + + view->SetDrawingMode(B_OP_ALPHA); + } else { + edgeLightColor = tint_color(base, edgeLightTint); + edgeShadowColor = tint_color(base, edgeShadowTint); + frameLightColor = tint_color(fillColor, frameLightTint); + frameShadowColor = tint_color(fillColor, frameShadowTint); + } + + if (orientation == B_HORIZONTAL) { + _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, + edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, + fillShadowColor, 1.0, 1.0, 0.0, -1.0, orientation); + + _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, + edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, + fillShadowColor, 0.0, 1.0, -1.0, -1.0, orientation); + } else { + _DrawRoundBarCorner(view, leftCorner, updateRect, edgeLightColor, + edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, + fillShadowColor, 1.0, 1.0, -1.0, 0.0, orientation); + + _DrawRoundBarCorner(view, rightCorner, updateRect, edgeLightColor, + edgeShadowColor, frameLightColor, frameShadowColor, fillLightColor, + fillShadowColor, 1.0, 0.0, -1.0, -1.0, orientation); + } + + view->ConstrainClippingRegion(NULL); + + view->BeginLineArray(4); + if (orientation == B_HORIZONTAL) { + 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.LeftBottom(), barRect.RightBottom(), + frameLightColor); + barRect.InsetBy(0, 1); + } else { + 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.RightTop(), barRect.RightBottom(), + frameLightColor); + barRect.InsetBy(1, 0); + } + view->EndLineArray(); + + view->SetDrawingMode(oldMode); + + _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, + orientation); +} + + +void +HaikuControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // figure out frame color + rgb_color frameLightColor; + rgb_color frameShadowColor; + rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; + + if ((flags & B_FOCUSED) != 0) { + // focused + frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + frameShadowColor = frameLightColor; + } else { + // figure out the tints to be used + float frameLightTint; + float frameShadowTint; + + if ((flags & B_DISABLED) != 0) { + frameLightTint = 1.30; + frameShadowTint = 1.35; + shadowColor.alpha = 30; + } else { + frameLightTint = 1.6; + frameShadowTint = 1.65; + } + + frameLightColor = tint_color(base, frameLightTint); + frameShadowColor = tint_color(base, frameShadowTint); + } + + BRect originalRect(rect); + rect.right--; + rect.bottom--; + + _DrawFrame(view, rect, frameLightColor, frameLightColor, + frameShadowColor, frameShadowColor); + + flags &= ~B_ACTIVATED; + DrawButtonBackground(view, rect, updateRect, base, flags); + + // thumb shadow + view->SetDrawingMode(B_OP_ALPHA); + view->SetHighColor(shadowColor); + originalRect.left++; + originalRect.top++; + view->StrokeLine(originalRect.LeftBottom(), originalRect.RightBottom()); + originalRect.bottom--; + view->StrokeLine(originalRect.RightTop(), originalRect.RightBottom()); + + // thumb edge + if (orientation == B_HORIZONTAL) { + rect.InsetBy(0, floorf(rect.Height() / 4)); + rect.left = floorf((rect.left + rect.right) / 2); + rect.right = rect.left + 1; + shadowColor = tint_color(base, B_DARKEN_2_TINT); + shadowColor.alpha = 128; + view->SetHighColor(shadowColor); + view->StrokeLine(rect.LeftTop(), rect.LeftBottom()); + rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); + lightColor.alpha = 128; + view->SetHighColor(lightColor); + view->StrokeLine(rect.RightTop(), rect.RightBottom()); + } else { + rect.InsetBy(floorf(rect.Width() / 4), 0); + rect.top = floorf((rect.top + rect.bottom) / 2); + rect.bottom = rect.top + 1; + shadowColor = tint_color(base, B_DARKEN_2_TINT); + shadowColor.alpha = 128; + view->SetHighColor(shadowColor); + view->StrokeLine(rect.LeftTop(), rect.RightTop()); + rgb_color lightColor = tint_color(base, B_LIGHTEN_2_TINT); + lightColor.alpha = 128; + view->SetHighColor(lightColor); + view->StrokeLine(rect.LeftBottom(), rect.RightBottom()); + } + + view->SetDrawingMode(B_OP_COPY); +} + + +void +HaikuControlLook::DrawSliderTriangle(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + orientation orientation) +{ + DrawSliderTriangle(view, rect, updateRect, base, base, flags, orientation); +} + + +void +HaikuControlLook::DrawSliderTriangle(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, const rgb_color& fill, + uint32 flags, orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // figure out frame color + rgb_color frameLightColor; + rgb_color frameShadowColor; + rgb_color shadowColor = (rgb_color){ 0, 0, 0, 60 }; + + float topTint = 0.49; + float middleTint1 = 0.62; + float middleTint2 = 0.76; + float bottomTint = 0.90; + + if ((flags & B_DISABLED) != 0) { + topTint = (topTint + B_NO_TINT) / 2; + middleTint1 = (middleTint1 + B_NO_TINT) / 2; + middleTint2 = (middleTint2 + B_NO_TINT) / 2; + bottomTint = (bottomTint + B_NO_TINT) / 2; + } else if ((flags & B_HOVER) != 0) { + topTint *= kHoverTintFactor; + middleTint1 *= kHoverTintFactor; + middleTint2 *= kHoverTintFactor; + bottomTint *= kHoverTintFactor; + } + + if ((flags & B_FOCUSED) != 0) { + // focused + frameLightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + frameShadowColor = frameLightColor; + } else { + // figure out the tints to be used + float frameLightTint; + float frameShadowTint; + + if ((flags & B_DISABLED) != 0) { + frameLightTint = 1.30; + frameShadowTint = 1.35; + shadowColor.alpha = 30; + } else { + frameLightTint = 1.6; + frameShadowTint = 1.65; + } + + frameLightColor = tint_color(base, frameLightTint); + frameShadowColor = tint_color(base, frameShadowTint); + } + + // make room for the shadow + rect.right--; + rect.bottom--; + + uint32 viewFlags = view->Flags(); + view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); + view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); + + float centerh = (rect.left + rect.right) / 2; + float centerv = (rect.top + rect.bottom) / 2; + + BShape shape; + if (orientation == B_HORIZONTAL) { + shape.MoveTo(BPoint(rect.left + 0.5, rect.bottom + 0.5)); + shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); + shape.LineTo(BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5)); + shape.LineTo(BPoint(centerh + 0.5, rect.top + 0.5)); + shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); + } else { + shape.MoveTo(BPoint(rect.right + 0.5, rect.top + 0.5)); + shape.LineTo(BPoint(rect.right + 0.5, rect.bottom + 0.5)); + shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.bottom + 0.5)); + shape.LineTo(BPoint(rect.left + 0.5, centerv + 0.5)); + shape.LineTo(BPoint(rect.right - 1 + 0.5, rect.top + 0.5)); + } + shape.Close(); + + view->MovePenTo(BPoint(1, 1)); + + view->SetDrawingMode(B_OP_ALPHA); + view->SetHighColor(shadowColor); + view->StrokeShape(&shape); + + view->MovePenTo(B_ORIGIN); + + view->SetDrawingMode(B_OP_COPY); + view->SetHighColor(frameLightColor); + view->StrokeShape(&shape); + + rect.InsetBy(1, 1); + shape.Clear(); + if (orientation == B_HORIZONTAL) { + shape.MoveTo(BPoint(rect.left, rect.bottom + 1)); + shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); + shape.LineTo(BPoint(centerh + 0.5, rect.top)); + } else { + shape.MoveTo(BPoint(rect.right + 1, rect.top)); + shape.LineTo(BPoint(rect.right + 1, rect.bottom + 1)); + shape.LineTo(BPoint(rect.left, centerv + 0.5)); + } + shape.Close(); + + BGradientLinear gradient; + if ((flags & B_DISABLED) != 0) { + _MakeGradient(gradient, rect, fill, topTint, bottomTint); + } else { + _MakeGlossyGradient(gradient, rect, fill, topTint, middleTint1, + middleTint2, bottomTint); + } + + view->FillShape(&shape, gradient); + + view->SetFlags(viewFlags); +} + + +void +HaikuControlLook::DrawSliderHashMarks(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, int32 count, + hash_mark_location location, uint32 flags, orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + rgb_color lightColor; + rgb_color darkColor; + + if ((flags & B_DISABLED) != 0) { + lightColor = tint_color(base, 0.9); + darkColor = tint_color(base, 1.07); + } else { + lightColor = tint_color(base, 0.8); + darkColor = tint_color(base, 1.14); + } + + int32 hashMarkCount = std::max(count, (int32)2); + // draw at least two hashmarks at min/max if + // fHashMarks != B_HASH_MARKS_NONE + float factor; + float startPos; + if (orientation == B_HORIZONTAL) { + factor = (rect.Width() - 2) / (hashMarkCount - 1); + startPos = rect.left + 1; + } else { + factor = (rect.Height() - 2) / (hashMarkCount - 1); + startPos = rect.top + 1; + } + + if (location & B_HASH_MARKS_TOP) { + view->BeginLineArray(hashMarkCount * 2); + + if (orientation == B_HORIZONTAL) { + float pos = startPos; + for (int32 i = 0; i < hashMarkCount; i++) { + view->AddLine(BPoint(pos, rect.top), + BPoint(pos, rect.top + 4), darkColor); + view->AddLine(BPoint(pos + 1, rect.top), + BPoint(pos + 1, rect.top + 4), lightColor); + + pos += factor; + } + } else { + float pos = startPos; + for (int32 i = 0; i < hashMarkCount; i++) { + view->AddLine(BPoint(rect.left, pos), + BPoint(rect.left + 4, pos), darkColor); + view->AddLine(BPoint(rect.left, pos + 1), + BPoint(rect.left + 4, pos + 1), lightColor); + + pos += factor; + } + } + + view->EndLineArray(); + } + + if ((location & B_HASH_MARKS_BOTTOM) != 0) { + view->BeginLineArray(hashMarkCount * 2); + + if (orientation == B_HORIZONTAL) { + float pos = startPos; + for (int32 i = 0; i < hashMarkCount; i++) { + view->AddLine(BPoint(pos, rect.bottom - 4), + BPoint(pos, rect.bottom), darkColor); + view->AddLine(BPoint(pos + 1, rect.bottom - 4), + BPoint(pos + 1, rect.bottom), lightColor); + + pos += factor; + } + } else { + float pos = startPos; + for (int32 i = 0; i < hashMarkCount; i++) { + view->AddLine(BPoint(rect.right - 4, pos), + BPoint(rect.right, pos), darkColor); + view->AddLine(BPoint(rect.right - 4, pos + 1), + BPoint(rect.right, pos + 1), lightColor); + + pos += factor; + } + } + + view->EndLineArray(); + } +} + + +void +HaikuControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, uint32 borders, uint32 side) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // Snap the rectangle to pixels to avoid rounding errors. + rect.left = floorf(rect.left); + rect.right = floorf(rect.right); + rect.top = floorf(rect.top); + rect.bottom = floorf(rect.bottom); + + // save the clipping constraints of the view + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + rgb_color edgeShadowColor; + rgb_color edgeLightColor; + rgb_color frameShadowColor; + rgb_color frameLightColor; + rgb_color bevelShadowColor; + rgb_color bevelLightColor; + BGradientLinear fillGradient; + fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); + fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); + + if ((flags & B_DISABLED) != 0) { + edgeLightColor = base; + edgeShadowColor = base; + frameLightColor = tint_color(base, 1.25); + frameShadowColor = tint_color(base, 1.30); + bevelLightColor = tint_color(base, 0.8); + bevelShadowColor = tint_color(base, 1.07); + fillGradient.AddColor(tint_color(base, 0.85), 0); + fillGradient.AddColor(base, 255); + } else { + edgeLightColor = tint_color(base, 0.80); + edgeShadowColor = tint_color(base, 1.03); + frameLightColor = tint_color(base, 1.30); + frameShadowColor = tint_color(base, 1.30); + bevelLightColor = tint_color(base, 0.6); + bevelShadowColor = tint_color(base, 1.07); + fillGradient.AddColor(tint_color(base, 0.75), 0); + fillGradient.AddColor(tint_color(base, 1.03), 255); + } + + static const float kRoundCornerRadius = 4.0f; + + // left top corner dimensions + BRect leftTopCorner(rect); + leftTopCorner.right = floorf(leftTopCorner.left + kRoundCornerRadius); + leftTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); + + // right top corner dimensions + BRect rightTopCorner(rect); + rightTopCorner.left = floorf(rightTopCorner.right - kRoundCornerRadius); + rightTopCorner.bottom = floorf(rect.top + kRoundCornerRadius); + + // left bottom corner dimensions + BRect leftBottomCorner(rect); + leftBottomCorner.right = floorf(leftBottomCorner.left + kRoundCornerRadius); + leftBottomCorner.top = floorf(rect.bottom - kRoundCornerRadius); + + // right bottom corner dimensions + BRect rightBottomCorner(rect); + rightBottomCorner.left = floorf(rightBottomCorner.right + - kRoundCornerRadius); + rightBottomCorner.top = floorf(rect.bottom - kRoundCornerRadius); + + switch (side) { + case B_TOP_BORDER: + clipping.Exclude(leftTopCorner); + clipping.Exclude(rightTopCorner); + + // draw the left top corner + _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, + edgeShadowColor, frameLightColor, bevelLightColor, + fillGradient); + // draw the right top corner + _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, + edgeShadowColor, edgeLightColor, frameLightColor, + frameShadowColor, bevelLightColor, bevelShadowColor, + fillGradient); + break; + case B_BOTTOM_BORDER: + clipping.Exclude(leftBottomCorner); + clipping.Exclude(rightBottomCorner); + + // draw the left bottom corner + _DrawRoundCornerLeftBottom(view, leftBottomCorner, updateRect, base, + edgeShadowColor, edgeLightColor, frameLightColor, + frameShadowColor, bevelLightColor, bevelShadowColor, + fillGradient); + // draw the right bottom corner + _DrawRoundCornerRightBottom(view, rightBottomCorner, updateRect, + base, edgeLightColor, frameShadowColor, bevelShadowColor, + fillGradient); + break; + case B_LEFT_BORDER: + clipping.Exclude(leftTopCorner); + clipping.Exclude(leftBottomCorner); + + // draw the left top corner + _DrawRoundCornerLeftTop(view, leftTopCorner, updateRect, base, + edgeShadowColor, frameLightColor, bevelLightColor, + fillGradient); + // draw the left bottom corner + _DrawRoundCornerLeftBottom(view, leftBottomCorner, updateRect, base, + edgeShadowColor, edgeLightColor, frameLightColor, + frameShadowColor, bevelLightColor, bevelShadowColor, + fillGradient); + break; + case B_RIGHT_BORDER: + clipping.Exclude(rightTopCorner); + clipping.Exclude(rightBottomCorner); + + // draw the right top corner + _DrawRoundCornerRightTop(view, rightTopCorner, updateRect, base, + edgeShadowColor, edgeLightColor, frameLightColor, + frameShadowColor, bevelLightColor, bevelShadowColor, + fillGradient); + // draw the right bottom corner + _DrawRoundCornerRightBottom(view, rightBottomCorner, updateRect, + base, edgeLightColor, frameShadowColor, bevelShadowColor, + fillGradient); + break; + } + + // clip out the corners + view->ConstrainClippingRegion(&clipping); + + uint32 bordersToDraw = 0; + switch (side) { + case B_TOP_BORDER: + bordersToDraw = (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); + break; + case B_BOTTOM_BORDER: + bordersToDraw = (B_LEFT_BORDER | B_BOTTOM_BORDER | B_RIGHT_BORDER); + break; + case B_LEFT_BORDER: + bordersToDraw = (B_LEFT_BORDER | B_BOTTOM_BORDER | B_TOP_BORDER); + break; + case B_RIGHT_BORDER: + bordersToDraw = (B_RIGHT_BORDER | B_BOTTOM_BORDER | B_TOP_BORDER); + break; + } + + // draw the rest of frame and fill + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, + edgeLightColor, borders); + if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { + if ((borders & B_LEFT_BORDER) == 0) + rect.left++; + if ((borders & B_RIGHT_BORDER) == 0) + rect.right--; + } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { + if ((borders & B_TOP_BORDER) == 0) + rect.top++; + if ((borders & B_BOTTOM_BORDER) == 0) + rect.bottom--; + } + + _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, + frameShadowColor, bordersToDraw); + + _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, + bevelShadowColor); + + view->FillRect(rect, fillGradient); + + // restore the clipping constraints of the view + view->PopState(); +} + + +void +HaikuControlLook::DrawInactiveTab(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, uint32 borders, uint32 side) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + rgb_color edgeShadowColor; + rgb_color edgeLightColor; + rgb_color frameShadowColor; + rgb_color frameLightColor; + rgb_color bevelShadowColor; + rgb_color bevelLightColor; + BGradientLinear fillGradient; + fillGradient.SetStart(rect.LeftTop() + BPoint(3, 3)); + fillGradient.SetEnd(rect.LeftBottom() + BPoint(3, -3)); + + if ((flags & B_DISABLED) != 0) { + edgeLightColor = base; + edgeShadowColor = base; + frameLightColor = tint_color(base, 1.25); + frameShadowColor = tint_color(base, 1.30); + bevelLightColor = tint_color(base, 0.8); + bevelShadowColor = tint_color(base, 1.07); + fillGradient.AddColor(tint_color(base, 0.85), 0); + fillGradient.AddColor(base, 255); + } else { + edgeLightColor = tint_color(base, 0.80); + edgeShadowColor = tint_color(base, 1.03); + frameLightColor = tint_color(base, 1.30); + frameShadowColor = tint_color(base, 1.30); + bevelLightColor = tint_color(base, 1.10); + bevelShadowColor = tint_color(base, 1.17); + fillGradient.AddColor(tint_color(base, 1.12), 0); + fillGradient.AddColor(tint_color(base, 1.08), 255); + } + + BRect background = rect; + switch (side) { + case B_TOP_BORDER: + rect.top += 4; + background.bottom = rect.top; + break; + case B_BOTTOM_BORDER: + rect.bottom -= 4; + background.top = rect.bottom; + break; + case B_LEFT_BORDER: + rect.left += 4; + background.right = rect.left; + break; + case B_RIGHT_BORDER: + rect.right -= 4; + background.left = rect.right; + break; + } + + // active tabs stand out at the top, but this is an inactive tab + view->SetHighColor(base); + view->FillRect(background); + + // frame and fill + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, + edgeLightColor, borders); + + _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, + frameShadowColor, borders); + + if (rect.IsValid()) { + if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { + _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, + bevelLightColor, bevelLightColor, B_LEFT_BORDER & ~borders); + } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { + _DrawFrame(view, rect, bevelShadowColor, bevelShadowColor, + bevelLightColor, bevelLightColor, B_TOP_BORDER & ~borders); + } + } else { + if (side == B_TOP_BORDER || side == B_BOTTOM_BORDER) { + if ((B_LEFT_BORDER & ~borders) != 0) + rect.left++; + } else if (side == B_LEFT_BORDER || side == B_RIGHT_BORDER) { + if ((B_TOP_BORDER & ~borders) != 0) + rect.top++; + } + } + + view->FillRect(rect, fillGradient); +} + + +void +HaikuControlLook::DrawSplitter(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, orientation orientation, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + rgb_color background; + if ((flags & (B_CLICKED | B_ACTIVATED)) != 0) + background = tint_color(base, B_DARKEN_1_TINT); + else + background = base; + + rgb_color light = tint_color(background, 0.6); + rgb_color shadow = tint_color(background, 1.21); + + // frame + if (borders != 0 && rect.Width() > 3 && rect.Height() > 3) + DrawRaisedBorder(view, rect, updateRect, background, flags, borders); + + // dots and rest of background + if (orientation == B_HORIZONTAL) { + if (rect.Width() > 2) { + // background on left/right + BRegion region(rect); + rect.left = floorf((rect.left + rect.right) / 2.0 - 0.5); + rect.right = rect.left + 1; + region.Exclude(rect); + view->SetHighColor(background); + view->FillRegion(®ion); + } + + BPoint dot = rect.LeftTop(); + BPoint stop = rect.LeftBottom(); + int32 num = 1; + while (dot.y <= stop.y) { + rgb_color col1; + rgb_color col2; + switch (num) { + case 1: + col1 = background; + col2 = background; + break; + case 2: + col1 = shadow; + col2 = background; + break; + case 3: + default: + col1 = background; + col2 = light; + num = 0; + break; + } + view->SetHighColor(col1); + view->StrokeLine(dot, dot, B_SOLID_HIGH); + view->SetHighColor(col2); + dot.x++; + view->StrokeLine(dot, dot, B_SOLID_HIGH); + dot.x -= 1.0; + // next pixel + num++; + dot.y++; + } + } else { + if (rect.Height() > 2) { + // background on left/right + BRegion region(rect); + rect.top = floorf((rect.top + rect.bottom) / 2.0 - 0.5); + rect.bottom = rect.top + 1; + region.Exclude(rect); + view->SetHighColor(background); + view->FillRegion(®ion); + } + + BPoint dot = rect.LeftTop(); + BPoint stop = rect.RightTop(); + int32 num = 1; + while (dot.x <= stop.x) { + rgb_color col1; + rgb_color col2; + switch (num) { + case 1: + col1 = background; + col2 = background; + break; + case 2: + col1 = shadow; + col2 = background; + break; + case 3: + default: + col1 = background; + col2 = light; + num = 0; + break; + } + view->SetHighColor(col1); + view->StrokeLine(dot, dot, B_SOLID_HIGH); + view->SetHighColor(col2); + dot.y++; + view->StrokeLine(dot, dot, B_SOLID_HIGH); + dot.y -= 1.0; + // next pixel + num++; + dot.x++; + } + } +} + + +// #pragma mark - + + +void +HaikuControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, border_style borderStyle, uint32 flags, + uint32 borders) +{ + if (borderStyle == B_NO_BORDER) + return; + + rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); + if ((flags & B_FOCUSED) != 0) + scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if (borderStyle == B_FANCY_BORDER) + _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, flags, borders); + + _DrawFrame(view, rect, scrollbarFrameColor, scrollbarFrameColor, + scrollbarFrameColor, scrollbarFrameColor, borders); +} + + +void +HaikuControlLook::DrawRaisedBorder(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + rgb_color lightColor; + rgb_color shadowColor; + + if ((flags & B_DISABLED) != 0) { + lightColor = base; + shadowColor = base; + } else { + lightColor = tint_color(base, 0.85); + shadowColor = tint_color(base, 1.07); + } + + _DrawFrame(view, rect, lightColor, lightColor, shadowColor, shadowColor, + borders); +} + + +void +HaikuControlLook::DrawTextControlBorder(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.Intersects(updateRect)) + return; + + rgb_color dark1BorderColor; + rgb_color dark2BorderColor; + rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + rgb_color invalidColor = ui_color(B_FAILURE_COLOR); + + if ((flags & B_DISABLED) != 0) { + _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, flags, borders); + + if ((flags & B_BLEND_FRAME) != 0) + dark1BorderColor = (rgb_color){ 0, 0, 0, 40 }; + else + dark1BorderColor = tint_color(base, 1.15); + dark2BorderColor = dark1BorderColor; + } else if ((flags & B_CLICKED) != 0) { + dark1BorderColor = tint_color(base, 1.50); + dark2BorderColor = tint_color(base, 1.49); + + // BCheckBox uses this to indicate the clicked state... + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor); + + dark2BorderColor = dark1BorderColor; + } else { + _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, flags, borders); + + if ((flags & B_BLEND_FRAME) != 0) { + dark1BorderColor = (rgb_color){ 0, 0, 0, 102 }; + dark2BorderColor = (rgb_color){ 0, 0, 0, 97 }; + } else { + dark1BorderColor = tint_color(base, 1.40); + dark2BorderColor = tint_color(base, 1.38); + } + } + + if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED) != 0) { + dark1BorderColor = navigationColor; + dark2BorderColor = navigationColor; + } + + if ((flags & B_DISABLED) == 0 && (flags & B_INVALID) != 0) { + dark1BorderColor = invalidColor; + dark2BorderColor = invalidColor; + } + + if ((flags & B_BLEND_FRAME) != 0) { + drawing_mode oldMode = view->DrawingMode(); + view->SetDrawingMode(B_OP_ALPHA); + + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor, borders); + + view->SetDrawingMode(oldMode); + } else { + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor, borders); + } +} + + +void +HaikuControlLook::DrawGroupFrame(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 borders) +{ + rgb_color frameColor = tint_color(base, 1.30); + rgb_color bevelLight = tint_color(base, 0.8); + rgb_color bevelShadow = tint_color(base, 1.03); + + _DrawFrame(view, rect, bevelShadow, bevelShadow, bevelLight, bevelLight, + borders); + + _DrawFrame(view, rect, frameColor, frameColor, frameColor, frameColor, + borders); + + _DrawFrame(view, rect, bevelLight, bevelLight, bevelShadow, bevelShadow, + borders); +} + + +void +HaikuControlLook::DrawLabel(BView* view, const char* label, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + const rgb_color* textColor) +{ + DrawLabel(view, label, NULL, rect, updateRect, base, flags, + DefaultLabelAlignment(), textColor); +} + + +void +HaikuControlLook::DrawLabel(BView* view, const char* label, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + const BAlignment& alignment, const rgb_color* textColor) +{ + DrawLabel(view, label, NULL, rect, updateRect, base, flags, alignment, + textColor); +} + + +void +HaikuControlLook::DrawLabel(BView* view, const char* label, const rgb_color& base, + uint32 flags, const BPoint& where, const rgb_color* textColor) +{ + // setup the text color + + BWindow* window = view->Window(); + bool isDesktop = window + && window->Feel() == kDesktopWindowFeel + && window->Look() == kDesktopWindowLook + && view->Parent() + && view->Parent()->Parent() == NULL + && (flags & B_IGNORE_OUTLINE) == 0; + + rgb_color low; + rgb_color color; + rgb_color glowColor; + + if (textColor != NULL) + glowColor = *textColor; + else if ((flags & B_IS_CONTROL) != 0) + glowColor = ui_color(B_CONTROL_TEXT_COLOR); + else + glowColor = ui_color(B_PANEL_TEXT_COLOR); + + color = glowColor; + + if (isDesktop) + low = view->Parent()->ViewColor(); + else + low = base; + + if ((flags & B_DISABLED) != 0) { + color.red = (uint8)(((int32)low.red + color.red + 1) / 2); + color.green = (uint8)(((int32)low.green + color.green + 1) / 2); + color.blue = (uint8)(((int32)low.blue + color.blue + 1) / 2); + } + + drawing_mode oldMode = view->DrawingMode(); + + if (isDesktop) { + // enforce proper use of desktop label colors + if (low.Brightness() < 100) { + if (textColor == NULL) + color = make_color(255, 255, 255); + + glowColor = make_color(0, 0, 0); + } else { + if (textColor == NULL) + color = make_color(0, 0, 0); + + glowColor = make_color(255, 255, 255); + } + + // drawing occurs on the desktop + if (fCachedWorkspace != current_workspace()) { + int8 indice = 0; + int32 mask; + bool tmpOutline; + while (fBackgroundInfo.FindInt32("be:bgndimginfoworkspaces", + indice, &mask) == B_OK + && fBackgroundInfo.FindBool("be:bgndimginfoerasetext", + indice, &tmpOutline) == B_OK) { + + if (((1 << current_workspace()) & mask) != 0) { + fCachedOutline = tmpOutline; + fCachedWorkspace = current_workspace(); + break; + } + indice++; + } + } + + if (fCachedOutline) { + BFont font; + view->GetFont(&font); + + view->SetDrawingMode(B_OP_ALPHA); + view->SetBlendingMode(B_CONSTANT_ALPHA, B_ALPHA_OVERLAY); + // Draw glow or outline + if (glowColor.Brightness() > 128) { + font.SetFalseBoldWidth(2.0); + view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); + + glowColor.alpha = 30; + view->SetHighColor(glowColor); + view->DrawString(label, where); + + font.SetFalseBoldWidth(1.0); + view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); + + glowColor.alpha = 65; + view->SetHighColor(glowColor); + view->DrawString(label, where); + + font.SetFalseBoldWidth(0.0); + view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); + } else { + font.SetFalseBoldWidth(1.0); + view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); + + glowColor.alpha = 30; + view->SetHighColor(glowColor); + view->DrawString(label, where); + + font.SetFalseBoldWidth(0.0); + view->SetFont(&font, B_FONT_FALSE_BOLD_WIDTH); + + glowColor.alpha = 200; + view->SetHighColor(glowColor); + view->DrawString(label, BPoint(where.x + 1, where.y + 1)); + } + } + } + + view->SetHighColor(color); + view->SetDrawingMode(B_OP_OVER); + view->DrawString(label, where); + view->SetDrawingMode(oldMode); +} + + +void +HaikuControlLook::DrawLabel(BView* view, const char* label, const BBitmap* icon, + BRect rect, const BRect& updateRect, const rgb_color& base, uint32 flags, + const BAlignment& alignment, const rgb_color* textColor) +{ + if (!rect.Intersects(updateRect)) + return; + + if (label == NULL && icon == NULL) + return; + + if (label == NULL) { + // icon only + BRect alignedRect = BLayoutUtils::AlignInFrame(rect, + icon->Bounds().Size(), alignment); + drawing_mode oldMode = view->DrawingMode(); + view->SetDrawingMode(B_OP_OVER); + view->DrawBitmap(icon, alignedRect.LeftTop()); + view->SetDrawingMode(oldMode); + return; + } + + // label, possibly with icon + float availableWidth = rect.Width() + 1; + float width = 0; + float textOffset = 0; + float height = 0; + + if (icon != NULL) { + width = icon->Bounds().Width() + DefaultLabelSpacing() + 1; + height = icon->Bounds().Height() + 1; + textOffset = width; + availableWidth -= textOffset; + } + + // truncate the label if necessary and get the width and height + BString truncatedLabel(label); + + BFont font; + view->GetFont(&font); + + font.TruncateString(&truncatedLabel, B_TRUNCATE_END, availableWidth); + width += ceilf(font.StringWidth(truncatedLabel.String())); + + font_height fontHeight; + font.GetHeight(&fontHeight); + float textHeight = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); + height = std::max(height, textHeight); + + // handle alignment + BRect alignedRect(BLayoutUtils::AlignOnRect(rect, + BSize(width - 1, height - 1), alignment)); + + if (icon != NULL) { + BPoint location(alignedRect.LeftTop()); + if (icon->Bounds().Height() + 1 < height) + location.y += ceilf((height - icon->Bounds().Height() - 1) / 2); + + drawing_mode oldMode = view->DrawingMode(); + view->SetDrawingMode(B_OP_OVER); + view->DrawBitmap(icon, location); + view->SetDrawingMode(oldMode); + } + + BPoint location(alignedRect.left + textOffset, + alignedRect.top + ceilf(fontHeight.ascent)); + if (textHeight < height) + location.y += ceilf((height - textHeight) / 2); + + DrawLabel(view, truncatedLabel.String(), base, flags, location, textColor); +} + + +void +HaikuControlLook::GetFrameInsets(frame_type frameType, uint32 flags, float& _left, + float& _top, float& _right, float& _bottom) +{ + // All frames have the same inset on each side. + float inset = 0; + + switch (frameType) { + case B_BUTTON_FRAME: + inset = (flags & B_DEFAULT_BUTTON) != 0 ? 5 : 2; + break; + case B_GROUP_FRAME: + case B_MENU_FIELD_FRAME: + inset = 3; + break; + case B_SCROLL_VIEW_FRAME: + case B_TEXT_CONTROL_FRAME: + inset = 2; + break; + } + + _left = inset; + _top = inset; + _right = inset; + _bottom = inset; +} + + +void +HaikuControlLook::GetBackgroundInsets(background_type backgroundType, + uint32 flags, float& _left, float& _top, float& _right, float& _bottom) +{ + // Most backgrounds have the same inset on each side. + float inset = 0; + + switch (backgroundType) { + case B_BUTTON_BACKGROUND: + case B_MENU_BACKGROUND: + case B_MENU_BAR_BACKGROUND: + case B_MENU_FIELD_BACKGROUND: + case B_MENU_ITEM_BACKGROUND: + inset = 1; + break; + case B_BUTTON_WITH_POP_UP_BACKGROUND: + _left = 1; + _top = 1; + _right = 1 + kButtonPopUpIndicatorWidth; + _bottom = 1; + return; + case B_HORIZONTAL_SCROLL_BAR_BACKGROUND: + _left = 2; + _top = 0; + _right = 1; + _bottom = 0; + return; + case B_VERTICAL_SCROLL_BAR_BACKGROUND: + _left = 0; + _top = 2; + _right = 0; + _bottom = 1; + return; + } + + _left = inset; + _top = inset; + _right = inset; + _bottom = inset; +} + + +void +HaikuControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, 0.0f, 0.0f, 0.0f, 0.0f, + base, true, flags, borders, orientation); +} + + +void +HaikuControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, + const BRect& updateRect, float radius, const rgb_color& base, uint32 flags, + uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, radius, radius, radius, + radius, base, true, flags, borders, orientation); +} + + +void +HaikuControlLook::DrawButtonWithPopUpBackground(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + uint32 flags, uint32 borders, orientation orientation) +{ + _DrawButtonBackground(view, rect, updateRect, leftTopRadius, + rightTopRadius, leftBottomRadius, rightBottomRadius, base, true, flags, + borders, orientation); +} + + +// #pragma mark - + + +void +HaikuControlLook::_DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + const rgb_color& background, float contrast, float brightness, + uint32 flags, uint32 borders) +{ + if (!rect.IsValid()) + return; + + // save the clipping constraints of the view + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + // If the button is flat and neither activated nor otherwise highlighted + // (mouse hovering or focussed), draw it flat. + if ((flags & B_FLAT) != 0 + && (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0 + && ((flags & (B_HOVER | B_FOCUSED)) == 0 + || (flags & B_DISABLED) != 0)) { + _DrawFrame(view, rect, background, background, background, + background, borders); + _DrawFrame(view, rect, background, background, background, + background, borders); + view->PopState(); + return; + } + + // outer edge colors + rgb_color edgeLightColor; + rgb_color edgeShadowColor; + + // default button frame color + rgb_color defaultIndicatorColor = ui_color(B_CONTROL_BORDER_COLOR); + rgb_color cornerBgColor; + + if ((flags & B_DISABLED) != 0) { + defaultIndicatorColor = disable_color(defaultIndicatorColor, + background); + } + + drawing_mode oldMode = view->DrawingMode(); + + if ((flags & B_DEFAULT_BUTTON) != 0) { + cornerBgColor = defaultIndicatorColor; + edgeLightColor = _EdgeLightColor(defaultIndicatorColor, + contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), + brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); + edgeShadowColor = _EdgeShadowColor(defaultIndicatorColor, + contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), + brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), flags); + + // draw default button indicator + // Allow a 1-pixel border of the background to come through. + rect.InsetBy(1, 1); + + view->SetHighColor(defaultIndicatorColor); + view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); + rect.InsetBy(1, 1); + + view->StrokeRoundRect(rect, leftTopRadius, leftTopRadius); + rect.InsetBy(1, 1); + } else { + cornerBgColor = background; + if ((flags & B_BLEND_FRAME) != 0) { + // set the background color to transparent for the case + // that we are on the desktop + cornerBgColor.alpha = 0; + view->SetDrawingMode(B_OP_ALPHA); + } + + edgeLightColor = _EdgeLightColor(background, + contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), + brightness * 1.0, flags); + edgeShadowColor = _EdgeShadowColor(background, + contrast * (flags & B_DISABLED) != 0 ? 0.0 : 1.0, + brightness * 1.0, flags); + } + + // frame colors + rgb_color frameLightColor = _FrameLightColor(base, flags); + rgb_color frameShadowColor = _FrameShadowColor(base, flags); + + // rounded corners + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 + && leftTopRadius > 0) { + // draw left top rounded corner + BRect leftTopCorner(floorf(rect.left), floorf(rect.top), + floorf(rect.left + leftTopRadius), + floorf(rect.top + leftTopRadius)); + clipping.Exclude(leftTopCorner); + _DrawRoundCornerFrameLeftTop(view, leftTopCorner, updateRect, + cornerBgColor, edgeShadowColor, frameLightColor); + } + + if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 + && rightTopRadius > 0) { + // draw right top rounded corner + BRect rightTopCorner(floorf(rect.right - rightTopRadius), + floorf(rect.top), floorf(rect.right), + floorf(rect.top + rightTopRadius)); + clipping.Exclude(rightTopCorner); + _DrawRoundCornerFrameRightTop(view, rightTopCorner, updateRect, + cornerBgColor, edgeShadowColor, edgeLightColor, + frameLightColor, frameShadowColor); + } + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && leftBottomRadius > 0) { + // draw left bottom rounded corner + BRect leftBottomCorner(floorf(rect.left), + floorf(rect.bottom - leftBottomRadius), + floorf(rect.left + leftBottomRadius), floorf(rect.bottom)); + clipping.Exclude(leftBottomCorner); + _DrawRoundCornerFrameLeftBottom(view, leftBottomCorner, updateRect, + cornerBgColor, edgeShadowColor, edgeLightColor, + frameLightColor, frameShadowColor); + } + + if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && rightBottomRadius > 0) { + // draw right bottom rounded corner + BRect rightBottomCorner(floorf(rect.right - rightBottomRadius), + floorf(rect.bottom - rightBottomRadius), floorf(rect.right), + floorf(rect.bottom)); + clipping.Exclude(rightBottomCorner); + _DrawRoundCornerFrameRightBottom(view, rightBottomCorner, + updateRect, cornerBgColor, edgeLightColor, frameShadowColor); + } + + // clip out the corners + view->ConstrainClippingRegion(&clipping); + + // draw outer edge + if ((flags & B_DEFAULT_BUTTON) != 0) { + _DrawOuterResessedFrame(view, rect, defaultIndicatorColor, + contrast * ((flags & B_DISABLED) != 0 ? 0.3 : 0.8), + brightness * ((flags & B_DISABLED) != 0 ? 1.0 : 0.9), + flags, borders); + } else { + _DrawOuterResessedFrame(view, rect, background, + contrast * ((flags & B_DISABLED) != 0 ? 0.0 : 1.0), + brightness * 1.0, flags, borders); + } + + view->SetDrawingMode(oldMode); + + // draw frame + if ((flags & B_BLEND_FRAME) != 0) { + drawing_mode oldDrawingMode = view->DrawingMode(); + view->SetDrawingMode(B_OP_ALPHA); + + _DrawFrame(view, rect, frameLightColor, frameLightColor, + frameShadowColor, frameShadowColor, borders); + + view->SetDrawingMode(oldDrawingMode); + } else { + _DrawFrame(view, rect, frameLightColor, frameLightColor, + frameShadowColor, frameShadowColor, borders); + } + + // restore the clipping constraints of the view + view->PopState(); +} + + +void +HaikuControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, + const rgb_color& base, float contrast, float brightness, uint32 flags, + uint32 borders) +{ + rgb_color edgeLightColor = _EdgeLightColor(base, contrast, + brightness, flags); + rgb_color edgeShadowColor = _EdgeShadowColor(base, contrast, + brightness, flags); + + if ((flags & B_BLEND_FRAME) != 0) { + // assumes the background has already been painted + drawing_mode oldDrawingMode = view->DrawingMode(); + view->SetDrawingMode(B_OP_ALPHA); + + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, + edgeLightColor, edgeLightColor, borders); + + view->SetDrawingMode(oldDrawingMode); + } else { + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, + edgeLightColor, edgeLightColor, borders); + } +} + + +void +HaikuControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, + const rgb_color& top, const rgb_color& right, const rgb_color& bottom, + uint32 borders) +{ + view->BeginLineArray(4); + + if (borders & B_LEFT_BORDER) { + view->AddLine( + BPoint(rect.left, rect.bottom), + BPoint(rect.left, rect.top), left); + rect.left++; + } + if (borders & B_TOP_BORDER) { + view->AddLine( + BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), top); + rect.top++; + } + if (borders & B_RIGHT_BORDER) { + view->AddLine( + BPoint(rect.right, rect.top), + BPoint(rect.right, rect.bottom), right); + rect.right--; + } + if (borders & B_BOTTOM_BORDER) { + view->AddLine( + BPoint(rect.left, rect.bottom), + BPoint(rect.right, rect.bottom), bottom); + rect.bottom--; + } + + view->EndLineArray(); +} + + +void +HaikuControlLook::_DrawFrame(BView* view, BRect& rect, const rgb_color& left, + const rgb_color& top, const rgb_color& right, const rgb_color& bottom, + const rgb_color& rightTop, const rgb_color& leftBottom, uint32 borders) +{ + view->BeginLineArray(6); + + if (borders & B_TOP_BORDER) { + if (borders & B_RIGHT_BORDER) { + view->AddLine( + BPoint(rect.left, rect.top), + BPoint(rect.right - 1, rect.top), top); + view->AddLine( + BPoint(rect.right, rect.top), + BPoint(rect.right, rect.top), rightTop); + } else { + view->AddLine( + BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), top); + } + rect.top++; + } + + if (borders & B_LEFT_BORDER) { + view->AddLine( + BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom - 1), left); + view->AddLine( + BPoint(rect.left, rect.bottom), + BPoint(rect.left, rect.bottom), leftBottom); + rect.left++; + } + + if (borders & B_BOTTOM_BORDER) { + view->AddLine( + BPoint(rect.left, rect.bottom), + BPoint(rect.right, rect.bottom), bottom); + rect.bottom--; + } + + if (borders & B_RIGHT_BORDER) { + view->AddLine( + BPoint(rect.right, rect.bottom), + BPoint(rect.right, rect.top), right); + rect.right--; + } + + view->EndLineArray(); +} + + +void +HaikuControlLook::_DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + bool popupIndicator, uint32 flags, uint32 borders, orientation orientation) +{ + if (!rect.IsValid()) + return; + + // save the clipping constraints of the view + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + // If the button is flat and neither activated nor otherwise highlighted + // (mouse hovering or focussed), draw it flat. + if ((flags & B_FLAT) != 0 + && (flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED)) == 0 + && ((flags & (B_HOVER | B_FOCUSED)) == 0 + || (flags & B_DISABLED) != 0)) { + _DrawFlatButtonBackground(view, rect, updateRect, base, popupIndicator, + flags, borders, orientation); + } else { + _DrawNonFlatButtonBackground(view, rect, updateRect, clipping, + leftTopRadius, rightTopRadius, leftBottomRadius, rightBottomRadius, + base, popupIndicator, flags, borders, orientation); + } + + // restore the clipping constraints of the view + view->PopState(); +} + + +void +HaikuControlLook::_DrawFlatButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, bool popupIndicator, + uint32 flags, uint32 borders, orientation orientation) +{ + _DrawFrame(view, rect, base, base, base, base, borders); + // Not an actual frame, but the method insets our rect as needed. + + view->SetHighColor(base); + view->FillRect(rect); + + if (popupIndicator) { + BRect indicatorRect(rect); + rect.right -= kButtonPopUpIndicatorWidth; + indicatorRect.left = rect.right + 3; + // 2 pixels for the separator + + view->SetHighColor(base); + view->FillRect(indicatorRect); + + _DrawPopUpMarker(view, indicatorRect, base, flags); + } +} + + +void +HaikuControlLook::_DrawNonFlatButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, BRegion& clipping, float leftTopRadius, + float rightTopRadius, float leftBottomRadius, float rightBottomRadius, + const rgb_color& base, bool popupIndicator, uint32 flags, uint32 borders, + orientation orientation) +{ + // inner bevel colors + rgb_color bevelLightColor = _BevelLightColor(base, flags); + rgb_color bevelShadowColor = _BevelShadowColor(base, flags); + + // button background color + rgb_color buttonBgColor; + if ((flags & B_DISABLED) != 0) + buttonBgColor = tint_color(base, 0.7); + else + buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); + + // surface top gradient + BGradientLinear fillGradient; + _MakeButtonGradient(fillGradient, rect, base, flags, orientation); + + // rounded corners + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 + && leftTopRadius > 0) { + // draw left top rounded corner + BRect leftTopCorner(floorf(rect.left), floorf(rect.top), + floorf(rect.left + leftTopRadius - 2.0), + floorf(rect.top + leftTopRadius - 2.0)); + clipping.Exclude(leftTopCorner); + _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, + bevelLightColor, fillGradient); + } + + if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 + && rightTopRadius > 0) { + // draw right top rounded corner + BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), + floorf(rect.top), floorf(rect.right), + floorf(rect.top + rightTopRadius - 2.0)); + clipping.Exclude(rightTopCorner); + _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, + updateRect, bevelLightColor, bevelShadowColor, fillGradient); + } + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && leftBottomRadius > 0) { + // draw left bottom rounded corner + BRect leftBottomCorner(floorf(rect.left), + floorf(rect.bottom - leftBottomRadius + 2.0), + floorf(rect.left + leftBottomRadius - 2.0), + floorf(rect.bottom)); + clipping.Exclude(leftBottomCorner); + _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, + updateRect, bevelLightColor, bevelShadowColor, fillGradient); + } + + if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && rightBottomRadius > 0) { + // draw right bottom rounded corner + BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), + floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), + floorf(rect.bottom)); + clipping.Exclude(rightBottomCorner); + _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, + updateRect, bevelShadowColor, fillGradient); + } + + // clip out the corners + view->ConstrainClippingRegion(&clipping); + + // draw inner bevel + + if ((flags & B_ACTIVATED) != 0) { + view->BeginLineArray(4); + + // shadow along left/top borders + if (borders & B_LEFT_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), bevelLightColor); + rect.left++; + } + if (borders & B_TOP_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), bevelLightColor); + rect.top++; + } + + // softer shadow along left/top borders + if (borders & B_LEFT_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), bevelShadowColor); + rect.left++; + } + if (borders & B_TOP_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), bevelShadowColor); + rect.top++; + } + + view->EndLineArray(); + } else { + _DrawFrame(view, rect, + bevelLightColor, bevelLightColor, + bevelShadowColor, bevelShadowColor, + buttonBgColor, buttonBgColor, borders); + } + + if (popupIndicator) { + BRect indicatorRect(rect); + rect.right -= kButtonPopUpIndicatorWidth; + indicatorRect.left = rect.right + 3; + // 2 pixels for the separator + + // Even when depressed we want the pop-up indicator background and + // separator to cover the area up to the top. + if ((flags & B_ACTIVATED) != 0) + indicatorRect.top--; + + // draw the separator + rgb_color separatorBaseColor = base; + if ((flags & B_ACTIVATED) != 0) + separatorBaseColor = tint_color(base, B_DARKEN_1_TINT); + + rgb_color separatorLightColor = _EdgeLightColor(separatorBaseColor, + (flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags); + rgb_color separatorShadowColor = _EdgeShadowColor(separatorBaseColor, + (flags & B_DISABLED) != 0 ? 0.7 : 1.0, 1.0, flags); + + view->BeginLineArray(2); + + view->AddLine(BPoint(indicatorRect.left - 2, indicatorRect.top), + BPoint(indicatorRect.left - 2, indicatorRect.bottom), + separatorShadowColor); + view->AddLine(BPoint(indicatorRect.left - 1, indicatorRect.top), + BPoint(indicatorRect.left - 1, indicatorRect.bottom), + separatorLightColor); + + view->EndLineArray(); + + // draw background and pop-up marker + _DrawMenuFieldBackgroundInside(view, indicatorRect, updateRect, + 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, 0); + + if ((flags & B_ACTIVATED) != 0) + indicatorRect.top++; + + _DrawPopUpMarker(view, indicatorRect, base, flags); + } + + // fill in the background + view->FillRect(rect, fillGradient); +} + + +void +HaikuControlLook::_DrawPopUpMarker(BView* view, const BRect& rect, + const rgb_color& base, uint32 flags) +{ + BPoint center(roundf((rect.left + rect.right) / 2.0), + roundf((rect.top + rect.bottom) / 2.0)); + BPoint triangle[3]; + triangle[0] = center + BPoint(-2.5, -0.5); + triangle[1] = center + BPoint(2.5, -0.5); + triangle[2] = center + BPoint(0.0, 2.0); + + uint32 viewFlags = view->Flags(); + view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); + + rgb_color markColor; + if ((flags & B_DISABLED) != 0) + markColor = tint_color(base, 1.35); + else + markColor = tint_color(base, 1.65); + + view->SetHighColor(markColor); + view->FillTriangle(triangle[0], triangle[1], triangle[2]); + + view->SetFlags(viewFlags); +} + + +void +HaikuControlLook::_DrawMenuFieldBackgroundOutside(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + bool popupIndicator, uint32 flags) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + if (popupIndicator) { + BRect leftRect(rect); + leftRect.right -= 10; + + BRect rightRect(rect); + rightRect.left = rightRect.right - 9; + + _DrawMenuFieldBackgroundInside(view, leftRect, updateRect, + leftTopRadius, 0.0f, leftBottomRadius, 0.0f, base, flags, + B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); + + _DrawMenuFieldBackgroundInside(view, rightRect, updateRect, + 0.0f, rightTopRadius, 0.0f, rightBottomRadius, base, flags, + B_TOP_BORDER | B_RIGHT_BORDER | B_BOTTOM_BORDER); + + _DrawPopUpMarker(view, rightRect, base, flags); + + // draw a line on the left of the popup frame + rgb_color bevelShadowColor = _BevelShadowColor(base, flags); + view->SetHighColor(bevelShadowColor); + BPoint leftTopCorner(floorf(rightRect.left - 1.0), + floorf(rightRect.top - 1.0)); + BPoint leftBottomCorner(floorf(rightRect.left - 1.0), + floorf(rightRect.bottom + 1.0)); + view->StrokeLine(leftTopCorner, leftBottomCorner); + + rect = leftRect; + } else { + _DrawMenuFieldBackgroundInside(view, rect, updateRect, leftTopRadius, + rightTopRadius, leftBottomRadius, rightBottomRadius, base, flags); + } +} + + +void +HaikuControlLook::_DrawMenuFieldBackgroundInside(BView* view, BRect& rect, + const BRect& updateRect, float leftTopRadius, float rightTopRadius, + float leftBottomRadius, float rightBottomRadius, const rgb_color& base, + uint32 flags, uint32 borders) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // save the clipping constraints of the view + view->PushState(); + + // set clipping constraints to updateRect + BRegion clipping(updateRect); + view->ConstrainClippingRegion(&clipping); + + // frame colors + rgb_color frameLightColor = _FrameLightColor(base, flags); + rgb_color frameShadowColor = _FrameShadowColor(base, flags); + + // indicator background color + rgb_color indicatorBase; + if ((borders & B_LEFT_BORDER) != 0) + indicatorBase = base; + else { + if ((flags & B_DISABLED) != 0) + indicatorBase = tint_color(base, 1.05); + else + indicatorBase = tint_color(base, 1.12); + } + + // bevel colors + rgb_color cornerColor = tint_color(indicatorBase, 0.85); + rgb_color bevelColor1 = tint_color(indicatorBase, 0.3); + rgb_color bevelColor2 = tint_color(indicatorBase, 0.5); + rgb_color bevelColor3 = tint_color(indicatorBase, 1.03); + + if ((flags & B_DISABLED) != 0) { + cornerColor = tint_color(indicatorBase, 0.8); + bevelColor1 = tint_color(indicatorBase, 0.7); + bevelColor2 = tint_color(indicatorBase, 0.8); + bevelColor3 = tint_color(indicatorBase, 1.01); + } else { + cornerColor = tint_color(indicatorBase, 0.85); + bevelColor1 = tint_color(indicatorBase, 0.3); + bevelColor2 = tint_color(indicatorBase, 0.5); + bevelColor3 = tint_color(indicatorBase, 1.03); + } + + // surface top gradient + BGradientLinear fillGradient; + _MakeButtonGradient(fillGradient, rect, indicatorBase, flags); + + // rounded corners + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_TOP_BORDER) != 0 + && leftTopRadius > 0) { + // draw left top rounded corner + BRect leftTopCorner(floorf(rect.left), floorf(rect.top), + floorf(rect.left + leftTopRadius - 2.0), + floorf(rect.top + leftTopRadius - 2.0)); + clipping.Exclude(leftTopCorner); + + BRegion cornerClipping(leftTopCorner); + view->ConstrainClippingRegion(&cornerClipping); + + BRect ellipseRect(leftTopCorner); + ellipseRect.InsetBy(-1.0, -1.0); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + // draw the frame (again) + view->SetHighColor(frameLightColor); + view->FillEllipse(ellipseRect); + + // draw the bevel and background + _DrawRoundCornerBackgroundLeftTop(view, leftTopCorner, updateRect, + bevelColor1, fillGradient); + } + + if ((borders & B_TOP_BORDER) != 0 && (borders & B_RIGHT_BORDER) != 0 + && rightTopRadius > 0) { + // draw right top rounded corner + BRect rightTopCorner(floorf(rect.right - rightTopRadius + 2.0), + floorf(rect.top), floorf(rect.right), + floorf(rect.top + rightTopRadius - 2.0)); + clipping.Exclude(rightTopCorner); + + BRegion cornerClipping(rightTopCorner); + view->ConstrainClippingRegion(&cornerClipping); + + BRect ellipseRect(rightTopCorner); + ellipseRect.InsetBy(-1.0, -1.0); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + // draw the frame (again) + if (frameLightColor == frameShadowColor) { + view->SetHighColor(frameLightColor); + view->FillEllipse(ellipseRect); + } else { + BGradientLinear gradient; + gradient.AddColor(frameLightColor, 0); + gradient.AddColor(frameShadowColor, 255); + gradient.SetStart(rightTopCorner.LeftTop()); + gradient.SetEnd(rightTopCorner.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + } + + // draw the bevel and background + _DrawRoundCornerBackgroundRightTop(view, rightTopCorner, updateRect, + bevelColor1, bevelColor3, fillGradient); + } + + if ((borders & B_LEFT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && leftBottomRadius > 0) { + // draw left bottom rounded corner + BRect leftBottomCorner(floorf(rect.left), + floorf(rect.bottom - leftBottomRadius + 2.0), + floorf(rect.left + leftBottomRadius - 2.0), + floorf(rect.bottom)); + clipping.Exclude(leftBottomCorner); + + BRegion cornerClipping(leftBottomCorner); + view->ConstrainClippingRegion(&cornerClipping); + + BRect ellipseRect(leftBottomCorner); + ellipseRect.InsetBy(-1.0, -1.0); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + // draw the frame (again) + if (frameLightColor == frameShadowColor) { + view->SetHighColor(frameLightColor); + view->FillEllipse(ellipseRect); + } else { + BGradientLinear gradient; + gradient.AddColor(frameLightColor, 0); + gradient.AddColor(frameShadowColor, 255); + gradient.SetStart(leftBottomCorner.LeftTop()); + gradient.SetEnd(leftBottomCorner.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + } + + // draw the bevel and background + _DrawRoundCornerBackgroundLeftBottom(view, leftBottomCorner, + updateRect, bevelColor2, bevelColor3, fillGradient); + } + + if ((borders & B_RIGHT_BORDER) != 0 && (borders & B_BOTTOM_BORDER) != 0 + && rightBottomRadius > 0) { + // draw right bottom rounded corner + BRect rightBottomCorner(floorf(rect.right - rightBottomRadius + 2.0), + floorf(rect.bottom - rightBottomRadius + 2.0), floorf(rect.right), + floorf(rect.bottom)); + clipping.Exclude(rightBottomCorner); + + BRegion cornerClipping(rightBottomCorner); + view->ConstrainClippingRegion(&cornerClipping); + + BRect ellipseRect(rightBottomCorner); + ellipseRect.InsetBy(-1.0, -1.0); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + // draw the frame (again) + view->SetHighColor(frameShadowColor); + view->FillEllipse(ellipseRect); + + // draw the bevel and background + _DrawRoundCornerBackgroundRightBottom(view, rightBottomCorner, + updateRect, bevelColor3, fillGradient); + } + + // clip out the corners + view->ConstrainClippingRegion(&clipping); + + // draw the bevel + _DrawFrame(view, rect, + bevelColor2, bevelColor1, + bevelColor3, bevelColor3, + cornerColor, cornerColor, + borders); + + // fill in the background + view->FillRect(rect, fillGradient); + + // restore the clipping constraints of the view + view->PopState(); +} + + +void +HaikuControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeColor, const rgb_color& frameColor, + const rgb_color& bevelColor, const BGradientLinear& fillGradient) +{ + _DrawRoundCornerFrameLeftTop(view, cornerRect, updateRect, + background, edgeColor, frameColor); + _DrawRoundCornerBackgroundLeftTop(view, cornerRect, updateRect, + bevelColor, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerFrameLeftTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeColor, const rgb_color& frameColor) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(background); + view->FillRect(cornerRect); + + // outer edge + BRect ellipseRect(cornerRect); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + view->SetHighColor(edgeColor); + view->FillEllipse(ellipseRect); + + // frame + ellipseRect.InsetBy(1, 1); + cornerRect.left++; + cornerRect.top++; + view->SetHighColor(frameColor); + view->FillEllipse(ellipseRect); + + // prepare for bevel + cornerRect.left++; + cornerRect.top++; +} + + +void +HaikuControlLook::_DrawRoundCornerBackgroundLeftTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& bevelColor, + const BGradientLinear& fillGradient) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + BRect ellipseRect(cornerRect); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + // bevel + view->SetHighColor(bevelColor); + view->FillEllipse(ellipseRect); + + // gradient + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerRightTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, + const rgb_color& frameTopColor, const rgb_color& frameRightColor, + const rgb_color& bevelTopColor, const rgb_color& bevelRightColor, + const BGradientLinear& fillGradient) +{ + _DrawRoundCornerFrameRightTop(view, cornerRect, updateRect, + background, edgeTopColor, edgeRightColor, frameTopColor, + frameRightColor); + _DrawRoundCornerBackgroundRightTop(view, cornerRect, updateRect, + bevelTopColor, bevelRightColor, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerFrameRightTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeTopColor, const rgb_color& edgeRightColor, + const rgb_color& frameTopColor, const rgb_color& frameRightColor) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(background); + view->FillRect(cornerRect); + + // outer edge + BRect ellipseRect(cornerRect); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + BGradientLinear gradient; + gradient.AddColor(edgeTopColor, 0); + gradient.AddColor(edgeRightColor, 255); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // frame + ellipseRect.InsetBy(1, 1); + cornerRect.right--; + cornerRect.top++; + if (frameTopColor == frameRightColor) { + view->SetHighColor(frameTopColor); + view->FillEllipse(ellipseRect); + } else { + gradient.SetColor(0, frameTopColor); + gradient.SetColor(1, frameRightColor); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + } + + // prepare for bevel + cornerRect.right--; + cornerRect.top++; +} + + +void +HaikuControlLook::_DrawRoundCornerBackgroundRightTop(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& bevelTopColor, + const rgb_color& bevelRightColor, const BGradientLinear& fillGradient) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + BRect ellipseRect(cornerRect); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.bottom = ellipseRect.top + ellipseRect.Height() * 2; + + // bevel + BGradientLinear gradient; + gradient.AddColor(bevelTopColor, 0); + gradient.AddColor(bevelRightColor, 255); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // gradient + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerLeftBottom(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, + const rgb_color& frameLeftColor, const rgb_color& frameBottomColor, + const rgb_color& bevelLeftColor, const rgb_color& bevelBottomColor, + const BGradientLinear& fillGradient) +{ + _DrawRoundCornerFrameLeftBottom(view, cornerRect, updateRect, + background, edgeLeftColor, edgeBottomColor, frameLeftColor, + frameBottomColor); + _DrawRoundCornerBackgroundLeftBottom(view, cornerRect, updateRect, + bevelLeftColor, bevelBottomColor, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerFrameLeftBottom(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeLeftColor, const rgb_color& edgeBottomColor, + const rgb_color& frameLeftColor, const rgb_color& frameBottomColor) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(background); + view->FillRect(cornerRect); + + // outer edge + BRect ellipseRect(cornerRect); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + BGradientLinear gradient; + gradient.AddColor(edgeLeftColor, 0); + gradient.AddColor(edgeBottomColor, 255); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // frame + ellipseRect.InsetBy(1, 1); + cornerRect.left++; + cornerRect.bottom--; + if (frameLeftColor == frameBottomColor) { + view->SetHighColor(frameLeftColor); + view->FillEllipse(ellipseRect); + } else { + gradient.SetColor(0, frameLeftColor); + gradient.SetColor(1, frameBottomColor); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + } + + // prepare for bevel + cornerRect.left++; + cornerRect.bottom--; +} + + +void +HaikuControlLook::_DrawRoundCornerBackgroundLeftBottom(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& bevelLeftColor, + const rgb_color& bevelBottomColor, const BGradientLinear& fillGradient) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + BRect ellipseRect(cornerRect); + ellipseRect.right = ellipseRect.left + ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + // bevel + BGradientLinear gradient; + gradient.AddColor(bevelLeftColor, 0); + gradient.AddColor(bevelBottomColor, 255); + gradient.SetStart(cornerRect.LeftTop()); + gradient.SetEnd(cornerRect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // gradient + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerRightBottom(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeColor, const rgb_color& frameColor, + const rgb_color& bevelColor, const BGradientLinear& fillGradient) +{ + _DrawRoundCornerFrameRightBottom(view, cornerRect, updateRect, + background, edgeColor, frameColor); + _DrawRoundCornerBackgroundRightBottom(view, cornerRect, updateRect, + bevelColor, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundCornerFrameRightBottom(BView* view, BRect& cornerRect, + const BRect& updateRect, const rgb_color& background, + const rgb_color& edgeColor, const rgb_color& frameColor) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(background); + view->FillRect(cornerRect); + + // outer edge + BRect ellipseRect(cornerRect); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + view->SetHighColor(edgeColor); + view->FillEllipse(ellipseRect); + + // frame + ellipseRect.InsetBy(1, 1); + cornerRect.right--; + cornerRect.bottom--; + view->SetHighColor(frameColor); + view->FillEllipse(ellipseRect); + + // prepare for bevel + cornerRect.right--; + cornerRect.bottom--; +} + + +void +HaikuControlLook::_DrawRoundCornerBackgroundRightBottom(BView* view, + BRect& cornerRect, const BRect& updateRect, const rgb_color& bevelColor, + const BGradientLinear& fillGradient) +{ + // constrain clipping region to corner + BRegion clipping(cornerRect); + view->ConstrainClippingRegion(&clipping); + + BRect ellipseRect(cornerRect); + ellipseRect.left = ellipseRect.right - ellipseRect.Width() * 2; + ellipseRect.top = ellipseRect.bottom - ellipseRect.Height() * 2; + + // bevel + view->SetHighColor(bevelColor); + view->FillEllipse(ellipseRect); + + // gradient + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); +} + + +void +HaikuControlLook::_DrawRoundBarCorner(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& edgeLightColor, const rgb_color& edgeShadowColor, + const rgb_color& frameLightColor, const rgb_color& frameShadowColor, + const rgb_color& fillLightColor, const rgb_color& fillShadowColor, + float leftInset, float topInset, float rightInset, float bottomInset, + orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + BGradientLinear gradient; + gradient.AddColor(edgeShadowColor, 0); + gradient.AddColor(edgeLightColor, 255); + gradient.SetStart(rect.LeftTop()); + if (orientation == B_HORIZONTAL) + gradient.SetEnd(rect.LeftBottom()); + else + gradient.SetEnd(rect.RightTop()); + + view->FillEllipse(rect, gradient); + + rect.left += leftInset; + rect.top += topInset; + rect.right += rightInset; + rect.bottom += bottomInset; + + gradient.MakeEmpty(); + gradient.AddColor(frameShadowColor, 0); + gradient.AddColor(frameLightColor, 255); + gradient.SetStart(rect.LeftTop()); + if (orientation == B_HORIZONTAL) + gradient.SetEnd(rect.LeftBottom()); + else + gradient.SetEnd(rect.RightTop()); + + view->FillEllipse(rect, gradient); + + rect.left += leftInset; + rect.top += topInset; + rect.right += rightInset; + rect.bottom += bottomInset; + + gradient.MakeEmpty(); + gradient.AddColor(fillShadowColor, 0); + gradient.AddColor(fillLightColor, 255); + gradient.SetStart(rect.LeftTop()); + if (orientation == B_HORIZONTAL) + gradient.SetEnd(rect.LeftBottom()); + else + gradient.SetEnd(rect.RightTop()); + + view->FillEllipse(rect, gradient); +} + + +rgb_color +HaikuControlLook::_EdgeLightColor(const rgb_color& base, float contrast, + float brightness, uint32 flags) +{ + rgb_color edgeLightColor; + + if ((flags & B_BLEND_FRAME) != 0) { + uint8 alpha = uint8(20 * contrast); + uint8 white = uint8(255 * brightness); + + edgeLightColor = (rgb_color){ white, white, white, alpha }; + } else { + // colors + float tintLight = kEdgeBevelLightTint; + + if (contrast == 0.0) + tintLight = B_NO_TINT; + else if (contrast != 1.0) + tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; + + edgeLightColor = tint_color(base, tintLight); + + if (brightness < 1.0) { + edgeLightColor.red = uint8(edgeLightColor.red * brightness); + edgeLightColor.green = uint8(edgeLightColor.green * brightness); + edgeLightColor.blue = uint8(edgeLightColor.blue * brightness); + } + } + + return edgeLightColor; +} + + +rgb_color +HaikuControlLook::_EdgeShadowColor(const rgb_color& base, float contrast, + float brightness, uint32 flags) +{ + rgb_color edgeShadowColor; + + if ((flags & B_BLEND_FRAME) != 0) { + uint8 alpha = uint8(20 * contrast); + edgeShadowColor = (rgb_color){ 0, 0, 0, alpha }; + } else { + float tintShadow = kEdgeBevelShadowTint; + + if (contrast == 0.0) + tintShadow = B_NO_TINT; + else if (contrast != 1.0) + tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; + + edgeShadowColor = tint_color(base, tintShadow); + + if (brightness < 1.0) { + edgeShadowColor.red = uint8(edgeShadowColor.red * brightness); + edgeShadowColor.green = uint8(edgeShadowColor.green * brightness); + edgeShadowColor.blue = uint8(edgeShadowColor.blue * brightness); + } + } + + return edgeShadowColor; +} + + +rgb_color +HaikuControlLook::_FrameLightColor(const rgb_color& base, uint32 flags) +{ + if ((flags & B_FOCUSED) != 0) + return ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if ((flags & B_ACTIVATED) != 0) + return _FrameShadowColor(base, flags & ~B_ACTIVATED); + + rgb_color frameLightColor; + + if ((flags & B_DISABLED) != 0) { + // TODO: B_BLEND_FRAME + frameLightColor = tint_color(base, 1.145); + + if ((flags & B_DEFAULT_BUTTON) != 0) + frameLightColor = tint_color(frameLightColor, 1.14); + } else { + if ((flags & B_BLEND_FRAME) != 0) + frameLightColor = (rgb_color){ 0, 0, 0, 75 }; + else + frameLightColor = tint_color(base, 1.33); + + if ((flags & B_DEFAULT_BUTTON) != 0) + frameLightColor = tint_color(frameLightColor, 1.35); + } + + return frameLightColor; +} + + +rgb_color +HaikuControlLook::_FrameShadowColor(const rgb_color& base, uint32 flags) +{ + if ((flags & B_FOCUSED) != 0) + return ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if ((flags & B_ACTIVATED) != 0) + return _FrameLightColor(base, flags & ~B_ACTIVATED); + + rgb_color frameShadowColor; + + if ((flags & B_DISABLED) != 0) { + // TODO: B_BLEND_FRAME + frameShadowColor = tint_color(base, 1.24); + + if ((flags & B_DEFAULT_BUTTON) != 0) { + frameShadowColor = tint_color(base, 1.145); + frameShadowColor = tint_color(frameShadowColor, 1.12); + } + } else { + if ((flags & B_DEFAULT_BUTTON) != 0) { + if ((flags & B_BLEND_FRAME) != 0) + frameShadowColor = (rgb_color){ 0, 0, 0, 75 }; + else + frameShadowColor = tint_color(base, 1.33); + + frameShadowColor = tint_color(frameShadowColor, 1.5); + } else { + if ((flags & B_BLEND_FRAME) != 0) + frameShadowColor = (rgb_color){ 0, 0, 0, 95 }; + else + frameShadowColor = tint_color(base, 1.47); + } + } + + return frameShadowColor; +} + + +rgb_color +HaikuControlLook::_BevelLightColor(const rgb_color& base, uint32 flags) +{ + rgb_color bevelLightColor = tint_color(base, 0.2); + + if ((flags & B_DISABLED) != 0) + bevelLightColor = tint_color(base, B_LIGHTEN_1_TINT); + + if ((flags & B_ACTIVATED) != 0) + bevelLightColor = tint_color(base, B_DARKEN_1_TINT); + + return bevelLightColor; +} + + +rgb_color +HaikuControlLook::_BevelShadowColor(const rgb_color& base, uint32 flags) +{ + rgb_color bevelShadowColor = tint_color(base, 1.08); + + if ((flags & B_DISABLED) != 0) + bevelShadowColor = base; + + if ((flags & B_ACTIVATED) != 0) + bevelShadowColor = tint_color(base, B_DARKEN_1_TINT); + + return bevelShadowColor; +} + + +void +HaikuControlLook::_FillGradient(BView* view, const BRect& rect, + const rgb_color& base, float topTint, float bottomTint, + orientation orientation) +{ + BGradientLinear gradient; + _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); + view->FillRect(rect, gradient); +} + + +void +HaikuControlLook::_FillGlossyGradient(BView* view, const BRect& rect, + const rgb_color& base, float topTint, float middle1Tint, + float middle2Tint, float bottomTint, orientation orientation) +{ + BGradientLinear gradient; + _MakeGlossyGradient(gradient, rect, base, topTint, middle1Tint, + middle2Tint, bottomTint, orientation); + view->FillRect(rect, gradient); +} + + +void +HaikuControlLook::_MakeGradient(BGradientLinear& gradient, const BRect& rect, + const rgb_color& base, float topTint, float bottomTint, + orientation orientation) const +{ + gradient.AddColor(tint_color(base, topTint), 0); + gradient.AddColor(tint_color(base, bottomTint), 255); + gradient.SetStart(rect.LeftTop()); + if (orientation == B_HORIZONTAL) + gradient.SetEnd(rect.LeftBottom()); + else + gradient.SetEnd(rect.RightTop()); +} + + +void +HaikuControlLook::_MakeGlossyGradient(BGradientLinear& gradient, const BRect& rect, + const rgb_color& base, float topTint, float middle1Tint, + float middle2Tint, float bottomTint, + orientation orientation) const +{ + gradient.AddColor(tint_color(base, topTint), 0); + gradient.AddColor(tint_color(base, middle1Tint), 132); + gradient.AddColor(tint_color(base, middle2Tint), 136); + gradient.AddColor(tint_color(base, bottomTint), 255); + gradient.SetStart(rect.LeftTop()); + if (orientation == B_HORIZONTAL) + gradient.SetEnd(rect.LeftBottom()); + else + gradient.SetEnd(rect.RightTop()); +} + + +void +HaikuControlLook::_MakeButtonGradient(BGradientLinear& gradient, BRect& rect, + const rgb_color& base, uint32 flags, orientation orientation) const +{ + float topTint = 0.49; + float middleTint1 = 0.62; + float middleTint2 = 0.76; + float bottomTint = 0.90; + + if ((flags & B_ACTIVATED) != 0) { + topTint = 1.11; + bottomTint = 1.08; + } + + if ((flags & B_DISABLED) != 0) { + topTint = (topTint + B_NO_TINT) / 2; + middleTint1 = (middleTint1 + B_NO_TINT) / 2; + middleTint2 = (middleTint2 + B_NO_TINT) / 2; + bottomTint = (bottomTint + B_NO_TINT) / 2; + } else if ((flags & B_HOVER) != 0) { + topTint *= kHoverTintFactor; + middleTint1 *= kHoverTintFactor; + middleTint2 *= kHoverTintFactor; + bottomTint *= kHoverTintFactor; + } + + if ((flags & B_ACTIVATED) != 0) { + _MakeGradient(gradient, rect, base, topTint, bottomTint, orientation); + } else { + _MakeGlossyGradient(gradient, rect, base, topTint, middleTint1, + middleTint2, bottomTint, orientation); + } +} + + + +bool +HaikuControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, + rgb_color& color, uint32 flags) const +{ + if ((flags & (B_ACTIVATED | B_PARTIALLY_ACTIVATED | B_CLICKED)) == 0) { + // no mark to be drawn at all + return false; + } + + color = ui_color(B_CONTROL_MARK_COLOR); + + float mix = 1.0; + + if ((flags & B_DISABLED) != 0) { + // activated, but disabled + mix = 0.4; + } else if ((flags & B_CLICKED) != 0) { + if ((flags & B_ACTIVATED) != 0) { + // losing activation + mix = 0.7; + } else { + // becoming activated (or losing partial activation) + mix = 0.3; + } + } else if ((flags & B_PARTIALLY_ACTIVATED) != 0) { + // partially activated + mix = 0.5; + } else { + // simply activated + } + + color.red = uint8(color.red * mix + base.red * (1.0 - mix)); + color.green = uint8(color.green * mix + base.green * (1.0 - mix)); + color.blue = uint8(color.blue * mix + base.blue * (1.0 - mix)); + + return true; +} + + +} // namespace BPrivate diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index 0549b0541f..4ad19fa81c 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -1286,7 +1287,7 @@ _init_interface_kit_() be_clipboard = new BClipboard(NULL); // TODO: Could support different themes here in the future. - be_control_look = new BControlLook(); + be_control_look = new HaikuControlLook(); _init_global_fonts_(); diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index e69e4be1ea..bfc5e4a587 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -78,6 +78,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { GroupLayout.cpp GroupLayoutBuilder.cpp GroupView.cpp + HaikuControlLook.cpp Icon.cpp Input.cpp InterfaceDefs.cpp