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