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;