From 2f86ba45579bdc9648b232175f87edc62ab71b54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 15 Feb 2009 18:23:19 +0000 Subject: [PATCH] Implemented a new look for the Haiku interface controls. It was overheard that they looked too ninety-ish. TODO: The code behind this is work in progress. The basic idea is to extract all drawing code into a new class BControlLook, of which there is a global instance be_control_look, instantiated in InterfaceDefs.cpp. At the moment, all the old drawing code is still there, and the usage of be_control_look is inside if-bodies checking the instance against NULL. In another words, by not instanitating be_control_look, you can revert back to the old look. BControlLook's job is to provide reusable methods for drawing certain types of frames, backgrounds and labels, so that application developers can make controls that re-use the same drawing code as built-in controls and adopt to changes made there. I have added the notion of "borders". Each of the frame drawing methods can be made to draw certain borders only, which is supposed to help when controls shall visually attach. This feature is not fully explored at all ATM. TODO: Update BColumnListView header view and BStringItem text spacing. Update other apps where it makes sense to use BControlLook. For the moment, only Tracker and LaunchBox are updated. More... NOTE: The new look is not very radically different, so that existing apps do not immediately look too ugly or out of place. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29221 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/ChannelSlider.h | 91 +- headers/os/interface/ControlLook.h | 297 ++++ headers/os/interface/Menu.h | 2 + headers/os/interface/ScrollBar.h | 7 + headers/os/interface/Slider.h | 1 + src/apps/launchbox/IconButton.cpp | 50 +- src/apps/launchbox/LaunchButton.cpp | 4 +- src/kits/interface/BMCPrivate.cpp | 36 +- src/kits/interface/Box.cpp | 40 +- src/kits/interface/Button.cpp | 19 + src/kits/interface/ChannelSlider.cpp | 58 +- src/kits/interface/CheckBox.cpp | 23 +- src/kits/interface/ColorControl.cpp | 95 +- src/kits/interface/ControlLook.cpp | 2041 ++++++++++++++++++++++++++ src/kits/interface/Dragger.cpp | 16 +- src/kits/interface/InterfaceDefs.cpp | 7 + src/kits/interface/Jamfile | 1 + src/kits/interface/Menu.cpp | 27 +- src/kits/interface/MenuBar.cpp | 22 +- src/kits/interface/MenuField.cpp | 21 +- src/kits/interface/MenuItem.cpp | 50 +- src/kits/interface/MenuWindow.cpp | 38 +- src/kits/interface/RadioButton.cpp | 28 + src/kits/interface/ScrollBar.cpp | 373 +++-- src/kits/interface/ScrollView.cpp | 67 +- src/kits/interface/Slider.cpp | 78 +- src/kits/interface/StatusBar.cpp | 19 +- src/kits/interface/TabView.cpp | 122 +- src/kits/interface/TextControl.cpp | 42 +- src/kits/interface/TextInput.cpp | 8 +- src/kits/interface/TextView.cpp | 2 +- src/kits/tracker/ContainerWindow.cpp | 14 +- src/kits/tracker/CountView.cpp | 28 +- src/kits/tracker/TitleView.cpp | 157 +- src/kits/tracker/TitleView.h | 2 +- 35 files changed, 3478 insertions(+), 408 deletions(-) create mode 100644 headers/os/interface/ControlLook.h create mode 100644 src/kits/interface/ControlLook.cpp diff --git a/headers/os/interface/ChannelSlider.h b/headers/os/interface/ChannelSlider.h index 18b3744fb3..ba7147f8b9 100644 --- a/headers/os/interface/ChannelSlider.h +++ b/headers/os/interface/ChannelSlider.h @@ -17,58 +17,67 @@ #include -class BChannelSlider : public BChannelControl -{ +class BChannelSlider : public BChannelControl { public: - BChannelSlider(BRect area, const char* name, - const char* label, BMessage* message, - int32 channels = 1, - uint32 resize = B_FOLLOW_LEFT | B_FOLLOW_TOP, - uint32 flags = B_WILL_DRAW); - BChannelSlider(BRect area, const char* name, - const char* label, BMessage* message, - orientation o, int32 channels = 1, - uint32 resize = B_FOLLOW_LEFT | B_FOLLOW_TOP, - uint32 flags = B_WILL_DRAW); - BChannelSlider(BMessage* archive); -virtual ~BChannelSlider(); + BChannelSlider(BRect area, const char* name, + const char* label, BMessage* message, + int32 channels = 1, + uint32 resizeMode + = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 flags = B_WILL_DRAW); + BChannelSlider(BRect area, const char* name, + const char* label, BMessage* message, + enum orientation orientation, + int32 channels = 1, + uint32 resizeMode + = B_FOLLOW_LEFT | B_FOLLOW_TOP, + uint32 flags = B_WILL_DRAW); + BChannelSlider(const char* name, + const char* label, BMessage* message, + enum orientation orientation, + int32 channels = 1, + uint32 flags = B_WILL_DRAW); + BChannelSlider(BMessage* archive); + virtual ~BChannelSlider(); -static BArchivable* Instantiate(BMessage* from); -virtual status_t Archive(BMessage* into, bool deep = true) const; + static BArchivable* Instantiate(BMessage* from); + virtual status_t Archive(BMessage* into, bool deep = true) const; -virtual orientation Orientation() const; - void SetOrientation(orientation o); + virtual orientation Orientation() const; + void SetOrientation(enum orientation orientation); -virtual int32 MaxChannelCount() const; -virtual bool SupportsIndividualLimits() const; + virtual int32 MaxChannelCount() const; + virtual bool SupportsIndividualLimits() const; -virtual void AttachedToWindow(); -virtual void AllAttached(); -virtual void DetachedFromWindow(); -virtual void AllDetached(); + virtual void AttachedToWindow(); + virtual void AllAttached(); + virtual void DetachedFromWindow(); + virtual void AllDetached(); -virtual void MessageReceived(BMessage* msg); + virtual void MessageReceived(BMessage* message); -virtual void Draw(BRect area); -virtual void MouseDown(BPoint where); -virtual void MouseUp(BPoint pt); -virtual void MouseMoved(BPoint pt,uint32 code, - const BMessage* message); -virtual void WindowActivated(bool state); -virtual void KeyDown(const char* bytes, int32 numBytes); -virtual void KeyUp(const char* bytes, int32 numBytes); -virtual void FrameResized(float width, float height); + virtual void Draw(BRect area); + virtual void MouseDown(BPoint where); + virtual void MouseUp(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMessage); + virtual void WindowActivated(bool state); + virtual void KeyDown(const char* bytes, int32 numBytes); + virtual void KeyUp(const char* bytes, int32 numBytes); + virtual void FrameResized(float width, float height); -virtual void SetFont(const BFont* font, uint32 mask = B_FONT_ALL); -virtual void MakeFocus(bool focusState = true); + virtual void SetFont(const BFont* font, + uint32 mask = B_FONT_ALL); + virtual void MakeFocus(bool focusState = true); -virtual void SetEnabled(bool on); + virtual void SetEnabled(bool on); -virtual void GetPreferredSize(float* width, float* height); + virtual void GetPreferredSize(float* _width, float* _height); -virtual BHandler* ResolveSpecifier(BMessage* msg, int32 index, - BMessage* specifier, int32 form, const char* p); -virtual status_t GetSupportedSuites(BMessage* data); + virtual BHandler* ResolveSpecifier(BMessage* message, int32 index, + BMessage* specifier, int32 form, + const char* p); + virtual status_t GetSupportedSuites(BMessage* data); // Perform rendering for an entire slider channel. virtual void DrawChannel(BView* into, int32 channel, BRect area, diff --git a/headers/os/interface/ControlLook.h b/headers/os/interface/ControlLook.h new file mode 100644 index 0000000000..4ffba22b3f --- /dev/null +++ b/headers/os/interface/ControlLook.h @@ -0,0 +1,297 @@ +/* + * Copyright 2009, Stephan Aßmus + * Distributed under the terms of the MIT License. + */ +#ifndef _CONTROL_LOOK_H +#define _CONTROL_LOOK_H + +#include +#include +#include +#include + + +class BControl; +class BGradientLinear; +class BView; + + +namespace BPrivate { + + +class BControlLook { +public: + BControlLook(); + virtual ~BControlLook(); + + enum frame_type { + B_BUTTON_FRAME, + B_MENU_FRAME, + B_LISTVIEW_FRAME, + B_INPUT_FRAME + }; + + enum background_type { + B_BUTTON_BACKGROUND, + B_MENU_BACKGROUND, + B_LISTVIEW_BACKGROUND, + B_INPUT_BACKGROUND + }; + + enum { + B_LEFT_BORDER = 1 << 0, + B_RIGHT_BORDER = 1 << 1, + B_TOP_BORDER = 1 << 2, + B_BOTTOM_BORDER = 1 << 3, + + B_ALL_BORDERS = B_LEFT_BORDER | B_RIGHT_BORDER + | B_TOP_BORDER | B_BOTTOM_BORDER + }; + + enum { + B_FOCUSED = 1 << 0, + B_CLICKED = 1 << 1, // some controls activate on mouse up + B_ACTIVATED = 1 << 2, + B_HOVER = 1 << 3, + B_DISABLED = 1 << 4, + B_DEFAULT_BUTTON = 1 << 5 + }; + + virtual BAlignment DefaultLabelAlignment() const; + virtual float DefaultLabelSpacing() const; + uint32 Flags(BControl* control) const; + + virtual void DrawButtonFrame(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + 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, + enum orientation orientation + = B_HORIZONTAL); + + virtual void DrawMenuBarBackground(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, + 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, + 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, + enum orientation orientation); + + virtual void DrawScrollBarBackground(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + enum orientation orientation); + + 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, + enum orientation orientation); + + virtual void DrawSliderBar(BView* view, BRect rect, + const BRect& updateRect, + const rgb_color& base, rgb_color fillColor, + uint32 flags, enum orientation orientation); + + virtual void DrawSliderThumb(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + enum orientation orientation); + + virtual void DrawSliderTriangle(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags, + enum orientation orientation); + + virtual void DrawSliderHashMarks(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, int32 count, + hash_mark_location location, + uint32 flags, enum orientation orientation); + + virtual void DrawActiveTab(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, uint32 flags = 0, + uint32 borders = B_ALL_BORDERS); + + virtual void DrawInctiveTab(BView* view, BRect& rect, + const BRect& updateRect, + const rgb_color& base, 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 border, 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 + + void DrawLabel(BView* view, const char* label, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags); + + virtual void DrawLabel(BView* view, const char* label, + BRect rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, + const BAlignment& alignment); + +protected: + void _DrawOuterResessedFrame(BView* view, + BRect& rect, const rgb_color& base, + float contrast = 1.0f, + float brightness = 1.0f, + 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 _FillGradient(BView* view, const BRect& rect, + const rgb_color& base, float topTint, + float bottomTint, + enum orientation orientation + = B_HORIZONTAL); + + void _FillGlossyGradient(BView* view, + const BRect& rect, const rgb_color& base, + float topTint, float middle1Tint, + float middle2Tint, float bottomTint, + enum orientation orientation + = B_HORIZONTAL); + + void _MakeGradient(BGradientLinear& gradient, + const BRect& rect, const rgb_color& base, + float topTint, float bottomTint, + enum orientation orientation + = B_HORIZONTAL) const; + + void _MakeGlossyGradient(BGradientLinear& gradient, + const BRect& rect, const rgb_color& base, + float topTint, float middle1Tint, + float middle2Tint, float bottomTint, + enum orientation orientation + = B_HORIZONTAL) const; + + bool _RadioButtonAndCheckBoxMarkColor( + const rgb_color& base, rgb_color& color, + uint32 flags) const; + + 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, + enum orientation orientation); + + void _DrawRoundCornerLeftTop(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, + const rgb_color& edgeColor, + const rgb_color& frameColor, + const rgb_color& bevelColor, + const BGradientLinear& fillGradient); + void _DrawRoundCornerRightTop(BView* view, + BRect& rect, const BRect& updateRect, + const rgb_color& base, + 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); +}; + +extern BControlLook* be_control_look; + + +} // namespace BPrivate + +using BPrivate::BControlLook; +using BPrivate::be_control_look; + +#endif // _CONTROL_LOOK_H diff --git a/headers/os/interface/Menu.h b/headers/os/interface/Menu.h index 0408ef2cde..3c269f7bf5 100644 --- a/headers/os/interface/Menu.h +++ b/headers/os/interface/Menu.h @@ -206,8 +206,10 @@ private: BRect _CalcFrame(BPoint where, bool* scrollOn); +protected: void _DrawItems(BRect updateRect); +private: bool _OverSuper(BPoint loc); bool _OverSubmenu(BMenuItem* item, BPoint loc); BPrivate::BMenuWindow* _MenuWindow(); diff --git a/headers/os/interface/ScrollBar.h b/headers/os/interface/ScrollBar.h index e73642cd0b..51fc199d6a 100644 --- a/headers/os/interface/ScrollBar.h +++ b/headers/os/interface/ScrollBar.h @@ -56,6 +56,13 @@ public: void SetOrientation(enum orientation orientation); orientation Orientation() const; + // TODO: make this a virtual method, it should be one, + // but it's not important right now. This is supposed + // to be used in case the BScrollBar should draw part of + // the focus indication of the target view for aesthetical + // reasons. BScrollView will forward this method. + status_t SetBorderHighlighted(bool state); + virtual void MessageReceived(BMessage* message); virtual void MouseDown(BPoint pt); virtual void MouseUp(BPoint pt); diff --git a/headers/os/interface/Slider.h b/headers/os/interface/Slider.h index aba86e213f..80b0327c05 100644 --- a/headers/os/interface/Slider.h +++ b/headers/os/interface/Slider.h @@ -177,6 +177,7 @@ class BSlider : public BControl { BSlider& operator=(const BSlider &); + void _InitBarColor(); void _InitObject(); private: diff --git a/src/apps/launchbox/IconButton.cpp b/src/apps/launchbox/IconButton.cpp index f409653520..93ffd2e47d 100644 --- a/src/apps/launchbox/IconButton.cpp +++ b/src/apps/launchbox/IconButton.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2006-2008, Haiku. + * Copyright 2006-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -80,8 +81,47 @@ IconButton::Draw(BRect area) rgb_color background = LowColor(); if (BView* parent = Parent()) background = parent->LowColor(); - rgb_color lightShadow, shadow, darkShadow, light; + BRect r(Bounds()); + + if (be_control_look != NULL) { + uint32 flags = 0; + BBitmap* bitmap = fNormalBitmap; + if (!IsEnabled()) { + flags |= BControlLook::B_DISABLED; + bitmap = fDisabledBitmap; + } + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + flags |= BControlLook::B_ACTIVATED; + + if (DrawBorder()) { + be_control_look->DrawButtonFrame(this, r, area, background, flags); + be_control_look->DrawButtonBackground(this, r, area, background, + flags); + } else { + SetHighColor(background); + FillRect(r); + } + + if (bitmap && bitmap->IsValid()) { + float x = r.left + floorf((r.Width() + - bitmap->Bounds().Width()) / 2.0 + 0.5); + float y = r.top + floorf((r.Height() + - bitmap->Bounds().Height()) / 2.0 + 0.5); + BPoint point(x, y); + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + point += BPoint(1.0, 1.0); + if (bitmap->ColorSpace() == B_RGBA32 + || bitmap->ColorSpace() == B_RGBA32_BIG) { + SetDrawingMode(B_OP_ALPHA); + SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); + } + DrawBitmap(bitmap, point); + } + return; + } + + rgb_color lightShadow, shadow, darkShadow, light; BBitmap* bitmap = fNormalBitmap; // adjust colors and bitmap according to flags if (IsEnabled()) { @@ -151,7 +191,7 @@ IconButton::Draw(BRect area) // background SetDrawingMode(B_OP_COPY); FillRect(r, B_SOLID_LOW); - ConstrainClippingRegion(&originalClippingRegion); + ConstrainClippingRegion(NULL); // label if (fLabel.CountChars() > 0) { SetDrawingMode(B_OP_COPY); @@ -243,8 +283,8 @@ IconButton::GetPreferredSize(float* width, float* height) if (minHeight < MIN_SPACE) minHeight = MIN_SPACE; - float hPadding = max_c(4.0, ceilf(minHeight / 4.0)); - float vPadding = max_c(4.0, ceilf(minWidth / 4.0)); + float hPadding = max_c(6.0, ceilf(minHeight / 4.0)); + float vPadding = max_c(6.0, ceilf(minWidth / 4.0)); if (fLabel.CountChars() > 0) { font_height fh; diff --git a/src/apps/launchbox/LaunchButton.cpp b/src/apps/launchbox/LaunchButton.cpp index 5e2d90ce8b..da268199be 100644 --- a/src/apps/launchbox/LaunchButton.cpp +++ b/src/apps/launchbox/LaunchButton.cpp @@ -253,8 +253,8 @@ LaunchButton::PreferredSize() float minWidth = fIconSize; float minHeight = fIconSize; - float hPadding = max_c(4.0, ceilf(minHeight / 4.0)); - float vPadding = max_c(4.0, ceilf(minWidth / 4.0)); + float hPadding = max_c(6.0, ceilf(minHeight / 3.0)); + float vPadding = max_c(6.0, ceilf(minWidth / 3.0)); if (fLabel.CountChars() > 0) { font_height fh; diff --git a/src/kits/interface/BMCPrivate.cpp b/src/kits/interface/BMCPrivate.cpp index dbb2564e09..cd35198805 100644 --- a/src/kits/interface/BMCPrivate.cpp +++ b/src/kits/interface/BMCPrivate.cpp @@ -7,9 +7,11 @@ * Stephan Aßmus */ +#include + #include -#include +#include #include #include #include @@ -122,12 +124,44 @@ _BMCMenuBar_::AttachedToWindow() if (fFixedSize) SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP); Window()->SetKeyMenuBar(menuBar); + + float left, top, right, bottom; + GetItemMargins(&left, &top, &right, &bottom); + + // TODO: Better fix would be to make BMenuItem draw text properly + // centered + font_height fontHeight; + GetFontHeight(&fontHeight); + top = ceilf((Bounds().Height() - ceilf(fontHeight.ascent) + - ceilf(fontHeight.descent)) / 2) + 1; + bottom = top - 1; + + if (be_control_look) + left = right = be_control_look->DefaultLabelSpacing(); + + SetItemMargins(left, top, right + fShowPopUpMarker ? 10 : 0, bottom); } void _BMCMenuBar_::Draw(BRect updateRect) { + if (be_control_look != NULL) { + BRect rect(Bounds()); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = 0; + if (!IsEnabled()) + flags |= BControlLook::B_DISABLED; + if (IsFocus()) + flags |= BControlLook::B_FOCUSED; + be_control_look->DrawMenuFieldBackground(this, rect, + updateRect, base, fShowPopUpMarker, flags); + + _DrawItems(updateRect); + + return; + } + if (!fShowPopUpMarker) { BMenuBar::Draw(updateRect); return; diff --git a/src/kits/interface/Box.cpp b/src/kits/interface/Box.cpp index 3af2bb6c56..cf1192f220 100644 --- a/src/kits/interface/Box.cpp +++ b/src/kits/interface/Box.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -53,8 +54,7 @@ BBox::BBox(BRect frame, const char *name, uint32 resizingMode, uint32 flags, BBox::BBox(const char* name, uint32 flags, border_style border, BView* child) - : BView(BRect(0, 0, -1, -1), name, B_FOLLOW_NONE, - flags | B_WILL_DRAW | B_FRAME_EVENTS | B_SUPPORTS_LAYOUT), + : BView(name, flags | B_WILL_DRAW | B_FRAME_EVENTS), fStyle(border) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -68,8 +68,7 @@ BBox::BBox(const char* name, uint32 flags, border_style border, BView* child) BBox::BBox(border_style border, BView* child) - : BView(BRect(0, 0, -1, -1), NULL, B_FOLLOW_NONE, - B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP | B_SUPPORTS_LAYOUT), + : BView(NULL, B_WILL_DRAW | B_FRAME_EVENTS | B_NAVIGABLE_JUMP), fStyle(border) { SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); @@ -639,15 +638,27 @@ BBox::_DrawPlain(BRect labelBox) BRect rect = Bounds(); rect.top += TopBorderOffset(); - rgb_color shadow = tint_color(ViewColor(), B_DARKEN_3_TINT); + float lightTint; + float shadowTint; + if (be_control_look != NULL) { + lightTint = B_LIGHTEN_1_TINT; + shadowTint = B_DARKEN_1_TINT; + } else { + lightTint = B_LIGHTEN_MAX_TINT; + shadowTint = B_DARKEN_3_TINT; + } if (rect.Height() == 0.0 || rect.Width() == 0.0) { // used as separator + rgb_color shadow = tint_color(ViewColor(), B_DARKEN_2_TINT); + SetHighColor(shadow); StrokeLine(rect.LeftTop(),rect.RightBottom()); } else { // used as box - rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT); + rgb_color light = tint_color(ViewColor(), lightTint); + rgb_color shadow = tint_color(ViewColor(), shadowTint); + BeginLineArray(4); AddLine(BPoint(rect.left, rect.bottom), BPoint(rect.left, rect.top), light); @@ -668,6 +679,23 @@ BBox::_DrawFancy(BRect labelBox) BRect rect = Bounds(); rect.top += TopBorderOffset(); + if (be_control_look != NULL) { + rgb_color base = ViewColor(); + if (rect.Height() == 1.0) { + // used as horizontal separator + be_control_look->DrawGroupFrame(this, rect, rect, base, + BControlLook::B_TOP_BORDER); + } else if (rect.Width() == 1.0) { + // used as vertical separator + be_control_look->DrawGroupFrame(this, rect, rect, base, + BControlLook::B_LEFT_BORDER); + } else { + // used as box + be_control_look->DrawGroupFrame(this, rect, rect, base); + } + return; + } + rgb_color light = tint_color(ViewColor(), B_LIGHTEN_MAX_TINT); rgb_color shadow = tint_color(ViewColor(), B_DARKEN_3_TINT); diff --git a/src/kits/interface/Button.cpp b/src/kits/interface/Button.cpp index 57e301df58..551b84dcca 100644 --- a/src/kits/interface/Button.cpp +++ b/src/kits/interface/Button.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -102,6 +103,24 @@ BButton::Archive(BMessage* archive, bool deep) const void BButton::Draw(BRect updateRect) { + if (be_control_look != NULL) { + BRect rect(Bounds()); + rgb_color base = LowColor(); + uint32 flags = be_control_look->Flags(this); + if (IsDefault()) + flags |= BControlLook::B_DEFAULT_BUTTON; + be_control_look->DrawButtonFrame(this, rect, updateRect, + base, flags); + be_control_look->DrawButtonBackground(this, rect, updateRect, + base, flags); + + // always leave some room around the label + rect.InsetBy(3.0, 3.0); + be_control_look->DrawLabel(this, Label(), rect, updateRect, + base, flags, BAlignment(B_ALIGN_CENTER, B_ALIGN_MIDDLE)); + return; + } + font_height fh; GetFontHeight(&fh); diff --git a/src/kits/interface/ChannelSlider.cpp b/src/kits/interface/ChannelSlider.cpp index 7fe25439e8..8f079a465d 100644 --- a/src/kits/interface/ChannelSlider.cpp +++ b/src/kits/interface/ChannelSlider.cpp @@ -4,8 +4,10 @@ * Distributed under the terms of the MIT License. */ -#include #include + +#include +#include #include #include #include @@ -79,12 +81,24 @@ BChannelSlider::BChannelSlider(BRect area, const char *name, const char *label, BChannelSlider::BChannelSlider(BRect area, const char *name, const char *label, - BMessage *model, orientation o, int32 channels, uint32 resizeMode, uint32 flags) + BMessage *model, enum orientation orientation, int32 channels, + uint32 resizeMode, uint32 flags) : BChannelControl(area, name, label, model, channels, resizeMode, flags) { _InitData(); - SetOrientation(o); + SetOrientation(orientation); +} + + +BChannelSlider::BChannelSlider(const char *name, const char *label, + BMessage *model, enum orientation orientation, int32 channels, + uint32 flags) + : BChannelControl(name, label, model, channels, flags) + +{ + _InitData(); + SetOrientation(orientation); } @@ -138,9 +152,9 @@ BChannelSlider::Orientation() const void -BChannelSlider::SetOrientation(orientation _orientation) +BChannelSlider::SetOrientation(enum orientation orientation) { - bool isVertical = _orientation == B_VERTICAL; + bool isVertical = orientation == B_VERTICAL; if (isVertical != _Vertical()) { fVertical = isVertical; Invalidate(Bounds()); @@ -415,6 +429,10 @@ void BChannelSlider::FrameResized(float newWidth, float newHeight) { BChannelControl::FrameResized(newWidth, newHeight); + + delete fBacking; + fBacking = NULL; + Invalidate(Bounds()); } @@ -533,6 +551,20 @@ BChannelSlider::DrawGroove(BView *into, int32 channel, BPoint leftTop, ASSERT(into != NULL); BRect rect(leftTop, bottomRight); + if (be_control_look != NULL) { + rect.InsetBy(-2.5, -2.5); + rect.left = floorf(rect.left); + rect.top = floorf(rect.top); + rect.right = floorf(rect.right); + rect.bottom = floorf(rect.bottom); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color barColor = be_control_look->SliderBarColor(base); + uint32 flags = 0; + be_control_look->DrawSliderBar(into, rect, rect, base, + barColor, flags, Orientation()); + return; + } + _DrawGrooveFrame(fBackingView, rect.InsetByCopy(-2.5, -2.5)); rect.InsetBy(-0.5, -0.5); @@ -553,6 +585,22 @@ BChannelSlider::DrawThumb(BView* into, int32 channel, BPoint where, bool pressed where.x -= bitmapBounds.right / 2.0; where.y -= bitmapBounds.bottom / 2.0; + + if (be_control_look != NULL) { + BRect rect(bitmapBounds.OffsetToCopy(where)); + rect.InsetBy(1, 1); + rect.left = floorf(rect.left); + rect.top = floorf(rect.top); + rect.right = ceilf(rect.right + 0.5); + rect.bottom = ceilf(rect.bottom + 0.5); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = 0; + be_control_look->DrawSliderThumb(into, rect, rect, base, + flags, Orientation()); + return; + } + + into->PushState(); into->SetDrawingMode(B_OP_OVER); diff --git a/src/kits/interface/CheckBox.cpp b/src/kits/interface/CheckBox.cpp index 11eaf1f0e9..8d616f95bc 100644 --- a/src/kits/interface/CheckBox.cpp +++ b/src/kits/interface/CheckBox.cpp @@ -11,6 +11,7 @@ #include +#include #include #include @@ -82,6 +83,26 @@ BCheckBox::Archive(BMessage *archive, bool deep) const void BCheckBox::Draw(BRect updateRect) { + if (be_control_look) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + + uint32 flags = be_control_look->Flags(this); + if (fOutlined) + flags |= BControlLook::B_CLICKED; + + BRect checkBoxRect(_CheckBoxFrame()); + BRect rect(checkBoxRect); + be_control_look->DrawCheckBox(this, rect, updateRect,base, flags); + + BRect labelRect(Bounds()); + labelRect.left = checkBoxRect.right + + be_control_look->DefaultLabelSpacing(); + + be_control_look->DrawLabel(this, Label(), labelRect, updateRect, + base, flags); + return; + } + font_height fontHeight; GetFontHeight(&fontHeight); @@ -551,7 +572,7 @@ BCheckBox::_CheckBoxFrame() const font_height fontHeight; GetFontHeight(&fontHeight); - return BRect(1.0f, 3.0f, ceilf(3.0f + fontHeight.ascent), + return BRect(0.0f, 2.0f, ceilf(3.0f + fontHeight.ascent), ceilf(5.0f + fontHeight.ascent)); } diff --git a/src/kits/interface/ColorControl.cpp b/src/kits/interface/ColorControl.cpp index ee32d88f04..c502fc6257 100644 --- a/src/kits/interface/ColorControl.cpp +++ b/src/kits/interface/ColorControl.cpp @@ -11,11 +11,12 @@ /** BColorControl displays a palette of selectable colors. */ +#include #include #include -#include +#include #include #include #include @@ -391,16 +392,12 @@ BColorControl::Draw(BRect updateRect) if (!fBitmap->Lock()) return; - if (fOffscreenView->Bounds().Intersects(updateRect)) { - BRegion region(updateRect); - ConstrainClippingRegion(®ion); + if (fOffscreenView->Bounds().Intersects(updateRect)) DrawBitmap(fBitmap, B_ORIGIN); - ConstrainClippingRegion(NULL); - } fBitmap->Unlock(); _DrawSelectors(this); - + } else { _DrawColorArea(this, updateRect); _DrawSelectors(this); @@ -413,44 +410,56 @@ BColorControl::_DrawColorArea(BView* target, BRect update) { BRegion region(update); target->ConstrainClippingRegion(®ion); - - rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); - rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT); - rgb_color lightenmax = tint_color(noTint, B_LIGHTEN_MAX_TINT); - rgb_color darken1 = tint_color(noTint, B_DARKEN_1_TINT); - rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT); - rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); - + BRect bevelRect = fPaletteFrame.InsetByCopy(-2.0,-2.0); //bevel - bool enabled = IsEnabled(); - - // First bevel - if (enabled) - target->SetHighColor(darken1); - else + + rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color darken1 = tint_color(noTint, B_DARKEN_1_TINT); + + if (be_control_look != NULL) { + uint32 flags = 0; + if (!enabled) + flags |= BControlLook::B_DISABLED; + be_control_look->DrawTextControlBorder(target, bevelRect, update, + noTint, flags); + } else { + rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT); + rgb_color lightenmax = tint_color(noTint, B_LIGHTEN_MAX_TINT); + rgb_color darken2 = tint_color(noTint, B_DARKEN_2_TINT); + rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); + + // First bevel + if (enabled) + target->SetHighColor(darken1); + else + target->SetHighColor(noTint); + target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); + target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); + if (enabled) + target->SetHighColor(lightenmax); + else + target->SetHighColor(lighten1); + target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), + bevelRect.RightBottom()); + target->StrokeLine(bevelRect.RightBottom(), + BPoint(bevelRect.right, bevelRect.top + 1.0f)); + + bevelRect.InsetBy(1.0f, 1.0f); + + // Second bevel + if (enabled) + target->SetHighColor(darken4); + else + target->SetHighColor(darken2); + target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); + target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); target->SetHighColor(noTint); - target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); - target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); - if (enabled) - target->SetHighColor(lightenmax); - else - target->SetHighColor(lighten1); - target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), bevelRect.RightBottom()); - target->StrokeLine(bevelRect.RightBottom(), BPoint(bevelRect.right, bevelRect.top + 1.0f)); - - bevelRect.InsetBy(1.0f, 1.0f); - - // Second bevel - if (enabled) - target->SetHighColor(darken4); - else - target->SetHighColor(darken2); - target->StrokeLine(bevelRect.LeftBottom(), bevelRect.LeftTop()); - target->StrokeLine(bevelRect.LeftTop(), bevelRect.RightTop()); - target->SetHighColor(noTint); - target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), bevelRect.RightBottom()); - target->StrokeLine(bevelRect.RightBottom(), BPoint(bevelRect.right, bevelRect.top + 1.0f)); + target->StrokeLine(BPoint(bevelRect.left + 1.0f, bevelRect.bottom), + bevelRect.RightBottom()); + target->StrokeLine(bevelRect.RightBottom(), + BPoint(bevelRect.right, bevelRect.top + 1.0f)); + } if (fPaletteMode) { int colBegin = max_c(0, -1 + int(update.left) / int(fCellSize)); @@ -501,7 +510,7 @@ BColorControl::_DrawColorArea(BView* target, BRect update) _ColorRamp(_RampFrame(3), target, blue, compColor, 0, false, update); } - ConstrainClippingRegion(NULL); + target->ConstrainClippingRegion(NULL); } diff --git a/src/kits/interface/ControlLook.cpp b/src/kits/interface/ControlLook.cpp new file mode 100644 index 0000000000..850d507eb5 --- /dev/null +++ b/src/kits/interface/ControlLook.cpp @@ -0,0 +1,2041 @@ +/* + * Copyright 2009, Stephan Aßmus + * Distributed under the terms of the MIT License. + */ +#include + +#include + +#include +#include +#include +#include +#include +#include + +namespace BPrivate { + +static const float kEdgeBevelLightTint = 0.59; +static const float kEdgeBevelShadowTint = 1.0735; + + +BControlLook::BControlLook() +{ +} + + +BControlLook::~BControlLook() +{ +} + + +BAlignment +BControlLook::DefaultLabelAlignment() const +{ + return BAlignment(B_ALIGN_LEFT, B_ALIGN_VERTICAL_CENTER); +} + + +float +BControlLook::DefaultLabelSpacing() const +{ + return 4.0;//ceilf(be_plain_font->Size() / 4.0); +} + + +uint32 +BControlLook::Flags(BControl* control) const +{ + uint32 flags = 0; + + if (!control->IsEnabled()) + flags |= B_DISABLED; + + if (control->IsFocus()) + flags |= B_FOCUSED; + + if (control->Value() == B_CONTROL_ON) + flags |= B_ACTIVATED; + + return flags; +} + + +// #pragma mark - + + +void +BControlLook::DrawButtonFrame(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, uint32 borders) +{ + // colors + rgb_color dark1BorderColor; + rgb_color dark2BorderColor; + + if ((flags & B_DISABLED) == 0) { + dark1BorderColor = tint_color(base, 1.33); + dark2BorderColor = tint_color(base, 1.45); + + if (flags & B_DEFAULT_BUTTON) { + dark2BorderColor = tint_color(dark1BorderColor, 1.5); + dark1BorderColor = tint_color(dark1BorderColor, 1.35); + } + } else { + dark1BorderColor = tint_color(base, 1.147); + dark2BorderColor = tint_color(base, 1.24); + + if (flags & B_DEFAULT_BUTTON) { + dark1BorderColor = tint_color(dark1BorderColor, 1.12); + dark2BorderColor = tint_color(dark1BorderColor, 1.16); + } + } + + if (flags & B_ACTIVATED) { + rgb_color temp = dark2BorderColor; + dark2BorderColor = dark1BorderColor; + dark1BorderColor = temp; + } + + // indicate focus by changing main button border + if (flags & B_FOCUSED) { + dark1BorderColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + dark2BorderColor = dark1BorderColor; + } + + if (flags & B_DEFAULT_BUTTON) { + float focusTint = 1.2; + if (flags & B_DISABLED) + focusTint = (B_NO_TINT + focusTint) / 2; + + rgb_color focusColor = tint_color(base, focusTint); + view->SetHighColor(base); + + view->StrokeRect(rect); + rect.InsetBy(1.0, 1.0); + + view->SetHighColor(focusColor); + view->StrokeRect(rect); + rect.InsetBy(1.0, 1.0); + view->StrokeRect(rect); + rect.InsetBy(1.0, 1.0); + + // bevel around external border + _DrawOuterResessedFrame(view, rect, focusColor, + (flags & B_DISABLED) ? 0.5 : 0.8, 0.9, borders); + } else { + // bevel around external border + _DrawOuterResessedFrame(view, rect, base, + (flags & B_DISABLED) ? 0.0 : 1.0, 1.0, borders); + } + + _DrawFrame(view, rect, dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor, borders); +} + + +void +BControlLook::DrawButtonBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders, enum orientation orientation) +{ + if (!rect.IsValid() || !updateRect.Intersects(rect)) + return; + + // the surface edges + + // colors + rgb_color buttonBgColor = tint_color(base, B_LIGHTEN_1_TINT); + rgb_color maxLightColor; + + rgb_color bevelColor1; + rgb_color bevelColor2; + + if ((flags & B_DISABLED) == 0) { + maxLightColor = tint_color(base, 0.2); + bevelColor1 = tint_color(base, 1.08); + bevelColor2 = base; + } else { + maxLightColor = tint_color(base, 0.7); + bevelColor1 = base; + bevelColor2 = buttonBgColor; + buttonBgColor = maxLightColor; + } + + if (flags & B_ACTIVATED) { + view->BeginLineArray(4); + + bevelColor1 = tint_color(bevelColor1, B_DARKEN_1_TINT); + bevelColor2 = tint_color(bevelColor2, B_DARKEN_1_TINT); + + // shadow along left/top borders + if (borders & B_LEFT_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.left, rect.bottom), bevelColor1); + rect.left++; + } + if (borders & B_TOP_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), bevelColor1); + 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), bevelColor2); + rect.left++; + } + if (borders & B_TOP_BORDER) { + view->AddLine(BPoint(rect.left, rect.top), + BPoint(rect.right, rect.top), bevelColor2); + rect.top++; + } + + view->EndLineArray(); + } else { + _DrawFrame(view, rect, + maxLightColor, maxLightColor, + bevelColor1, bevelColor1, + buttonBgColor, buttonBgColor, borders); + } + + // the actual surface top + + float topTint = 0.49; + float middleTint1 = 0.62; + float middleTint2 = 0.76; + float bottomTint = 0.90; + + if (flags & B_ACTIVATED) { + topTint = 1.11; + bottomTint = 1.08; + } + + if (flags & B_DISABLED) { + 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) { + static const float kHoverTintFactor = 0.85; + topTint *= kHoverTintFactor; + middleTint1 *= kHoverTintFactor; + middleTint2 *= kHoverTintFactor; + bottomTint *= kHoverTintFactor; + } + + if (flags & B_ACTIVATED) { + _FillGradient(view, rect, base, topTint, bottomTint, orientation); + } else { + _FillGlossyGradient(view, rect, base, topTint, middleTint1, + middleTint2, bottomTint, orientation); + } +} + + +void +BControlLook::DrawMenuBarBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 borders) +{ + if (!rect.IsValid() || !updateRect.Intersects(rect)) + return; + + // the surface edges + + // colors + rgb_color cornerColor = tint_color(base, 0.9); + rgb_color bevelColor1 = tint_color(base, 0.5); + rgb_color bevelColor2 = tint_color(base, 0.7); + rgb_color bevelColor3 = tint_color(base, 1.08); + + _DrawFrame(view, rect, + bevelColor2, bevelColor1, + bevelColor3, bevelColor3, + cornerColor, cornerColor, + borders); + + // the actual surface top + + float topTint = 0.69; + float bottomTint = 1.03; + + _FillGradient(view, rect, base, topTint, bottomTint); +} + + +void +BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, bool popupIndicator, + uint32 flags) +{ + if (popupIndicator) { + BRect leftRect(rect); + leftRect.right -= 10; + + BRect rightRect(rect); + rightRect.left = rightRect.right - 9; + + DrawMenuFieldBackground(view, leftRect, updateRect, base, flags, + B_LEFT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); + + rgb_color indicatorBase; + rgb_color markColor; + if (flags & B_DISABLED) { + indicatorBase = tint_color(base, 1.05); + markColor = tint_color(base, B_DARKEN_3_TINT); + } else { + indicatorBase = tint_color(base, 1.09); + markColor = tint_color(base, B_DARKEN_4_TINT); + } + + DrawMenuFieldBackground(view, rightRect, updateRect, indicatorBase, + flags, B_RIGHT_BORDER | B_TOP_BORDER | B_BOTTOM_BORDER); + + // popup marker + BPoint center(roundf((rightRect.left + rightRect.right) / 2.0), + roundf((rightRect.top + rightRect.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); + + view->SetHighColor(markColor); + view->FillTriangle(triangle[0], triangle[1], triangle[2]); + + view->SetFlags(viewFlags); + + rect = leftRect; + } else { + DrawMenuFieldBackground(view, rect, updateRect, base, flags); + } +} + +void +BControlLook::DrawMenuFieldBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !updateRect.Intersects(rect)) + return; + + // the surface edges + + // colors + rgb_color cornerColor = tint_color(base, 0.85); + rgb_color bevelColor1 = tint_color(base, 0.3); + rgb_color bevelColor2 = tint_color(base, 0.5); + rgb_color bevelColor3 = tint_color(base, 1.03); + + if (flags & B_DISABLED) { + cornerColor = tint_color(base, 0.8); + bevelColor1 = tint_color(base, 0.7); + bevelColor2 = tint_color(base, 0.8); + bevelColor3 = tint_color(base, 1.01); + } else { + cornerColor = tint_color(base, 0.85); + bevelColor1 = tint_color(base, 0.3); + bevelColor2 = tint_color(base, 0.5); + bevelColor3 = tint_color(base, 1.03); + } + + _DrawFrame(view, rect, + bevelColor2, bevelColor1, + bevelColor3, bevelColor3, + cornerColor, cornerColor, + borders); + + // the actual surface top + + float topTint = 0.49; + float middleTint1 = 0.62; + float middleTint2 = 0.76; + float bottomTint = 0.90; + + if (flags & B_DISABLED) { + 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) { + static const float kHoverTintFactor = 0.85; + topTint *= kHoverTintFactor; + middleTint1 *= kHoverTintFactor; + middleTint2 *= kHoverTintFactor; + bottomTint *= kHoverTintFactor; + } + + _FillGlossyGradient(view, rect, base, topTint, middleTint1, + middleTint2, bottomTint); +} + +void +BControlLook::DrawMenuBackground(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + uint32 borders) +{ + if (!rect.IsValid() || !updateRect.Intersects(rect)) + return; + + // the surface edges + + rgb_color bevelLightColor; + rgb_color bevelShadowColor; + rgb_color background = tint_color(base, 0.75); + + if (flags & B_DISABLED) { + 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); + } + + _DrawFrame(view, rect, + bevelLightColor, bevelLightColor, + bevelShadowColor, bevelShadowColor, + borders); + + // the actual 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() || !updateRect.Intersects(rect)) + return; + + // the surface edges + + float topTint; + float bottomTint; + rgb_color selectedColor = base; + + if (flags & B_ACTIVATED) { + topTint = 0.9; + bottomTint = 1.05; + selectedColor = tint_color(base, 1.26); + } else if (flags & B_DISABLED) { + 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); + + _DrawFrame(view, rect, + bevelLightColor, bevelLightColor, + bevelShadowColor, bevelShadowColor, + borders); + + // the actual 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) { + _DrawOuterResessedFrame(view, rect, base, 0.0); + + dark1BorderColor = tint_color(base, 1.15); + dark2BorderColor = tint_color(base, 1.15); + } else if (flags & B_CLICKED) { + 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); + + dark1BorderColor = tint_color(base, 1.40); + dark2BorderColor = tint_color(base, 1.38); + } + + if (flags & B_FOCUSED) { + dark1BorderColor = navigationColor; + dark2BorderColor = navigationColor; + } + + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor); + + if (flags & B_DISABLED) { + _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); + + rect.InsetBy(2, 2); + view->SetPenSize(max_c(1.0, ceilf(rect.Width() / 3.5))); + 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) { + borderColor = tint_color(base, 1.15); + bevelLight = base; + bevelShadow = base; + } else if (flags & B_CLICKED) { + 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) { + 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) { + 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); + rect.InsetBy(3, 3); + view->FillEllipse(rect); + } +} + + +void +BControlLook::DrawScrollBarBackground(BView* view, BRect& rect1, BRect& rect2, + const BRect& updateRect, const rgb_color& base, uint32 flags, + enum 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, + enum orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + float gradient1Tint; + float gradient2Tint; + float darkEdge1Tint; + float darkEdge2Tint; + float shadowTint; + + if (flags & B_DISABLED) { + 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); + } + } +} + + +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, enum orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + // 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 { + sliderPosition = floorf(rect.top + 2 + (rect.Height() - 2) + * sliderScale); + leftBarSide.bottom = sliderPosition - 1; + rightBarSide.top = sliderPosition; + } + + // 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(); + + view->ConstrainClippingRegion(NULL); +} + + +void +BControlLook::DrawSliderBar(BView* view, BRect rect, const BRect& updateRect, + const rgb_color& base, rgb_color fillColor, uint32 flags, + enum 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); + + 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; + + if (flags & B_DISABLED) { + edgeLightTint = 1.0; + edgeShadowTint = 1.0; + frameLightTint = 1.20; + frameShadowTint = 1.25; + fillLightTint = 0.9; + fillShadowTint = 1.05; + + 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; + } + + rgb_color edgeLightColor = tint_color(base, edgeLightTint); + rgb_color edgeShadowColor = tint_color(base, edgeShadowTint); + rgb_color frameLightColor = tint_color(fillColor, frameLightTint); + rgb_color frameShadowColor = tint_color(fillColor, frameShadowTint); + rgb_color fillLightColor = tint_color(fillColor, fillLightTint); + rgb_color fillShadowColor = tint_color(fillColor, fillShadowTint); + + 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(); + + _FillGradient(view, barRect, fillColor, fillShadowTint, fillLightTint, + orientation); +} + + +void +BControlLook::DrawSliderThumb(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, enum 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) { + // 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) { + 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, + enum 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) { + 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) { + static const float kHoverTintFactor = 0.85; + topTint *= kHoverTintFactor; + middleTint1 *= kHoverTintFactor; + middleTint2 *= kHoverTintFactor; + bottomTint *= kHoverTintFactor; + } + + if (flags & B_FOCUSED) { + // 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) { + 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--; + + float center = (rect.left + rect.right) / 2; + +// BShape shape; +// 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(rect.right + 0.5, rect.bottom - 1 + 0.5)); +// shape.LineTo(BPoint(center + 0.5, rect.top + 0.5)); +// shape.LineTo(BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5)); +// shape.Close(); +// +// BGradientLinear gradient; +// gradient.AddColor(frameLightColor, 0); +// gradient.AddColor(frameShadowColor, 255); +// gradient.SetStart(rect.LeftTop()); +// gradient.SetEnd(rect.RightBottom()); +// +// view->SetHighColor(frameLightColor); +// view->StrokeShape(&shape); +// +// view->StrokeRect(rect); + + uint32 viewFlags = view->Flags(); + view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); + view->SetLineMode(B_ROUND_CAP, B_ROUND_JOIN); + + BPoint triangle[3]; + triangle[0] = BPoint(rect.left + 0.5, rect.bottom - 1 + 0.5); + triangle[1] = BPoint(rect.right + 0.5, rect.bottom - 1 + 0.5); + triangle[2] = BPoint(center + 0.5, rect.top + 0.5); + + view->SetHighColor(frameLightColor); + view->StrokeTriangle(triangle[0], triangle[1], triangle[2]); + view->StrokeLine(BPoint(rect.left, rect.bottom), + BPoint(rect.right + 1, rect.bottom)); + + rect.InsetBy(1, 1); + + triangle[0] = BPoint(rect.left, rect.bottom); + triangle[1] = BPoint(rect.right + 1, rect.bottom); + triangle[2] = BPoint(center, rect.top); + + BGradientLinear gradient; + if (flags & B_DISABLED) { + _MakeGradient(gradient, rect, base, topTint, bottomTint); + } else { + _MakeGlossyGradient(gradient, rect, base, topTint, middleTint1, + middleTint2, bottomTint); + } + + view->FillTriangle(triangle[0], triangle[1], triangle[2], gradient); + + +// +// _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 +// rect.InsetBy(0, 2); +// 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()); +// +// view->SetDrawingMode(B_OP_COPY); + + 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, enum orientation orientation) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + rgb_color lightColor; + rgb_color darkColor; + + if (flags & B_DISABLED) { + 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 = max_c(count, 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) { + + 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(); + } +} + + +#if 0 +static void +_MakeTabShape(BShape& shape, const BRect& rect, float cornerRadius, + float slopeRadius) +{ + BPoint curve[3]; + + shape.Clear(); + shape.MoveTo(BPoint(rect.left, rect.bottom)); + shape.LineTo(BPoint(rect.left, rect.top + cornerRadius)); + + curve[0].x = rect.left; + curve[0].y = rect.top + 0.56 * cornerRadius; + curve[1].x = rect.left + 0.56 * cornerRadius; + curve[1].y = rect.top; + curve[2].x = rect.left + cornerRadius; + curve[2].y = rect.top; + + shape.BezierTo(curve); + + shape.LineTo(BPoint(rect.right - slopeRadius, rect.top)); + + curve[0].x = rect.right - slopeRadius / 5; + curve[0].y = rect.top; + curve[1].x = rect.right; + curve[1].y = rect.bottom - slopeRadius / 5; + curve[2].x = rect.right; + curve[2].y = rect.bottom; + + shape.BezierTo(curve); +} +#endif + + +void +BControlLook::DrawActiveTab(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, uint32 borders) +{ + 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) { + edgeShadowColor = base; + edgeLightColor = base; + frameShadowColor = tint_color(base, 1.30); + frameLightColor = tint_color(base, 1.25); + bevelShadowColor = tint_color(base, 1.07); + bevelLightColor = tint_color(base, 0.8); + fillGradient.AddColor(tint_color(base, 0.85), 0); + fillGradient.AddColor(base, 255); + } else { + edgeShadowColor = tint_color(base, 1.03); + edgeLightColor = tint_color(base, 0.80); + frameShadowColor = tint_color(base, 1.30); + frameLightColor = tint_color(base, 1.30); + bevelShadowColor = tint_color(base, 1.07); + bevelLightColor = tint_color(base, 0.6); + fillGradient.AddColor(tint_color(base, 0.75), 0); + fillGradient.AddColor(tint_color(base, 1.03), 255); + } +#if 1 + static const float kRoundCornerRadius = 4; + + // left/top corner + BRect cornerRect(rect); + cornerRect.right = cornerRect.left + kRoundCornerRadius; + cornerRect.bottom = cornerRect.top + kRoundCornerRadius; + + BRegion clipping(rect); + clipping.Exclude(cornerRect); + + _DrawRoundCornerLeftTop(view, cornerRect, updateRect, base, edgeShadowColor, + frameLightColor, bevelLightColor, fillGradient); + + // left/top corner + cornerRect.right = rect.right; + cornerRect.left = cornerRect.right - kRoundCornerRadius; + + clipping.Exclude(cornerRect); + + _DrawRoundCornerRightTop(view, cornerRect, updateRect, base, edgeShadowColor, + edgeLightColor, frameLightColor, frameShadowColor, bevelLightColor, + bevelShadowColor, fillGradient); + + // rest of frame and fill + view->ConstrainClippingRegion(&clipping); + + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, + edgeLightColor, + borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); +// B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); + if ((borders & B_LEFT_BORDER) == 0) + rect.left++; + if ((borders & B_RIGHT_BORDER) == 0) + rect.right--; + + _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, + frameShadowColor, B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); + + _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, + bevelShadowColor); + + view->FillRect(rect, fillGradient); + + view->ConstrainClippingRegion(NULL); +#else + + view->MovePenTo(B_ORIGIN); + + uint32 viewFlags = view->Flags(); + view->SetFlags(viewFlags | B_SUBPIXEL_PRECISE); + + rect.InsetBy(0.5, 0.5); + + float cornerRadius = 4; + float slopeRadius = 20; + BShape shape; + + _MakeTabShape(shape, rect, cornerRadius, slopeRadius); + view->SetHighColor(edgeShadowColor); + view->StrokeShape(&shape); + + rect.left += 1; + rect.top += 1; + rect.right -= 1; + cornerRadius -= 1; + + _MakeTabShape(shape, rect, cornerRadius, slopeRadius); + view->SetHighColor(frameLightColor); + view->StrokeShape(&shape); + + rect.left += 0.5; + rect.top += 0.5; + rect.right -= 0.5; + cornerRadius -= 1; + + _MakeTabShape(shape, rect, cornerRadius, slopeRadius); + view->FillShape(&shape, fillGradient); + + view->SetFlags(viewFlags); +#endif +} + + +void +BControlLook::DrawInctiveTab(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, uint32 flags, uint32 borders) +{ + 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) { + edgeShadowColor = base; + edgeLightColor = base; + frameShadowColor = tint_color(base, 1.30); + frameLightColor = tint_color(base, 1.25); + bevelShadowColor = tint_color(base, 1.07); + bevelLightColor = tint_color(base, 0.8); + fillGradient.AddColor(tint_color(base, 0.85), 0); + fillGradient.AddColor(base, 255); + } else { + edgeShadowColor = tint_color(base, 1.03); + edgeLightColor = tint_color(base, 0.80); + frameShadowColor = tint_color(base, 1.30); + frameLightColor = tint_color(base, 1.30); + bevelShadowColor = tint_color(base, 1.15); + bevelLightColor = tint_color(base, 1.10); + fillGradient.AddColor(tint_color(base, 1.12), 0); + fillGradient.AddColor(tint_color(base, 1.08), 255); + } + + // active tabs stand out at the top, but this is an inactive tab + view->SetHighColor(base); + view->FillRect(BRect(rect.left, rect.top, rect.right, rect.top + 4)); + rect.top += 4; + + // frame and fill + _DrawFrame(view, rect, edgeShadowColor, edgeShadowColor, edgeLightColor, + edgeLightColor, + borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); + + _DrawFrame(view, rect, frameLightColor, frameLightColor, frameShadowColor, + frameShadowColor, + //B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER); + borders & (B_LEFT_BORDER | B_TOP_BORDER | B_RIGHT_BORDER)); + + _DrawFrame(view, rect, bevelLightColor, bevelLightColor, bevelShadowColor, + bevelShadowColor, + //B_BOTTOM_BORDER); + 0); + + view->FillRect(rect, fillGradient); +} + + +// #pragma mark - + + +void +BControlLook::DrawBorder(BView* view, BRect& rect, const BRect& updateRect, + const rgb_color& base, border_style border, uint32 flags, uint32 borders) +{ + if (border == B_NO_BORDER) + return; + + rgb_color scrollbarFrameColor = tint_color(base, B_DARKEN_2_TINT); + if (flags & B_FOCUSED) + scrollbarFrameColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + + if (border == B_FANCY_BORDER) + _DrawOuterResessedFrame(view, rect, base, 1.0, 1.0, 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) { + 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); + + if (flags & B_DISABLED) { + _DrawOuterResessedFrame(view, rect, base, 0.0, 1.0, borders); + + dark1BorderColor = tint_color(base, 1.15); + dark2BorderColor = tint_color(base, 1.15); + } else if (flags & B_CLICKED) { + dark1BorderColor = tint_color(base, 1.50); + dark2BorderColor = tint_color(base, 1.49); + + _DrawFrame(view, rect, + dark1BorderColor, dark1BorderColor, + dark2BorderColor, dark2BorderColor); + + dark2BorderColor = dark1BorderColor; + } else { + _DrawOuterResessedFrame(view, rect, base, 0.6, 1.0, borders); + + dark1BorderColor = tint_color(base, 1.40); + dark2BorderColor = tint_color(base, 1.38); + } + + if ((flags & B_DISABLED) == 0 && (flags & B_FOCUSED)) { + dark1BorderColor = navigationColor; + dark2BorderColor = navigationColor; + } + + _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) +{ + DrawLabel(view, label, rect, updateRect, base, flags, + DefaultLabelAlignment()); +} + + +void +BControlLook::DrawLabel(BView* view, const char* label, BRect rect, + const BRect& updateRect, const rgb_color& base, uint32 flags, + const BAlignment& alignment) +{ + if (!rect.Intersects(updateRect)) + return; + + // setup the text color + rgb_color color; + if (base.red + base.green + base.blue > 128 * 3) + color = tint_color(base, B_DARKEN_MAX_TINT); + else + color = tint_color(base, B_LIGHTEN_MAX_TINT); + + if (flags & B_DISABLED) { + color.red = (uint8)(((int32)base.red + color.red + 1) / 2); + color.green = (uint8)(((int32)base.green + color.green + 1) / 2); + color.blue = (uint8)(((int32)base.blue + color.blue + 1) / 2); + } + + view->SetHighColor(color); + view->SetDrawingMode(B_OP_OVER); + + // truncate the label if necessary and get the width and height + BString truncatedLabel(label); + + BFont font; + view->GetFont(&font); + + float width = rect.Width(); + font.TruncateString(&truncatedLabel, B_TRUNCATE_END, width); + width = font.StringWidth(truncatedLabel.String()); + + font_height fontHeight; + font.GetHeight(&fontHeight); + float height = ceilf(fontHeight.ascent) + ceilf(fontHeight.descent); + + // handle alignment + BPoint location; + + switch (alignment.horizontal) { + default: + case B_ALIGN_LEFT: + location.x = rect.left; + break; + case B_ALIGN_RIGHT: + location.x = rect.right - width; + break; + case B_ALIGN_CENTER: + location.x = (rect.left + rect.right - width) / 2.0f; + break; + } + + switch (alignment.vertical) { + case B_ALIGN_TOP: + location.y = rect.top + ceilf(fontHeight.ascent); + break; + default: + case B_ALIGN_MIDDLE: + location.y = floorf((rect.top + rect.bottom - height) / 2.0f + 0.5f) + + ceilf(fontHeight.ascent); + break; + case B_ALIGN_BOTTOM: + location.y = rect.bottom - ceilf(fontHeight.descent); + break; + } + + view->DrawString(truncatedLabel.String(), location); +} + + +// #pragma mark - + + +void +BControlLook::_DrawOuterResessedFrame(BView* view, BRect& rect, + const rgb_color& base, float contrast, float brightness, uint32 borders) +{ + // colors + float tintLight = kEdgeBevelLightTint; + float tintShadow = kEdgeBevelShadowTint; + + if (contrast == 0.0) { + tintLight = B_NO_TINT; + tintShadow = B_NO_TINT; + } else if (contrast != 1.0) { + tintLight = B_NO_TINT + (tintLight - B_NO_TINT) * contrast; + tintShadow = B_NO_TINT + (tintShadow - B_NO_TINT) * contrast; + } + + rgb_color borderBevelShadow = tint_color(base, tintShadow); + rgb_color borderBevelLight = tint_color(base, tintLight); + + if (brightness < 1.0) { + borderBevelShadow.red = uint8(borderBevelShadow.red * brightness); + borderBevelShadow.green = uint8(borderBevelShadow.green * brightness); + borderBevelShadow.blue = uint8(borderBevelShadow.blue * brightness); + borderBevelLight.red = uint8(borderBevelLight.red * brightness); + borderBevelLight.green = uint8(borderBevelLight.green * brightness); + borderBevelLight.blue = uint8(borderBevelLight.blue * brightness); + } + + _DrawFrame(view, rect, borderBevelShadow, borderBevelShadow, + borderBevelLight, borderBevelLight, 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::_DrawShadowFrame(BView* view, BRect& rect, const rgb_color& base, +// uint32 borders) +//{ +// view->BeginLineArray(4); +// +// bevelColor1 = tint_color(base, 1.2); +// bevelColor2 = tint_color(base, 1.1); +// +// // shadow along left/top borders +// if (rect.Height() > 0 && borders & B_LEFT_BORDER) { +// view->AddLine(BPoint(rect.left, rect.top), +// BPoint(rect.left, rect.bottom), bevelColor1); +// rect.left++; +// } +// if (rect.Width() > 0 && borders & B_TOP_BORDER) { +// view->AddLine(BPoint(rect.left, rect.top), +// BPoint(rect.right, rect.top), bevelColor1); +// rect.top++; +// } +// +// // softer shadow along left/top borders +// if (rect.Height() > 0 && borders & B_LEFT_BORDER) { +// view->AddLine(BPoint(rect.left, rect.top), +// BPoint(rect.left, rect.bottom), bevelColor2); +// rect.left++; +// } +// if (rect.Width() > 0 && borders & B_TOP_BORDER) { +// view->AddLine(BPoint(rect.left, rect.top), +// BPoint(rect.right, rect.top), bevelColor2); +// rect.top++; +// } +// +// view->EndLineArray(); +//} + + +void +BControlLook::_FillGradient(BView* view, const BRect& rect, + const rgb_color& base, float topTint, float bottomTint, + enum 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, enum 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, + enum 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, + enum 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()); +} + + +bool +BControlLook::_RadioButtonAndCheckBoxMarkColor(const rgb_color& base, + rgb_color& color, uint32 flags) const +{ + if ((flags & (B_ACTIVATED | B_CLICKED)) == 0) { + // no mark to be drawn at all + return false; + } + + // TODO: Get from UI settings + color.red = 27; + color.green = 82; + color.blue = 140; + + float mix = 1.0; + + if (flags & B_DISABLED) { + // activated, but disabled + mix = 0.4; + } else if (flags & B_CLICKED) { + if (flags & B_ACTIVATED) { + // loosing activation + mix = 0.7; + } else { + // becoming activated + mix = 0.3; + } + } 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; +} + + +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, + enum 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); +} + + +void +BControlLook::_DrawRoundCornerLeftTop(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, const rgb_color& edgeColor, + const rgb_color& frameColor, const rgb_color& bevelColor, + const BGradientLinear& fillGradient) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + BRegion clipping(rect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(base); + view->FillRect(rect); + + // outer edge + BRect ellipseRect(rect); + 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); + view->SetHighColor(frameColor); + view->FillEllipse(ellipseRect); + + // bevel + ellipseRect.InsetBy(1, 1); + view->SetHighColor(bevelColor); + view->FillEllipse(ellipseRect); + + // fill + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); + + view->ConstrainClippingRegion(NULL); +} + +void +BControlLook::_DrawRoundCornerRightTop(BView* view, BRect& rect, + const BRect& updateRect, const rgb_color& base, + 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) +{ + if (!rect.IsValid() || !rect.Intersects(updateRect)) + return; + + BRegion clipping(rect); + view->ConstrainClippingRegion(&clipping); + + // background + view->SetHighColor(base); + view->FillRect(rect); + + // outer edge + BRect ellipseRect(rect); + 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(rect.LeftTop()); + gradient.SetEnd(rect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // frame + ellipseRect.InsetBy(1, 1); + rect.right--; + rect.top++; + if (frameTopColor == frameRightColor) { + view->SetHighColor(frameTopColor); + view->FillEllipse(ellipseRect); + } else { + gradient.SetColor(0, frameTopColor); + gradient.SetColor(1, frameRightColor); + gradient.SetStart(rect.LeftTop()); + gradient.SetEnd(rect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + } + + // bevel + ellipseRect.InsetBy(1, 1); + rect.right--; + rect.top++; + gradient.SetColor(0, bevelTopColor); + gradient.SetColor(1, bevelRightColor); + gradient.SetStart(rect.LeftTop()); + gradient.SetEnd(rect.RightBottom()); + view->FillEllipse(ellipseRect, gradient); + + // fill + ellipseRect.InsetBy(1, 1); + view->FillEllipse(ellipseRect, fillGradient); + + view->ConstrainClippingRegion(NULL); +} + + +// NOTE: May come from a add-on in the future. Initialized in +// InterfaceDefs.cpp +BControlLook* be_control_look = NULL; + +} // namespace BPrivate diff --git a/src/kits/interface/Dragger.cpp b/src/kits/interface/Dragger.cpp index a45c32aa69..536dfa8453 100644 --- a/src/kits/interface/Dragger.cpp +++ b/src/kits/interface/Dragger.cpp @@ -167,6 +167,12 @@ BDragger::Draw(BRect update) // TODO: should draw it differently ? } } else if (IsVisibilityChanging()) { + +//uint32 flags = Parent()->Flags(); +//Parent()->SetFlags(flags | B_DRAW_ON_CHILDREN); +//Parent()->Draw(Frame()); +//Parent()->SetFlags(flags); + if (Parent()) Parent()->Invalidate(Frame()); @@ -204,7 +210,7 @@ BDragger::MouseDown(BPoint where) while (true) { BPoint mousePoint; - GetMouse(&mousePoint, &buttons); + GetMouse(&mousePoint, &buttons, false); if (!buttons || system_time() > time + clickSpeed) break; @@ -226,10 +232,10 @@ BDragger::MouseDown(BPoint where) Archive(&archive); else { if (fTarget->Archive(&archive)) { - BMessage widget(B_ARCHIVED_OBJECT); + BMessage archivedSelf(B_ARCHIVED_OBJECT); - if (Archive(&widget)) - archive.AddMessage("__widget", &widget); + if (Archive(&archivedSelf)) + archive.AddMessage("__widget", &archivedSelf); } } @@ -280,7 +286,7 @@ BDragger::MessageReceived(BMessage *msg) // this code is used whenever the "are draggers drawn" option is changed if (fRelation == TARGET_IS_CHILD) { fTransition = true; - Invalidate(); + Draw(Bounds()); Flush(); fTransition = false; } else { diff --git a/src/kits/interface/InterfaceDefs.cpp b/src/kits/interface/InterfaceDefs.cpp index facac4d310..cd58464765 100644 --- a/src/kits/interface/InterfaceDefs.cpp +++ b/src/kits/interface/InterfaceDefs.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -932,6 +933,9 @@ _init_interface_kit_() if (status < B_OK) return status; + // TODO: Could support different themes here in the future. + be_control_look = new BControlLook(); + BPrivate::gWidthBuffer = new BPrivate::WidthBuffer; _init_global_fonts_(); @@ -958,6 +962,9 @@ _fini_interface_kit_() delete BPrivate::gWidthBuffer; BPrivate::gWidthBuffer = NULL; + delete be_control_look; + be_control_look = NULL; + // TODO: Anything else? return B_OK; diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index 48534a3771..5b87494199 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -55,6 +55,7 @@ MergeObject interface_kit.o : ColorControl.cpp ColorTools.cpp Control.cpp + ControlLook.cpp Deskbar.cpp Dragger.cpp Font.cpp diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 6f9808d637..e83bf6f1c7 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -926,6 +927,7 @@ BMenu::Draw(BRect updateRect) return; } + DrawBackground(updateRect); _DrawItems(updateRect); } @@ -1295,6 +1297,19 @@ BMenu::AddDynamicItem(add_state state) void BMenu::DrawBackground(BRect update) { + if (be_control_look != NULL) { + rgb_color base = sMenuInfo.background_color; + uint32 flags = 0; + if (!IsEnabled()) + flags |= BControlLook::B_DISABLED; + if (IsFocus()) + flags |= BControlLook::B_FOCUSED; + BRect rect = Bounds(); + be_control_look->DrawMenuBackground(this, rect, update, base); + + return; + } + rgb_color oldColor = HighColor(); SetHighColor(sMenuInfo.background_color); FillRect(Bounds() & update, B_SOLID_HIGH); @@ -1410,12 +1425,6 @@ BMenu::_Show(bool selectFirstItem) return false; } - // Move the BMenu to 1, 1, if it's attached to a BMenuWindow, - // (that means it's a BMenu, BMenuBars are attached to regular BWindows). - // This is needed to be able to draw the frame around the BMenu. - if (dynamic_cast(window) != NULL) - MoveTo(1, 1); - _UpdateWindowViewSize(true); window->Show(); @@ -2584,19 +2593,19 @@ BMenu::_UpdateWindowViewSize(bool updatePosition) if (fItems.CountItems() > 0) { if (!scroll) { - window->ResizeTo(Bounds().Width() + 2, Bounds().Height() + 2); + window->ResizeTo(Bounds().Width(), Bounds().Height()); } else { BScreen screen(window); // If we need scrolling, resize the window to fit the screen and // attach scrollers to our cached BMenuWindow. if (dynamic_cast(Supermenu()) == NULL) { - window->ResizeTo(Bounds().Width() + 2, screen.Frame().bottom); + window->ResizeTo(Bounds().Width(), screen.Frame().bottom); frame.top = 0; } else { // Or, in case our parent was a BMenuBar enable scrolling with // normal size. - window->ResizeTo(Bounds().Width() + 2, screen.Frame().bottom + window->ResizeTo(Bounds().Width(), screen.Frame().bottom - frame.top); } diff --git a/src/kits/interface/MenuBar.cpp b/src/kits/interface/MenuBar.cpp index e3e4f1db76..c2389e95dd 100644 --- a/src/kits/interface/MenuBar.cpp +++ b/src/kits/interface/MenuBar.cpp @@ -1,18 +1,20 @@ /* - * Copyright 2001-2007, Haiku, Inc. + * Copyright 2001-2009, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: * Marc Flerackers (mflerackers@androme.be) * Stefano Ceccherini (burton666@libero.it) + * Stephan Aßmus */ -#include - #include +#include + #include #include +#include #include #include #include @@ -149,6 +151,20 @@ BMenuBar::Draw(BRect updateRect) return; } + if (be_control_look != NULL) { + BRect rect(Bounds()); + rgb_color base = LowColor(); + uint32 flags = 0; + + be_control_look->DrawBorder(this, rect, updateRect, base, + B_PLAIN_BORDER, flags, BControlLook::B_BOTTOM_BORDER); + + be_control_look->DrawMenuBarBackground(this, rect, updateRect, base); + + _DrawItems(updateRect); + return; + } + // TODO: implement additional border styles rgb_color color = HighColor(); diff --git a/src/kits/interface/MenuField.cpp b/src/kits/interface/MenuField.cpp index f2eb2c586e..4395c7bcc7 100644 --- a/src/kits/interface/MenuField.cpp +++ b/src/kits/interface/MenuField.cpp @@ -8,13 +8,15 @@ * Ingo Weinhold */ +#include + #include #include #include +#include #include #include -#include #include #include #include @@ -259,15 +261,24 @@ void BMenuField::Draw(BRect update) { BRect bounds(Bounds()); - bool active = false; - - if (IsFocus()) - active = Window()->IsActive(); + bool active = IsFocus() && Window()->IsActive(); DrawLabel(bounds, update); BRect frame(fMenuBar->Frame()); + if (be_control_look != NULL) { + frame.InsetBy(-kVMargin, -kVMargin); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = 0; + if (!fMenuBar->IsEnabled()) + flags |= BControlLook::B_DISABLED; + if (active) + flags |= BControlLook::B_FOCUSED; + be_control_look->DrawButtonFrame(this, frame, update, base, flags); + return; + } + if (frame.InsetByCopy(-kVMargin, -kVMargin).Intersects(update)) { SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); StrokeLine(BPoint(frame.left - 1.0f, frame.top - 1.0f), diff --git a/src/kits/interface/MenuItem.cpp b/src/kits/interface/MenuItem.cpp index b99f952a31..e92d184933 100644 --- a/src/kits/interface/MenuItem.cpp +++ b/src/kits/interface/MenuItem.cpp @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -478,27 +479,44 @@ BMenuItem::Draw() bool enabled = IsEnabled(); bool selected = IsSelected(); -// rgb_color noTint = ui_color(B_MENU_BACKGROUND_COLOR); -// TODO: the above is currently broken, because ui_color is -// not informed of changes to the app_server palette yet rgb_color noTint = fSuper->LowColor(); rgb_color bgColor = noTint; + if (be_control_look != NULL) + fSuper->SetDrawingMode(B_OP_OVER); + // set low color and fill background if selected - if (selected && (enabled || Submenu()) /*&& fSuper->fRedrawAfterSticky*/) { -// bgColor = ui_color(B_MENU_SELECTED_BACKGROUND_COLOR); -// see above + bool activated = selected && (enabled || Submenu()) + /*&& fSuper->fRedrawAfterSticky*/; + if (activated) { bgColor = tint_color(bgColor, B_DARKEN_3_TINT); + if (be_control_look != NULL) { + BRect rect = Frame(); + be_control_look->DrawMenuItemBackground(fSuper, rect, rect, + noTint, BControlLook::B_ACTIVATED); + } else { + fSuper->SetLowColor(bgColor); + fSuper->FillRect(Frame(), B_SOLID_LOW); + } + } else { fSuper->SetLowColor(bgColor); - fSuper->FillRect(Frame(), B_SOLID_LOW); - } else - fSuper->SetLowColor(bgColor); + } // set high color - if (enabled) - fSuper->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); - else - fSuper->SetHighColor(tint_color(bgColor, B_DISABLED_LABEL_TINT)); + if (be_control_look != NULL) { + if (enabled) { + fSuper->SetHighColor(tint_color(fSuper->LowColor(), + B_DARKEN_MAX_TINT)); + } else { + fSuper->SetHighColor(tint_color(fSuper->LowColor(), + B_DISABLED_LABEL_TINT)); + } + } else { + if (enabled) + fSuper->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR)); + else + fSuper->SetHighColor(tint_color(bgColor, B_DISABLED_LABEL_TINT)); + } // draw content fSuper->MovePenTo(ContentLocation()); @@ -719,9 +737,6 @@ BMenuItem::_DrawMarkSymbol(rgb_color bgColor) r.left = floorf(center.x - size / 2 + 0.5); r.right = floorf(center.x + size / 2 + 0.5); - fSuper->SetHighColor(tint_color(bgColor, kLightBGTint)); - fSuper->FillRoundRect(r, 2, 2); - BShape arrowShape; center.x += 0.5; center.y += 0.5; @@ -819,9 +834,6 @@ BMenuItem::_DrawSubmenuSymbol(rgb_color bgColor) r.left = floorf(center.x - size / 2 + 0.5); r.right = floorf(center.x + size / 2 + 0.5); - fSuper->SetHighColor(tint_color(bgColor, kLightBGTint)); - fSuper->FillRoundRect(r, 2, 2); - BShape arrowShape; center.x += 0.5; center.y += 0.5; diff --git a/src/kits/interface/MenuWindow.cpp b/src/kits/interface/MenuWindow.cpp index 64463cd235..b59a695689 100644 --- a/src/kits/interface/MenuWindow.cpp +++ b/src/kits/interface/MenuWindow.cpp @@ -9,11 +9,12 @@ //! BMenuWindow is a custom BWindow for BMenus. +#include + +#include #include #include - #include -#include #include @@ -194,15 +195,22 @@ void BMenuFrame::Draw(BRect updateRect) { if (fMenu != NULL && fMenu->CountItems() == 0) { - // TODO: Review this as it's a bit hacky. - // Menu has a size of 0, 0, since there are no items in it. - // So the BMenuFrame class has to fake it and draw an empty item. - // Note that we can't add a real "empty" item because then we couldn't - // tell if the item was added by us or not. - // See also BMenu::UpdateWindowViewSize() - SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR)); - SetLowColor(HighColor()); - FillRect(updateRect); + if (be_control_look != NULL) { + BRect rect(Bounds()); + be_control_look->DrawMenuBackground(this, rect, updateRect, + ui_color(B_MENU_BACKGROUND_COLOR)); + SetDrawingMode(B_OP_OVER); + } else { + // TODO: Review this as it's a bit hacky. + // Menu has a size of 0, 0, since there are no items in it. + // So the BMenuFrame class has to fake it and draw an empty item. + // Note that we can't add a real "empty" item because then we couldn't + // tell if the item was added by us or not. + // See also BMenu::UpdateWindowViewSize() + SetHighColor(ui_color(B_MENU_BACKGROUND_COLOR)); + SetLowColor(HighColor()); + FillRect(updateRect); + } font_height height; GetFontHeight(&height); @@ -211,7 +219,10 @@ BMenuFrame::Draw(BRect updateRect) DrawString(kEmptyMenuLabel, where); } - SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); + if (be_control_look != NULL) + return; + + SetHighColor(tint_color(ui_color(B_MENU_BACKGROUND_COLOR), B_DARKEN_2_TINT)); BRect bounds(Bounds()); StrokeLine(BPoint(bounds.right, bounds.top), @@ -234,6 +245,7 @@ BMenuWindow::BMenuWindow(const char *name) fUpperScroller(NULL), fLowerScroller(NULL) { + SetSizeLimits(2, 10000, 2, 10000); } @@ -375,7 +387,7 @@ BMenuWindow::_Scroll(const BPoint &where) } else return false; - snooze(10000); + snooze(5000); return true; } diff --git a/src/kits/interface/RadioButton.cpp b/src/kits/interface/RadioButton.cpp index 6efdb141d0..827179e376 100644 --- a/src/kits/interface/RadioButton.cpp +++ b/src/kits/interface/RadioButton.cpp @@ -15,6 +15,7 @@ #include +#include #include #include #include @@ -87,6 +88,27 @@ BRadioButton::Draw(BRect updateRect) // its size depends on the text height font_height fontHeight; GetFontHeight(&fontHeight); + + if (be_control_look) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + + uint32 flags = be_control_look->Flags(this); + if (fOutlined) + flags |= BControlLook::B_CLICKED; + + BRect knobRect(_KnobFrame(fontHeight)); + BRect rect(knobRect); + be_control_look->DrawRadioButton(this, rect, updateRect, base, flags); + + BRect labelRect(Bounds()); + labelRect.left = knobRect.right + + be_control_look->DefaultLabelSpacing(); + + be_control_look->DrawLabel(this, Label(), labelRect, updateRect, + base, flags); + return; + } + float textHeight = ceilf(fontHeight.ascent + fontHeight.descent); // layout the rect for the dot @@ -573,6 +595,12 @@ BRadioButton::_KnobFrame() const BRect BRadioButton::_KnobFrame(const font_height& fontHeight) const { + if (be_control_look != NULL) { + // Same as BCheckBox... + return BRect(0.0f, 2.0f, ceilf(3.0f + fontHeight.ascent), + ceilf(5.0f + fontHeight.ascent)); + } + // layout the rect for the dot BRect rect(Bounds()); diff --git a/src/kits/interface/ScrollBar.cpp b/src/kits/interface/ScrollBar.cpp index 7214ce0e00..dbb363a2d1 100644 --- a/src/kits/interface/ScrollBar.cpp +++ b/src/kits/interface/ScrollBar.cpp @@ -12,6 +12,7 @@ #include +#include #include #include #include @@ -74,6 +75,7 @@ public: fStopValue(0.0), fUpArrowsEnabled(true), fDownArrowsEnabled(true), + fBorderHighlighted(false), fButtonDown(NOARROW) { #ifdef TEST_MODE @@ -123,6 +125,8 @@ public: bool fUpArrowsEnabled; bool fDownArrowsEnabled; + bool fBorderHighlighted; + int8 fButtonDown; }; @@ -584,6 +588,26 @@ BScrollBar::Orientation() const } +status_t +BScrollBar::SetBorderHighlighted(bool state) +{ + if (fPrivateData->fBorderHighlighted == state) + return B_OK; + + fPrivateData->fBorderHighlighted = state; + + BRect dirty(Bounds()); + if (fOrientation == B_HORIZONTAL) + dirty.bottom = dirty.top; + else + dirty.right = dirty.left; + + Invalidate(dirty); + + return B_OK; +} + + void BScrollBar::MessageReceived(BMessage* message) { @@ -751,8 +775,33 @@ BScrollBar::Draw(BRect updateRect) // stroke a dark frame arround the entire scrollbar // (independent of enabled state) + // take care of border highlighting (scroll target is focus view) SetHighColor(tint_color(normal, B_DARKEN_2_TINT)); - StrokeRect(bounds); + if (fPrivateData->fBorderHighlighted && fPrivateData->fEnabled) { + rgb_color borderColor = HighColor(); + rgb_color highlightColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); + BeginLineArray(4); + AddLine(BPoint(bounds.left + 1, bounds.bottom), + BPoint(bounds.right, bounds.bottom), borderColor); + AddLine(BPoint(bounds.right, bounds.top + 1), + BPoint(bounds.right, bounds.bottom - 1), borderColor); + if (fOrientation == B_HORIZONTAL) { + AddLine(BPoint(bounds.left, bounds.top + 1), + BPoint(bounds.left, bounds.bottom), borderColor); + } else { + AddLine(BPoint(bounds.left, bounds.top), + BPoint(bounds.left, bounds.bottom), highlightColor); + } + if (fOrientation == B_HORIZONTAL) { + AddLine(BPoint(bounds.left, bounds.top), + BPoint(bounds.right, bounds.top), highlightColor); + } else { + AddLine(BPoint(bounds.left + 1, bounds.top), + BPoint(bounds.right, bounds.top), borderColor); + } + EndLineArray(); + } else + StrokeRect(bounds); bounds.InsetBy(1.0, 1.0); bool enabled = fPrivateData->fEnabled && fMin < fMax @@ -842,163 +891,176 @@ BScrollBar::Draw(BRect updateRect) // background for thumb area BRect rect(fPrivateData->fThumbFrame); - // frame - if (fOrientation == B_HORIZONTAL) { - int32 totalLines = 0; - if (rect.left > thumbBG.left) - totalLines += 1; - if (rect.left > thumbBG.left + 1) - totalLines += 3; - if (rect.right < thumbBG.right - 1) - totalLines += 3; - if (rect.right < thumbBG.right) - totalLines += 1; - - if (totalLines > 0) { - BeginLineArray(totalLines); - if (rect.left > thumbBG.left) { - AddLine(BPoint(thumbBG.left, thumbBG.bottom), - BPoint(thumbBG.left, thumbBG.top), - rect.left > thumbBG.left + 1 ? dark4 : dark); - } - if (rect.left > thumbBG.left + 1) { - AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1), - BPoint(thumbBG.left + 1, thumbBG.bottom), dark2); - AddLine(BPoint(thumbBG.left + 1, thumbBG.top), - BPoint(rect.left - 1, thumbBG.top), dark2); - AddLine(BPoint(rect.left - 1, thumbBG.bottom), - BPoint(thumbBG.left + 2, thumbBG.bottom), normal); - } - - if (rect.right < thumbBG.right - 1) { - AddLine(BPoint(rect.right + 2, thumbBG.top + 1), - BPoint(rect.right + 2, thumbBG.bottom), dark2); - AddLine(BPoint(rect.right + 1, thumbBG.top), - BPoint(thumbBG.right, thumbBG.top), dark2); - AddLine(BPoint(thumbBG.right - 1, thumbBG.bottom), - BPoint(rect.right + 3, thumbBG.bottom), normal); - } - if (rect.right < thumbBG.right) { - AddLine(BPoint(thumbBG.right, thumbBG.top), - BPoint(thumbBG.right, thumbBG.bottom), dark); - } + if (be_control_look == NULL) { + if (fOrientation == B_HORIZONTAL) { + BeginLineArray(8); + + if (rect.left > thumbBG.left) { + AddLine(BPoint(thumbBG.left, thumbBG.bottom), + BPoint(thumbBG.left, thumbBG.top), + rect.left > thumbBG.left + 1 ? dark4 : dark); + } + if (rect.left > thumbBG.left + 1) { + AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1), + BPoint(thumbBG.left + 1, thumbBG.bottom), dark2); + AddLine(BPoint(thumbBG.left + 1, thumbBG.top), + BPoint(rect.left - 1, thumbBG.top), dark2); + AddLine(BPoint(rect.left - 1, thumbBG.bottom), + BPoint(thumbBG.left + 2, thumbBG.bottom), normal); + } + + if (rect.right < thumbBG.right - 1) { + AddLine(BPoint(rect.right + 2, thumbBG.top + 1), + BPoint(rect.right + 2, thumbBG.bottom), dark2); + AddLine(BPoint(rect.right + 1, thumbBG.top), + BPoint(thumbBG.right, thumbBG.top), dark2); + AddLine(BPoint(thumbBG.right - 1, thumbBG.bottom), + BPoint(rect.right + 3, thumbBG.bottom), normal); + } + if (rect.right < thumbBG.right) { + AddLine(BPoint(thumbBG.right, thumbBG.top), + BPoint(thumbBG.right, thumbBG.bottom), dark); + } + EndLineArray(); - } - } else { - int32 totalLines = 0; - if (rect.top > thumbBG.top) - totalLines += 1; - if (rect.top > thumbBG.top + 1) - totalLines += 3; - if (rect.bottom < thumbBG.bottom - 1) - totalLines += 3; - if (rect.bottom < thumbBG.bottom) - totalLines += 1; - - if (totalLines > 0) { - BeginLineArray(totalLines); - if (rect.top > thumbBG.top) { - AddLine(BPoint(thumbBG.left, thumbBG.top), - BPoint(thumbBG.right, thumbBG.top), - rect.top > thumbBG.top + 1 ? dark4 : dark); - } - if (rect.top > thumbBG.top + 1) { - AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1), - BPoint(thumbBG.right, thumbBG.top + 1), dark2); - AddLine(BPoint(thumbBG.left, rect.top - 1), - BPoint(thumbBG.left, thumbBG.top + 1), dark2); - AddLine(BPoint(thumbBG.right, rect.top - 1), - BPoint(thumbBG.right, thumbBG.top + 2), normal); - } - - if (rect.bottom < thumbBG.bottom - 1) { - AddLine(BPoint(thumbBG.left + 1, rect.bottom + 2), - BPoint(thumbBG.right, rect.bottom + 2), dark2); - AddLine(BPoint(thumbBG.left, rect.bottom + 1), - BPoint(thumbBG.left, thumbBG.bottom - 1), dark2); - AddLine(BPoint(thumbBG.right, rect.bottom + 3), - BPoint(thumbBG.right, thumbBG.bottom - 1), normal); - } - if (rect.bottom < thumbBG.bottom) { - AddLine(BPoint(thumbBG.left, thumbBG.bottom), - BPoint(thumbBG.right, thumbBG.bottom), dark); - } + } else { + BeginLineArray(8); + + if (rect.top > thumbBG.top) { + AddLine(BPoint(thumbBG.left, thumbBG.top), + BPoint(thumbBG.right, thumbBG.top), + rect.top > thumbBG.top + 1 ? dark4 : dark); + } + if (rect.top > thumbBG.top + 1) { + AddLine(BPoint(thumbBG.left + 1, thumbBG.top + 1), + BPoint(thumbBG.right, thumbBG.top + 1), dark2); + AddLine(BPoint(thumbBG.left, rect.top - 1), + BPoint(thumbBG.left, thumbBG.top + 1), dark2); + AddLine(BPoint(thumbBG.right, rect.top - 1), + BPoint(thumbBG.right, thumbBG.top + 2), normal); + } + + if (rect.bottom < thumbBG.bottom - 1) { + AddLine(BPoint(thumbBG.left + 1, rect.bottom + 2), + BPoint(thumbBG.right, rect.bottom + 2), dark2); + AddLine(BPoint(thumbBG.left, rect.bottom + 1), + BPoint(thumbBG.left, thumbBG.bottom - 1), dark2); + AddLine(BPoint(thumbBG.right, rect.bottom + 3), + BPoint(thumbBG.right, thumbBG.bottom - 1), normal); + } + if (rect.bottom < thumbBG.bottom) { + AddLine(BPoint(thumbBG.left, thumbBG.bottom), + BPoint(thumbBG.right, thumbBG.bottom), dark); + } + EndLineArray(); } } - SetHighColor(dark1); + if (be_control_look != NULL) { + uint32 flags = 0; + if (!enabled) + flags |= BControlLook::B_DISABLED; + + // fill background besides the thumb + if (fOrientation == B_HORIZONTAL) { + BRect leftOfThumb(thumbBG.left, thumbBG.top, rect.left - 1, + thumbBG.bottom); + BRect rightOfThumb(rect.right + 1, thumbBG.top, thumbBG.right, + thumbBG.bottom); + + be_control_look->DrawScrollBarBackground(this, leftOfThumb, + rightOfThumb, updateRect, normal, flags, fOrientation); + } else { + BRect topOfThumb(thumbBG.left, thumbBG.top, + thumbBG.right, rect.top - 1); + + BRect bottomOfThumb(thumbBG.left, rect.bottom + 1, + thumbBG.right, thumbBG.bottom); + + be_control_look->DrawScrollBarBackground(this, topOfThumb, + bottomOfThumb, updateRect, normal, flags, fOrientation); + } + } + // Draw scroll thumb if (enabled) { - // fill and additional dark lines - thumbBG.InsetBy(1.0, 1.0); - if (fOrientation == B_HORIZONTAL) { - BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, - thumbBG.bottom); - if (leftOfThumb.IsValid()) - FillRect(leftOfThumb); - - BRect rightOfThumb(rect.right + 3, thumbBG.top, thumbBG.right, - thumbBG.bottom); - if (rightOfThumb.IsValid()) - FillRect(rightOfThumb); - - // dark lines before and after thumb - if (rect.left > thumbBG.left) { - SetHighColor(dark); - StrokeLine(BPoint(rect.left - 1, rect.top), - BPoint(rect.left - 1, rect.bottom)); - } - if (rect.right < thumbBG.right) { - SetHighColor(dark4); - StrokeLine(BPoint(rect.right + 1, rect.top), - BPoint(rect.right + 1, rect.bottom)); - } - } else { - BRect topOfThumb(thumbBG.left, thumbBG.top + 1, - thumbBG.right, rect.top - 1); - if (topOfThumb.IsValid()) - FillRect(topOfThumb); - - BRect bottomOfThumb(thumbBG.left, rect.bottom + 3, - thumbBG.right, thumbBG.bottom); - if (bottomOfThumb.IsValid()) - FillRect(bottomOfThumb); - - // dark lines before and after thumb - if (rect.top > thumbBG.top) { - SetHighColor(dark); - StrokeLine(BPoint(rect.left, rect.top - 1), - BPoint(rect.right, rect.top - 1)); - } - if (rect.bottom < thumbBG.bottom) { - SetHighColor(dark4); - StrokeLine(BPoint(rect.left, rect.bottom + 1), - BPoint(rect.right, rect.bottom + 1)); + if (be_control_look == NULL) { + // fill and additional dark lines + thumbBG.InsetBy(1.0, 1.0); + if (fOrientation == B_HORIZONTAL) { + BRect leftOfThumb(thumbBG.left + 1, thumbBG.top, rect.left - 1, + thumbBG.bottom); + if (leftOfThumb.IsValid()) + FillRect(leftOfThumb); + + BRect rightOfThumb(rect.right + 3, thumbBG.top, thumbBG.right, + thumbBG.bottom); + if (rightOfThumb.IsValid()) + FillRect(rightOfThumb); + + // dark lines before and after thumb + if (rect.left > thumbBG.left) { + SetHighColor(dark); + StrokeLine(BPoint(rect.left - 1, rect.top), + BPoint(rect.left - 1, rect.bottom)); + } + if (rect.right < thumbBG.right) { + SetHighColor(dark4); + StrokeLine(BPoint(rect.right + 1, rect.top), + BPoint(rect.right + 1, rect.bottom)); + } + } else { + BRect topOfThumb(thumbBG.left, thumbBG.top + 1, + thumbBG.right, rect.top - 1); + if (topOfThumb.IsValid()) + FillRect(topOfThumb); + + BRect bottomOfThumb(thumbBG.left, rect.bottom + 3, + thumbBG.right, thumbBG.bottom); + if (bottomOfThumb.IsValid()) + FillRect(bottomOfThumb); + + // dark lines before and after thumb + if (rect.top > thumbBG.top) { + SetHighColor(dark); + StrokeLine(BPoint(rect.left, rect.top - 1), + BPoint(rect.right, rect.top - 1)); + } + if (rect.bottom < thumbBG.bottom) { + SetHighColor(dark4); + StrokeLine(BPoint(rect.left, rect.bottom + 1), + BPoint(rect.right, rect.bottom + 1)); + } } } - BeginLineArray(4); - AddLine(BPoint(rect.left, rect.bottom), - BPoint(rect.left, rect.top), light); - AddLine(BPoint(rect.left + 1, rect.top), - BPoint(rect.right, rect.top), light); - AddLine(BPoint(rect.right, rect.top + 1), - BPoint(rect.right, rect.bottom), dark1); - AddLine(BPoint(rect.right - 1, rect.bottom), - BPoint(rect.left + 1, rect.bottom), dark1); - EndLineArray(); - - // fill - rect.InsetBy(1.0, 1.0); - /*if (fPrivateData->fButtonDown == THUMB) - SetHighColor(tint_color(normal, (B_NO_TINT + B_DARKEN_1_TINT) / 2)); - else*/ - SetHighColor(normal); - - FillRect(rect); - + // fill the clickable surface of the thumb + if (be_control_look) { + be_control_look->DrawButtonBackground(this, rect, updateRect, + normal, 0, BControlLook::B_ALL_BORDERS, fOrientation); + } else { + BeginLineArray(4); + AddLine(BPoint(rect.left, rect.bottom), + BPoint(rect.left, rect.top), light); + AddLine(BPoint(rect.left + 1, rect.top), + BPoint(rect.right, rect.top), light); + AddLine(BPoint(rect.right, rect.top + 1), + BPoint(rect.right, rect.bottom), dark1); + AddLine(BPoint(rect.right - 1, rect.bottom), + BPoint(rect.left + 1, rect.bottom), dark1); + EndLineArray(); + + // fill + rect.InsetBy(1.0, 1.0); + /*if (fPrivateData->fButtonDown == THUMB) + SetHighColor(tint_color(normal, (B_NO_TINT + B_DARKEN_1_TINT) / 2)); + else*/ + SetHighColor(normal); + + FillRect(rect); + } // TODO: Add the other thumb styles - dots and lines } else { if (fMin >= fMax || fProportion >= 1.0 || fProportion < 0.0) { @@ -1708,8 +1770,18 @@ BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r, } r.InsetBy(-(hInset - 1), -(vInset - 1)); - SetHighColor(normal); - FillRect(r); + if (be_control_look != NULL) { + BRect temp(r.InsetByCopy(-1, -1)); + uint32 flags = 0; + if (down) + flags |= BControlLook::B_ACTIVATED; + be_control_look->DrawButtonBackground(this, temp, updateRect, + down ? c : normal, flags, BControlLook::B_ALL_BORDERS, + fOrientation); + } else { + SetHighColor(normal); + FillRect(r); + } BShape arrowShape; arrowShape.MoveTo(tri1); @@ -1721,6 +1793,9 @@ BScrollBar::_DrawArrowButton(int32 direction, bool doubleArrows, BRect r, StrokeShape(&arrowShape); SetPenSize(1.0); + if (be_control_look != NULL) + return; + r.InsetBy(-1, -1); BeginLineArray(4); if (direction == ARROW_LEFT || direction == ARROW_RIGHT) { diff --git a/src/kits/interface/ScrollView.cpp b/src/kits/interface/ScrollView.cpp index 86f2e0c401..7bb8bad990 100644 --- a/src/kits/interface/ScrollView.cpp +++ b/src/kits/interface/ScrollView.cpp @@ -2,12 +2,14 @@ * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved. * Distributed under the terms of the MIT License. */ +#include #include +#include #include -#include #include +#include #include #include @@ -90,6 +92,9 @@ BScrollView::_Init(bool horizontal, bool vertical) fVerticalScrollBar = NULL; fHighlighted = false; + if (be_control_look != NULL) + SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); + BRect targetFrame; if (fTarget) { // layout target and add it @@ -218,6 +223,43 @@ BScrollView::AllDetached() void BScrollView::Draw(BRect updateRect) { + if (be_control_look != NULL) { + uint32 flags = 0; + if (fHighlighted && Window()->IsActive()) + flags |= BControlLook::B_FOCUSED; + BRect rect(Bounds()); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + if (fBorder == B_FANCY_BORDER + && fHorizontalScrollBar && fVerticalScrollBar) { + BRect scrollCornerRect(rect); + scrollCornerRect.left = fHorizontalScrollBar->Frame().right + 2; + scrollCornerRect.top = fVerticalScrollBar->Frame().bottom + 2; + BRegion region(rect); + region.Exclude(scrollCornerRect); + ConstrainClippingRegion(®ion); + } + + be_control_look->DrawBorder(this, rect, updateRect, base, fBorder, + flags); + + if (fBorder == B_FANCY_BORDER + && fHorizontalScrollBar && fVerticalScrollBar) { + ConstrainClippingRegion(NULL); + + rect = Bounds().InsetByCopy(1, 1); + rect.right = fHorizontalScrollBar->Frame().right + 1; + be_control_look->DrawBorder(this, rect, updateRect, base, fBorder, + flags, BControlLook::B_RIGHT_BORDER); + + rect = Bounds().InsetByCopy(1, 1); + rect.bottom = fVerticalScrollBar->Frame().bottom + 1; + be_control_look->DrawBorder(this, rect, updateRect, base, fBorder, + flags, BControlLook::B_BOTTOM_BORDER); + } + + return; + } + if (fBorder == B_PLAIN_BORDER) { SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), B_DARKEN_2_TINT)); StrokeRect(Bounds()); @@ -339,7 +381,15 @@ BScrollView::SetBorderHighlighted(bool state) fHighlighted = state; + if (fHorizontalScrollBar != NULL) + fHorizontalScrollBar->SetBorderHighlighted(state); + if (fVerticalScrollBar != NULL) + fVerticalScrollBar->SetBorderHighlighted(state); + BRect bounds = Bounds(); + if (be_control_look != NULL) + bounds.InsetBy(1, 1); + Invalidate(BRect(bounds.left, bounds.top, bounds.right, bounds.top)); Invalidate(BRect(bounds.left, bounds.top + 1, bounds.left, bounds.bottom - 1)); @@ -444,11 +494,22 @@ BScrollView::FrameResized(float width, float height) if (fBorder == B_NO_BORDER) return; - // changes in width - BRect bounds = Bounds(); float border = _BorderSize() - 1; + if (be_control_look && fHorizontalScrollBar && fVerticalScrollBar) { + BRect scrollCorner(bounds); + scrollCorner.left = min_c( + fPreviousWidth - fVerticalScrollBar->Frame().Height(), + fHorizontalScrollBar->Frame().right + 1); + scrollCorner.top = min_c( + fPreviousHeight - fHorizontalScrollBar->Frame().Width(), + fVerticalScrollBar->Frame().bottom + 1); + Invalidate(scrollCorner); + } + + // changes in width + if (bounds.Width() > fPreviousWidth) { // invalidate the region between the old and the new right border BRect rect = bounds; diff --git a/src/kits/interface/Slider.cpp b/src/kits/interface/Slider.cpp index 8ea1d652f9..cba554881e 100644 --- a/src/kits/interface/Slider.cpp +++ b/src/kits/interface/Slider.cpp @@ -16,6 +16,7 @@ #include #include +#include #include #include #include @@ -48,10 +49,7 @@ BSlider::BSlider(BRect frame, const char* name, const char* label, fOrientation(B_HORIZONTAL), fBarThickness(6.0) { - SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), - B_DARKEN_4_TINT)); - - UseFillColor(false, NULL); + _InitBarColor(); _InitObject(); SetValue(0); @@ -81,10 +79,7 @@ BSlider::BSlider(BRect frame, const char *name, const char *label, fOrientation(posture), fBarThickness(6.0) { - SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), - B_DARKEN_4_TINT)); - - UseFillColor(false, NULL); + _InitBarColor(); _InitObject(); SetValue(0); @@ -113,10 +108,7 @@ BSlider::BSlider(const char *name, const char *label, BMessage *message, fOrientation(posture), fBarThickness(6.0) { - SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), - B_DARKEN_4_TINT)); - - UseFillColor(false, NULL); + _InitBarColor(); _InitObject(); SetValue(0); @@ -212,6 +204,21 @@ BSlider::~BSlider() } +void +BSlider::_InitBarColor() +{ + if (be_control_look != NULL) { + SetBarColor(be_control_look->SliderBarColor( + ui_color(B_PANEL_BACKGROUND_COLOR))); + } else { + SetBarColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), + B_DARKEN_4_TINT)); + } + + UseFillColor(false, NULL); +} + + void BSlider::_InitObject() { @@ -791,8 +798,17 @@ BSlider::Draw(BRect updateRect) // ToDo: the triangle thumb doesn't delete its background, so we still have // to do it Note, this also creates a different behaviour for subclasses, // depending on the thumb style - if possible this should be avoided. - if (Style() == B_BLOCK_THUMB) - background.Exclude(ThumbFrame()); + if (Style() == B_BLOCK_THUMB) { + BRect thumbFrame = ThumbFrame(); + if (be_control_look != NULL) { + // fill background where shadow will be... + // TODO: Such drawint dependent behavior should be moved into + // BControlLook of course. + thumbFrame.right--; + thumbFrame.bottom--; + } + background.Exclude(thumbFrame); + } #if USE_OFF_SCREEN_VIEW if (!fOffScreenBits) @@ -849,6 +865,16 @@ BSlider::DrawBar() BRect frame = BarFrame(); BView *view = OffscreenView(); + if (be_control_look != NULL) { + uint32 flags = be_control_look->Flags(this); + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + rgb_color rightFillColor = fBarColor; + rgb_color leftFillColor = fUseFillColor ? fFillColor : fBarColor; + be_control_look->DrawSliderBar(view, frame, frame, base, leftFillColor, + rightFillColor, Position(), flags, fOrientation); + return; + } + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lightenmax; rgb_color darken1; @@ -974,6 +1000,14 @@ BSlider::DrawHashMarks() BRect frame = HashMarksFrame(); BView* view = OffscreenView(); + if (be_control_look) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = be_control_look->Flags(this); + be_control_look->DrawSliderHashMarks(view, frame, frame, base, + fHashMarkCount, fHashMarks, flags, fOrientation); + return; + } + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lightenmax; rgb_color darken2; @@ -1685,6 +1719,14 @@ BSlider::_DrawBlockThumb() BRect frame = ThumbFrame(); BView *view = OffscreenView(); + if (be_control_look != NULL) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = be_control_look->Flags(this); + be_control_look->DrawSliderThumb(view, frame, frame, base, flags, + fOrientation); + return; + } + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lighten2; rgb_color lighten1; @@ -1811,6 +1853,14 @@ BSlider::_DrawTriangleThumb() BRect frame = ThumbFrame(); BView *view = OffscreenView(); + if (be_control_look != NULL) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = be_control_look->Flags(this); + be_control_look->DrawSliderTriangle(view, frame, frame, base, flags, + fOrientation); + return; + } + rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lightenmax; rgb_color lighten1; diff --git a/src/kits/interface/StatusBar.cpp b/src/kits/interface/StatusBar.cpp index b9730ba590..7ac44160bb 100644 --- a/src/kits/interface/StatusBar.cpp +++ b/src/kits/interface/StatusBar.cpp @@ -15,11 +15,11 @@ #include #include -#include -#include - +#include #include #include +#include +#include #include @@ -265,6 +265,12 @@ BStatusBar::Draw(BRect updateRect) rect = outerFrame; + if (be_control_look != NULL) { + be_control_look->DrawStatusBar(this, rect, updateRect, + backgroundColor, fBarColor, _BarPosition(barFrame)); + return; + } + // First bevel SetHighColor(tint_color(ui_color ( B_PANEL_BACKGROUND_COLOR ), B_DARKEN_1_TINT)); StrokeLine(rect.LeftBottom(), rect.LeftTop()); @@ -411,6 +417,10 @@ BStatusBar::SetTo(float value, const char* text, const char* trailingText) update.right = ceilf(oldPosition); } + // TODO: Ask the BControlLook in the first place about dirty rect. + if (be_control_look) + update.InsetBy(-1, -1); + Invalidate(update); } @@ -794,6 +804,7 @@ BStatusBar::_BarPosition(const BRect& barFrame) const if (fCurrent == 0) return barFrame.left - 1; - return roundf(barFrame.left + ceilf(fCurrent * barFrame.Width() / fMax)); + return roundf(barFrame.left - 1 + + (fCurrent * (barFrame.Width() + 3) / fMax)); } diff --git a/src/kits/interface/TabView.cpp b/src/kits/interface/TabView.cpp index 70c487f5d2..f6fc220572 100644 --- a/src/kits/interface/TabView.cpp +++ b/src/kits/interface/TabView.cpp @@ -14,12 +14,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include @@ -251,6 +253,7 @@ BTab::DrawLabel(BView *owner, BRect frame) owner->GetFontHeight(&fh); } + owner->SetDrawingMode(B_OP_OVER); owner->SetHighColor(ui_color(B_CONTROL_TEXT_COLOR)); owner->DrawString(label.String(), BPoint((frame.left + frame.right - width) / 2.0, @@ -263,6 +266,38 @@ void BTab::DrawTab(BView *owner, BRect frame, tab_position position, bool full) { rgb_color no_tint = ui_color(B_PANEL_BACKGROUND_COLOR); + + if (be_control_look != NULL) { +// uint32 borders = BControlLook::B_RIGHT_BORDER +// | BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER; +// if (frame.left == owner->Bounds().left) +// borders |= BControlLook::B_LEFT_BORDER; +// be_control_look->DrawButtonFrame(owner, frame, frame, +// no_tint, 0, borders); +// if (position == B_TAB_FRONT) +// no_tint = tint_color(no_tint, B_DARKEN_2_TINT); +// be_control_look->DrawButtonBackground(owner, frame, frame, no_tint); + + uint32 borders = BControlLook::B_TOP_BORDER + | BControlLook::B_BOTTOM_BORDER; + if (frame.left == owner->Bounds().left) + borders |= BControlLook::B_LEFT_BORDER; + if (frame.right == owner->Bounds().right) + borders |= BControlLook::B_RIGHT_BORDER; + + if (position == B_TAB_FRONT) { + frame.bottom += 1; + be_control_look->DrawActiveTab(owner, frame, frame, no_tint, 0, + borders); + } else { + be_control_look->DrawInctiveTab(owner, frame, frame, no_tint, 0, + borders); + } + + DrawLabel(owner, frame); + return; + } + rgb_color lightenmax = tint_color(no_tint, B_LIGHTEN_MAX_TINT); rgb_color darken2 = tint_color(no_tint, B_DARKEN_2_TINT); rgb_color darken3 = tint_color(no_tint, B_DARKEN_3_TINT); @@ -782,7 +817,11 @@ BTabView::FocusTab() const void BTabView::Draw(BRect updateRect) { - DrawBox(DrawTabs()); + if (be_control_look != NULL) { + DrawBox(TabFrame(fSelection)); + DrawTabs(); + } else + DrawBox(DrawTabs()); if (IsFocus() && fFocus != -1) TabAt(fFocus)->DrawFocusMark(this, TabFrame(fFocus)); @@ -792,10 +831,34 @@ BTabView::Draw(BRect updateRect) BRect BTabView::DrawTabs() { + if (be_control_look != NULL) { +// BRect rect(Bounds()); +// rect.bottom = rect.top + fTabHeight; +// rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); +// be_control_look->DrawButtonFrame(this, rect, rect, base); +// be_control_look->DrawButtonBackground(this, rect, rect, base); + } + + float left = 0; + for (int32 i = 0; i < CountTabs(); i++) { - TabAt(i)->DrawTab(this, TabFrame(i), + BRect tabFrame = TabFrame(i); + TabAt(i)->DrawTab(this, tabFrame, i == fSelection ? B_TAB_FRONT : (i == 0) ? B_TAB_FIRST : B_TAB_ANY, i + 1 != fSelection); + left = tabFrame.right; + } + + if (be_control_look != NULL) { + BRect frame(Bounds()); + frame.left = left; + frame.bottom = fTabHeight; + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 borders = BControlLook::B_TOP_BORDER + | BControlLook::B_BOTTOM_BORDER | BControlLook::B_RIGHT_BORDER; + if (left == 0) + borders |= BControlLook::B_LEFT_BORDER; + be_control_look->DrawInctiveTab(this, frame, frame, base, 0, borders); } if (fSelection < CountTabs()) @@ -808,6 +871,24 @@ BTabView::DrawTabs() void BTabView::DrawBox(BRect selTabRect) { + if (be_control_look != NULL) { + BRect rect(Bounds()); + rect.top = selTabRect.bottom; + +// BRegion clipping(Bounds()); +// selTabRect.left += 2; +// selTabRect.right -= 2; +// clipping.Exclude(selTabRect); +// ConstrainClippingRegion(&clipping); + + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + be_control_look->DrawGroupFrame(this, rect, rect, base); + +// ConstrainClippingRegion(NULL); + + return; + } + BRect rect = Bounds(); BRect lastTabRect = TabFrame(CountTabs() - 1); @@ -869,6 +950,38 @@ BTabView::DrawBox(BRect selTabRect) BRect BTabView::TabFrame(int32 tab_index) const { + if (be_control_look != NULL) { + float width = 100.0; + float height = fTabHeight;; + switch (fTabWidthSetting) { + case B_WIDTH_FROM_LABEL: + { + float x = 0.0; + for (int32 i = 0; i < tab_index; i++){ + x += StringWidth(TabAt(i)->Label()) + 20.0; + } + + return BRect(x, 0.0, + x + StringWidth(TabAt(tab_index)->Label()) + 20.0, + height); + } + + case B_WIDTH_FROM_WIDEST: + width = 0.0; + for (int32 i = 0; i < CountTabs(); i++) { + float tabWidth = StringWidth(TabAt(i)->Label()) + 20.0; + if (tabWidth > width) + width = tabWidth; + } + // fall through + + case B_WIDTH_AS_USUAL: + default: + return BRect(tab_index * width, 0.0, + tab_index * width + width, height); + } + } + // TODO: fix to remove "offset" in DrawTab and DrawLabel ... switch (fTabWidthSetting) { case B_WIDTH_FROM_LABEL: @@ -1128,7 +1241,8 @@ BTabView::ViewForTab(int32 tabIndex) const void BTabView::_InitObject(bool layouted, button_width width) { - SetFont(be_bold_font); + if (!be_control_look) + SetFont(be_bold_font); fTabList = new BList; @@ -1149,7 +1263,7 @@ BTabView::_InitObject(bool layouted, button_width width) if (layouted) { BGroupLayout* layout = new(std::nothrow) BGroupLayout(B_HORIZONTAL); if (layout) { - layout->SetInsets(3.0, 3.0 + TabHeight(), 3.0, 3.0); + layout->SetInsets(3.0, 3.0 + TabHeight() - 1, 3.0, 3.0); SetLayout(layout); } diff --git a/src/kits/interface/TextControl.cpp b/src/kits/interface/TextControl.cpp index c778429866..c7836c537a 100644 --- a/src/kits/interface/TextControl.cpp +++ b/src/kits/interface/TextControl.cpp @@ -10,12 +10,13 @@ /*! BTextControl displays text that can act like a control. */ +#include #include +#include #include #include #include -#include #include #include @@ -316,6 +317,34 @@ BTextControl::Divider() const void BTextControl::Draw(BRect updateRect) { + bool enabled = IsEnabled(); + bool active = fText->IsFocus() && Window()->IsActive(); + + BRect rect = fText->Frame(); + rect.InsetBy(-2, -2); + + if (be_control_look != NULL) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + uint32 flags = 0; + if (!enabled) + flags |= BControlLook::B_DISABLED; + if (active) + flags |= BControlLook::B_FOCUSED; + be_control_look->DrawTextControlBorder(this, rect, updateRect, base, + flags); + + rect = Bounds(); + rect.right = fDivider - kLabelInputSpacing; +// rect.right = fText->Frame().left - 2; +// rect.right -= 3;//be_control_look->DefaultLabelSpacing(); + be_control_look->DrawLabel(this, Label(), rect, updateRect, + base, flags, BAlignment(fLabelAlign, B_ALIGN_MIDDLE)); + + return; + } + + // outer bevel + rgb_color noTint = ui_color(B_PANEL_BACKGROUND_COLOR); rgb_color lighten1 = tint_color(noTint, B_LIGHTEN_1_TINT); rgb_color lighten2 = tint_color(noTint, B_LIGHTEN_2_TINT); @@ -325,17 +354,6 @@ BTextControl::Draw(BRect updateRect) rgb_color darken4 = tint_color(noTint, B_DARKEN_4_TINT); rgb_color navigationColor = ui_color(B_KEYBOARD_NAVIGATION_COLOR); - bool enabled = IsEnabled(); - bool active = false; - - if (fText->IsFocus() && Window()->IsActive()) - active = true; - - // outer bevel - - BRect rect = fText->Frame(); - rect.InsetBy(-2, -2); - if (enabled) SetHighColor(darken1); else diff --git a/src/kits/interface/TextInput.cpp b/src/kits/interface/TextInput.cpp index e02e0bfc8a..5e555776ca 100644 --- a/src/kits/interface/TextInput.cpp +++ b/src/kits/interface/TextInput.cpp @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -168,7 +169,12 @@ _BTextInput_::AlignTextRect() BRect textRect(Bounds()); textRect.left = 0.0; float vInset = max_c(1, floorf((textRect.Height() - LineHeight(0)) / 2.0)); - textRect.InsetBy(2, vInset); + float hInset = 2; + + if (be_control_look) + hInset = be_control_look->DefaultLabelSpacing(); + + textRect.InsetBy(hInset, vInset); SetTextRect(textRect); } diff --git a/src/kits/interface/TextView.cpp b/src/kits/interface/TextView.cpp index 5c0f0d81cf..0b83eb5329 100644 --- a/src/kits/interface/TextView.cpp +++ b/src/kits/interface/TextView.cpp @@ -647,7 +647,7 @@ BTextView::MouseMoved(BPoint where, uint32 code, const BMessage *message) // Check if it's a "click'n'move if (_PerformMouseMoved(where, code)) return; - + bool sync = false; switch (code) { // We force a sync when the mouse enters the view diff --git a/src/kits/tracker/ContainerWindow.cpp b/src/kits/tracker/ContainerWindow.cpp index e8374318a5..6b02fdb021 100644 --- a/src/kits/tracker/ContainerWindow.cpp +++ b/src/kits/tracker/ContainerWindow.cpp @@ -39,6 +39,7 @@ All rights reserved. #include #include #include +#include #include #include #include @@ -499,12 +500,19 @@ DraggableContainerIcon::FrameMoved(BPoint /*newLocation*/) void -DraggableContainerIcon::Draw(BRect /*updateRect*/) +DraggableContainerIcon::Draw(BRect updateRect) { BContainerWindow *window = dynamic_cast(Window()); if (window == NULL) return; + if (be_control_look != NULL) { + BRect rect(Bounds()); + rgb_color base = ui_color(B_MENU_BACKGROUND_COLOR); + be_control_look->DrawMenuBarBackground(this, rect, updateRect, base, + 0); + } + // Draw the icon, straddling the border #ifdef __HAIKU__ SetDrawingMode(B_OP_ALPHA); @@ -910,8 +918,8 @@ BContainerWindow::Init(const BMessage *message) fPoseView->MoveTo(BPoint(0, navigatorDelta + y_delta)); fPoseView->ResizeBy(0, -(y_delta)); if (fPoseView->VScrollBar()) { - fPoseView->VScrollBar()->MoveBy(0, KeyMenuBar()->Bounds().Height() + 1); - fPoseView->VScrollBar()->ResizeBy(0, -(KeyMenuBar()->Bounds().Height() + 1)); + fPoseView->VScrollBar()->MoveBy(0, KeyMenuBar()->Bounds().Height()); + fPoseView->VScrollBar()->ResizeBy(0, -(KeyMenuBar()->Bounds().Height())); } // add folder icon to menu bar diff --git a/src/kits/tracker/CountView.cpp b/src/kits/tracker/CountView.cpp index 3627e4854b..9353cde769 100644 --- a/src/kits/tracker/CountView.cpp +++ b/src/kits/tracker/CountView.cpp @@ -37,6 +37,7 @@ All rights reserved. #include "CountView.h" #include +#include #include "AutoLock.h" #include "Bitmaps.h" @@ -179,9 +180,19 @@ BCountView::CheckCount() void -BCountView::Draw(BRect) +BCountView::Draw(BRect updateRect) { BRect bounds(Bounds()); + + if (be_control_look != NULL) { + rgb_color base = ViewColor(); + SetHighColor(tint_color(base, B_DARKEN_2_TINT)); + StrokeLine(bounds.LeftTop(), bounds.RightTop()); + bounds.top++; + be_control_look->DrawMenuBarBackground(this, bounds, updateRect, + ViewColor()); + } + BString itemString; if (!IsTypingAhead()) { if (fLastCount == 0) @@ -214,13 +225,16 @@ BCountView::Draw(BRect) rgb_color lightShadow = tint_color(ViewColor(), B_DARKEN_1_TINT); BeginLineArray(fShowingBarberPole && !fStartSpinningAfter ? 9 : 5); - AddLine(bounds.LeftTop(), bounds.RightTop(), light); - AddLine(bounds.LeftTop(), bounds.LeftBottom(), light); - bounds.top--; - AddLine(bounds.LeftTop(), bounds.RightTop(), shadow); - AddLine(BPoint(bounds.right, bounds.top + 2), bounds.RightBottom(), lightShadow); - AddLine(bounds.LeftBottom(), bounds.RightBottom(), lightShadow); + if (be_control_look == NULL) { + AddLine(bounds.LeftTop(), bounds.RightTop(), light); + AddLine(bounds.LeftTop(), bounds.LeftBottom(), light); + bounds.top--; + + AddLine(bounds.LeftTop(), bounds.RightTop(), shadow); + AddLine(BPoint(bounds.right, bounds.top + 2), bounds.RightBottom(), lightShadow); + AddLine(bounds.LeftBottom(), bounds.RightBottom(), lightShadow); + } if (!fShowingBarberPole || fStartSpinningAfter) { EndLineArray(); diff --git a/src/kits/tracker/TitleView.cpp b/src/kits/tracker/TitleView.cpp index 4a23e9f34b..d9fa024853 100644 --- a/src/kits/tracker/TitleView.cpp +++ b/src/kits/tracker/TitleView.cpp @@ -37,6 +37,7 @@ All rights reserved. #include #include +#include #include #include #include @@ -73,7 +74,7 @@ static void _DrawLine(BPoseView *view, BPoint from, BPoint to) { rgb_color highColor = view->HighColor(); - view->SetHighColor(kHighlightColor); + view->SetHighColor(tint_color(view->LowColor(), B_DARKEN_1_TINT)); view->StrokeLine(from, to); view->SetHighColor(highColor); } @@ -89,7 +90,11 @@ _UndrawLine(BPoseView *view, BPoint from, BPoint to) static void _DrawOutline(BView *view, BRect where) { - where.InsetBy(1, 1); + if (be_control_look != NULL) { + where.right++; + where.bottom--; + } else + where.InsetBy(1, 1); rgb_color highColor = view->HighColor(); view->SetHighColor(kHighlightColor); view->StrokeRect(where); @@ -221,18 +226,28 @@ BTitleView::Draw(BRect /*updateRect*/, bool useOffscreen, bool updateOnly, } else view = this; - // fill background with light gray background - if (!updateOnly) - view->FillRect(bounds, B_SOLID_LOW); + if (be_control_look != NULL) { + rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR); + view->SetHighColor(tint_color(base, B_DARKEN_2_TINT)); + view->StrokeLine(bounds.LeftBottom(), bounds.RightBottom()); + bounds.bottom--; - view->BeginLineArray(4); - view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShadowColor); - view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sShadowColor); - // draw lighter gray and white inset lines - bounds.InsetBy(0, 1); - view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sLightShadowColor); - view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShineColor); - view->EndLineArray(); + be_control_look->DrawButtonBackground(view, bounds, bounds, base, 0, + BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER); + } else { + // fill background with light gray background + if (!updateOnly) + view->FillRect(bounds, B_SOLID_LOW); + + view->BeginLineArray(4); + view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShadowColor); + view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sShadowColor); + // draw lighter gray and white inset lines + bounds.InsetBy(0, 1); + view->AddLine(bounds.LeftBottom(), bounds.RightBottom(), sLightShadowColor); + view->AddLine(bounds.LeftTop(), bounds.RightTop(), sShineColor); + view->EndLineArray(); + } int32 count = fTitleList.CountItems(); float minx = bounds.right; @@ -247,15 +262,22 @@ BTitleView::Draw(BRect /*updateRect*/, bool useOffscreen, bool updateOnly, maxx = titleBounds.right; } - // first and last shades before and after first column - maxx++; - minx--; - view->BeginLineArray(2); - view->AddLine(BPoint(minx, bounds.top), - BPoint(minx, bounds.bottom), sShadowColor); - view->AddLine(BPoint(maxx, bounds.top), - BPoint(maxx, bounds.bottom), sShineColor); - view->EndLineArray(); + if (be_control_look != NULL) { + bounds = Bounds(); + minx--; + view->SetHighColor(sLightShadowColor); + view->StrokeLine(BPoint(minx, bounds.top), BPoint(minx, bounds.bottom - 1)); + } else { + // first and last shades before and after first column + maxx++; + minx--; + view->BeginLineArray(2); + view->AddLine(BPoint(minx, bounds.top), + BPoint(minx, bounds.bottom), sShadowColor); + view->AddLine(BPoint(maxx, bounds.top), + BPoint(maxx, bounds.bottom), sShineColor); + view->EndLineArray(); + } #if !(APP_SERVER_CLEARS_BACKGROUND) FillRect(BRect(bounds.left, bounds.top + 1, minx - 1, bounds.bottom - 1), B_SOLID_LOW); @@ -460,8 +482,21 @@ BColumnTitle::Draw(BView *view, bool pressed) BRect bounds(Bounds()); BPoint loc(0, bounds.bottom - 4); - view->SetLowColor(pressed ? sDarkTitleBackground : sTitleBackground); - view->FillRect(bounds, B_SOLID_LOW); + if (pressed) { + if (be_control_look != NULL) { + bounds.bottom--; + BRect rect(bounds); + rect.right--; + rgb_color base = tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), + B_DARKEN_1_TINT); + + be_control_look->DrawButtonBackground(view, rect, rect, base, 0, + BControlLook::B_TOP_BORDER | BControlLook::B_BOTTOM_BORDER); + } else { + view->SetLowColor(pressed ? sDarkTitleBackground : sTitleBackground); + view->FillRect(bounds, B_SOLID_LOW); + } + } BString titleString(fColumn->Title()); view->TruncateString(&titleString, B_TRUNCATE_END, @@ -483,43 +518,63 @@ BColumnTitle::Draw(BView *view, bool pressed) break; } - view->SetHighColor(0, 0, 0); + view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.75)); view->DrawString(titleString.String(), loc); // show sort columns bool secondary = (fColumn->AttrHash() == fParent->PoseView()->SecondarySort()); if (secondary || (fColumn->AttrHash() == fParent->PoseView()->PrimarySort())) { - BPoint pt1(loc); - BPoint pt2(view->PenLocation()); - pt1.x--; - pt2.x--; - pt1.y++; - pt2.y++; - if (secondary) - view->StrokeLine(pt1, pt2, B_MIXED_COLORS); - else - view->StrokeLine(pt1, pt2); + + BPoint center(loc.x - 6, roundf((bounds.top + bounds.bottom) / 2.0)); + BPoint triangle[3]; + if (fParent->PoseView()->ReverseSort()) { + triangle[0] = center + BPoint(-3.5, 1.5); + triangle[1] = center + BPoint(3.5, 1.5); + triangle[2] = center + BPoint(0.0, -2.0); + } else { + triangle[0] = center + BPoint(-3.5, -1.5); + triangle[1] = center + BPoint(3.5, -1.5); + triangle[2] = center + BPoint(0.0, 2.0); + } + + uint32 flags = view->Flags(); + view->SetFlags(flags | B_SUBPIXEL_PRECISE); + + if (secondary) { + view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.3)); + view->FillTriangle(triangle[0], triangle[1], triangle[2]); + } else { + view->SetHighColor(tint_color(ui_color(B_PANEL_BACKGROUND_COLOR), 1.6)); + view->FillTriangle(triangle[0], triangle[1], triangle[2]); + } + + view->SetFlags(flags); } - BRect rect(bounds); + if (be_control_look != NULL) { + view->SetHighColor(sLightShadowColor); + view->StrokeLine(bounds.RightTop(), bounds.RightBottom()); + } else { + BRect rect(bounds); - view->SetHighColor(sShadowColor); - view->StrokeRect(rect); + view->SetHighColor(sShadowColor); + view->StrokeRect(rect); - view->BeginLineArray(4); - // draw lighter gray and white inset lines - rect.InsetBy(1, 1); - view->AddLine(rect.LeftBottom(), rect.RightBottom(), - pressed ? sLightShadowColor : sLightShadowColor); - view->AddLine(rect.LeftTop(), rect.RightTop(), - pressed ? sDarkShadowColor : sShineColor); + view->BeginLineArray(4); + // draw lighter gray and white inset lines + rect.InsetBy(1, 1); + view->AddLine(rect.LeftBottom(), rect.RightBottom(), + pressed ? sLightShadowColor : sLightShadowColor); + view->AddLine(rect.LeftTop(), rect.RightTop(), + pressed ? sDarkShadowColor : sShineColor); + + view->AddLine(rect.LeftTop(), rect.LeftBottom(), + pressed ? sDarkShadowColor : sShineColor); + view->AddLine(rect.RightTop(), rect.RightBottom(), + pressed ? sLightShadowColor : sLightShadowColor); - view->AddLine(rect.LeftTop(), rect.LeftBottom(), - pressed ? sDarkShadowColor : sShineColor); - view->AddLine(rect.RightTop(), rect.RightBottom(), - pressed ? sLightShadowColor : sLightShadowColor); - - view->EndLineArray(); + view->EndLineArray(); + } } diff --git a/src/kits/tracker/TitleView.h b/src/kits/tracker/TitleView.h index 7e825d49b8..baabfe6d88 100644 --- a/src/kits/tracker/TitleView.h +++ b/src/kits/tracker/TitleView.h @@ -51,7 +51,7 @@ class OffscreenBitmap; const int32 kTitleViewHeight = 16; const int32 kEdgeSize = 6; -const int32 kTitleColumnLeftExtraMargin = 10; +const int32 kTitleColumnLeftExtraMargin = 11; const int32 kTitleColumnRightExtraMargin = 5; const int32 kTitleColumnExtraMargin = kTitleColumnLeftExtraMargin + kTitleColumnRightExtraMargin;