From 804c69ca0658b139a7ba202b790f066ce8c289de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stephan=20A=C3=9Fmus?= Date: Sun, 20 Feb 2011 22:33:05 +0000 Subject: [PATCH] Moved IconButton from LaunchBox (actually the updated version from WebPositive) into libshared.a as BPrivate::BIconButton. Removed some outdated functionality as well (now only uses BControlLook for drawing, cleaned up custom drawing). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40587 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../private/shared}/IconButton.h | 74 +- src/apps/launchbox/Jamfile | 2 - src/apps/launchbox/LaunchButton.cpp | 37 +- src/apps/launchbox/LaunchButton.h | 15 +- .../launchbox => kits/shared}/IconButton.cpp | 674 +++++++++--------- src/kits/shared/Jamfile | 3 +- 6 files changed, 428 insertions(+), 377 deletions(-) rename {src/apps/launchbox => headers/private/shared}/IconButton.h (70%) rename src/{apps/launchbox => kits/shared}/IconButton.cpp (52%) diff --git a/src/apps/launchbox/IconButton.h b/headers/private/shared/IconButton.h similarity index 70% rename from src/apps/launchbox/IconButton.h rename to headers/private/shared/IconButton.h index 74213876ca..953c657a83 100644 --- a/src/apps/launchbox/IconButton.h +++ b/headers/private/shared/IconButton.h @@ -1,42 +1,55 @@ /* - * Copyright 2006, Haiku. + * Copyright 2006-2011, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus */ - -/** gui class that loads an image from disk and shows it - as clickable button */ - -// TODO: inherit from BControl? - -// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic -// it should be placed into a common folder for generic useful stuff - #ifndef ICON_BUTTON_H #define ICON_BUTTON_H + +//! GUI class that loads an image from disk and shows it as clickable button. + +// TODO: inherit from BControl + + #include #include #include + class BBitmap; class BMimeType; -class IconButton : public BView, public BInvoker { + +namespace BPrivate { + + +class BIconButton : public BView, public BInvoker { public: - IconButton(const char* name, + BIconButton(const char* name, uint32 id, const char* label = NULL, BMessage* message = NULL, BHandler* target = NULL); - virtual ~IconButton(); + virtual ~BIconButton(); // BView interface virtual void MessageReceived(BMessage* message); virtual void AttachedToWindow(); + virtual void Draw(BRect updateRect); + virtual bool ShouldDrawBorder() const; + virtual void DrawBorder(BRect& frame, + const BRect& updateRect, + const rgb_color& backgroundColor, + uint32 controlLookFlags); + virtual void DrawBackground(BRect& frame, + const BRect& updateRect, + const rgb_color& backgroundColor, + uint32 controlLookFlags); + virtual void MouseDown(BPoint where); virtual void MouseUp(BPoint where); virtual void MouseMoved(BPoint where, uint32 transit, @@ -50,7 +63,7 @@ public: // BInvoker interface virtual status_t Invoke(BMessage* message = NULL); - // IconButton + // BIconButton bool IsValid() const; virtual int32 Value() const; @@ -64,6 +77,7 @@ public: uint32 ID() const { return fID; } + status_t SetIcon(int32 resourceID); status_t SetIcon(const char* pathToBitmap); status_t SetIcon(const BBitmap* bitmap); status_t SetIcon(const BMimeType* fileType, @@ -73,23 +87,11 @@ public: color_space format, bool convertToBW = false); void ClearIcon(); + void TrimIcon(bool keepAspect = true); BBitmap* Bitmap() const; // caller has to delete the returned bitmap - - virtual bool DrawBorder() const; - virtual void DrawNormalBorder(BRect r, - rgb_color background, - rgb_color shadow, - rgb_color darkShadow, - rgb_color lightShadow, - rgb_color light); - virtual void DrawPressedBorder(BRect r, - rgb_color background, - rgb_color shadow, - rgb_color darkShadow, - rgb_color lightShadow, - rgb_color light); + const BString& Label() const; protected: enum { @@ -105,19 +107,14 @@ protected: void _ClearFlags(uint32 flags); bool _HasFlags(uint32 flags) const; - void _DrawFrame(BRect frame, - rgb_color col1, - rgb_color col2, - rgb_color col3, - rgb_color col4); - -// private: +private: BBitmap* _ConvertToRGB32(const BBitmap* bitmap) const; status_t _MakeBitmaps(const BBitmap* bitmap); void _DeleteBitmaps(); void _SendMessage() const; void _Update(); +private: uint32 fButtonState; int32 fID; BBitmap* fNormalBitmap; @@ -129,4 +126,11 @@ protected: BHandler* fTargetCache; }; + +} // namespac BPrivate + + +using BPrivate::BIconButton; + + #endif // ICON_BUTTON_H diff --git a/src/apps/launchbox/Jamfile b/src/apps/launchbox/Jamfile index ccb8e6300e..d560636534 100644 --- a/src/apps/launchbox/Jamfile +++ b/src/apps/launchbox/Jamfile @@ -4,7 +4,6 @@ UsePrivateHeaders shared ; Application LaunchBox : App.cpp - IconButton.cpp LaunchButton.cpp main.cpp MainWindow.cpp @@ -20,7 +19,6 @@ DoCatalogs LaunchBox : x-vnd.Haiku-LaunchBox : App.cpp - IconButton.cpp LaunchButton.cpp MainWindow.cpp NamePanel.cpp diff --git a/src/apps/launchbox/LaunchButton.cpp b/src/apps/launchbox/LaunchButton.cpp index 03e5be7d17..d965842b5f 100644 --- a/src/apps/launchbox/LaunchButton.cpp +++ b/src/apps/launchbox/LaunchButton.cpp @@ -42,7 +42,7 @@ LaunchButton::sIgnoreDoubleClick = true; LaunchButton::LaunchButton(const char* name, uint32 id, const char* label, BMessage* message, BHandler* target) : - IconButton(name, id, label, message, target), + BIconButton(name, id, label, message, target), fRef(NULL), fAppSig(NULL), fDescription(""), @@ -65,7 +65,7 @@ LaunchButton::~LaunchButton() void LaunchButton::AttachedToWindow() { - IconButton::AttachedToWindow(); + BIconButton::AttachedToWindow(); _UpdateToolTip(); } @@ -85,7 +85,7 @@ LaunchButton::Draw(BRect updateRect) ConstrainClippingRegion(®ion); } if (IsValid()) { - IconButton::Draw(updateRect); + BIconButton::Draw(updateRect); } else { rgb_color background = LowColor(); rgb_color lightShadow = tint_color(background, @@ -149,7 +149,7 @@ LaunchButton::MessageReceived(BMessage* message) case B_PASTE: case B_MODIFIERS_CHANGED: default: - IconButton::MessageReceived(message); + BIconButton::MessageReceived(message); break; } } @@ -177,7 +177,7 @@ LaunchButton::MouseDown(BPoint where) } } if (callInherited) - IconButton::MouseDown(where); + BIconButton::MouseDown(where); } @@ -188,7 +188,7 @@ LaunchButton::MouseUp(BPoint where) fAnticipatingDrop = false; Invalidate(); } - IconButton::MouseUp(where); + BIconButton::MouseUp(where); } @@ -238,11 +238,12 @@ LaunchButton::MouseMoved(BPoint where, uint32 transit, BMessage message(B_SIMPLE_DATA); message.AddPointer("button", this); message.AddRef("refs", fRef); + // DragMessage takes ownership of the bitmap. DragMessage(&message, bitmap, B_OP_ALPHA, fDragStart); } } } - IconButton::MouseMoved(where, transit, dragMessage); + BIconButton::MouseMoved(where, transit, dragMessage); } @@ -262,11 +263,11 @@ LaunchButton::PreferredSize() float hPadding = max_c(6.0, ceilf(minHeight / 3.0)); float vPadding = max_c(6.0, ceilf(minWidth / 3.0)); - if (fLabel.CountChars() > 0) { + if (Label().CountChars() > 0) { font_height fh; GetFontHeight(&fh); minHeight += ceilf(fh.ascent + fh.descent) + vPadding; - minWidth += StringWidth(fLabel.String()) + vPadding; + minWidth += StringWidth(Label().String()) + vPadding; } return BSize(minWidth + hPadding, minHeight + vPadding); @@ -427,3 +428,21 @@ LaunchButton::_NotifySettingsChanged() { be_app->PostMessage(MSG_SETTINGS_CHANGED); } + + +void +LaunchButton::_DrawFrame(BRect r, rgb_color col1, rgb_color col2, + rgb_color col3, rgb_color col4) +{ + BeginLineArray(8); + AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col1); + AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col1); + AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col2); + AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col2); + r.InsetBy(1.0, 1.0); + AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col3); + AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col3); + AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col4); + AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col4); + EndLineArray(); +} diff --git a/src/apps/launchbox/LaunchButton.h b/src/apps/launchbox/LaunchButton.h index 4d06c0f19a..85ca5549d0 100644 --- a/src/apps/launchbox/LaunchButton.h +++ b/src/apps/launchbox/LaunchButton.h @@ -1,14 +1,15 @@ /* - * Copyright 2006-2009, Stephan Aßmus + * Copyright 2006-2011, Stephan Aßmus * All rights reserved. Distributed under the terms of the MIT License. */ #ifndef LAUNCH_BUTTON_H #define LAUNCH_BUTTON_H + +#include #include #include -#include "IconButton.h" enum { MSG_ADD_SLOT = 'adsl', @@ -17,7 +18,8 @@ enum { MSG_LAUNCH = 'lnch', }; -class LaunchButton : public IconButton { + +class LaunchButton : public BIconButton { public: LaunchButton(const char* name, uint32 id, const char* label = NULL, @@ -25,7 +27,7 @@ public: BHandler* target = NULL); virtual ~LaunchButton(); - // IconButton interface + // BIconButton interface virtual void AttachedToWindow(); virtual void Draw(BRect updateRect); virtual void MessageReceived(BMessage* message); @@ -64,6 +66,11 @@ private: void _NotifySettingsChanged(); + void _DrawFrame(BRect frame, + rgb_color left, rgb_color top, + rgb_color right, rgb_color bottom); + +private: entry_ref* fRef; char* fAppSig; BString fDescription; diff --git a/src/apps/launchbox/IconButton.cpp b/src/kits/shared/IconButton.cpp similarity index 52% rename from src/apps/launchbox/IconButton.cpp rename to src/kits/shared/IconButton.cpp index 7573e34b88..d5c50960f7 100644 --- a/src/apps/launchbox/IconButton.cpp +++ b/src/kits/shared/IconButton.cpp @@ -1,13 +1,11 @@ /* - * Copyright 2006-2009, Haiku. + * Copyright 2006-2011, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Stephan Aßmus */ -// NOTE: this file is a duplicate of the version in Icon-O-Matic/generic -// it should be placed into a common folder for generic useful stuff #include "IconButton.h" @@ -16,50 +14,48 @@ #include #include -#include #include #include #include +#include #include #include #include #include #include +#include #include #include #include -#undef B_TRANSLATE_CONTEXT -#define B_TRANSLATE_CONTEXT "LaunchBox" -using std::nothrow; -// constructor -IconButton::IconButton(const char* name, uint32 id, const char* label, +BIconButton::BIconButton(const char* name, uint32 id, const char* label, BMessage* message, BHandler* target) - : BView(name, B_WILL_DRAW), - BInvoker(message, target), - fButtonState(STATE_ENABLED), - fID(id), - fNormalBitmap(NULL), - fDisabledBitmap(NULL), - fClickedBitmap(NULL), - fDisabledClickedBitmap(NULL), - fLabel(label), - fTargetCache(target) + : + BView(name, B_WILL_DRAW), + BInvoker(message, target), + fButtonState(STATE_ENABLED), + fID(id), + fNormalBitmap(NULL), + fDisabledBitmap(NULL), + fClickedBitmap(NULL), + fDisabledClickedBitmap(NULL), + fLabel(label), + fTargetCache(target) { SetLowColor(ui_color(B_PANEL_BACKGROUND_COLOR)); SetViewColor(B_TRANSPARENT_32_BIT); } -// destructor -IconButton::~IconButton() + +BIconButton::~BIconButton() { _DeleteBitmaps(); } -// MessageReceived + void -IconButton::MessageReceived(BMessage* message) +BIconButton::MessageReceived(BMessage* message) { switch (message->what) { default: @@ -68,9 +64,9 @@ IconButton::MessageReceived(BMessage* message) } } -// AttachedToWindow + void -IconButton::AttachedToWindow() +BIconButton::AttachedToWindow() { rgb_color background = B_TRANSPARENT_COLOR; if (BView* parent = Parent()) { @@ -87,143 +83,82 @@ IconButton::AttachedToWindow() SetTarget(Window()); } -// Draw + void -IconButton::Draw(BRect area) +BIconButton::Draw(BRect updateRect) { rgb_color background = LowColor(); 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, - 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; + uint32 flags = 0; BBitmap* bitmap = fNormalBitmap; - // adjust colors and bitmap according to flags - if (IsEnabled()) { - lightShadow = tint_color(background, B_DARKEN_1_TINT); - shadow = tint_color(background, B_DARKEN_2_TINT); - darkShadow = tint_color(background, B_DARKEN_4_TINT); - light = tint_color(background, B_LIGHTEN_MAX_TINT); - SetHighColor(0, 0, 0, 255); - } else { - lightShadow = tint_color(background, 1.11); - shadow = tint_color(background, B_DARKEN_1_TINT); - darkShadow = tint_color(background, B_DARKEN_2_TINT); - light = tint_color(background, B_LIGHTEN_2_TINT); + if (!IsEnabled()) { + flags |= BControlLook::B_DISABLED; bitmap = fDisabledBitmap; - SetHighColor(tint_color(background, B_DISABLED_LABEL_TINT)); } - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) { - if (IsEnabled()) { -// background = tint_color(background, B_DARKEN_2_TINT); -// background = tint_color(background, B_LIGHTEN_1_TINT); - background = tint_color(background, B_DARKEN_1_TINT); - bitmap = fClickedBitmap; - } else { -// background = tint_color(background, B_DARKEN_1_TINT); -// background = tint_color(background, (B_NO_TINT + B_LIGHTEN_1_TINT) / 2.0); - background = tint_color(background, (B_NO_TINT + B_DARKEN_1_TINT) / 2.0); - bitmap = fDisabledClickedBitmap; - } - // background - SetLowColor(background); - r.InsetBy(2.0, 2.0); - StrokeLine(r.LeftBottom(), r.LeftTop(), B_SOLID_LOW); - StrokeLine(r.LeftTop(), r.RightTop(), B_SOLID_LOW); - r.InsetBy(-2.0, -2.0); + if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) + flags |= BControlLook::B_ACTIVATED; + + if (ShouldDrawBorder()) { + DrawBorder(r, updateRect, background, flags); + DrawBackground(r, updateRect, background, flags); + } else { + SetHighColor(background); + FillRect(r); } - // draw frame only if tracking - if (DrawBorder()) { - if (_HasFlags(STATE_PRESSED) || _HasFlags(STATE_FORCE_PRESSED)) - DrawPressedBorder(r, background, shadow, darkShadow, lightShadow, light); - else - DrawNormalBorder(r, background, shadow, darkShadow, lightShadow, light); - r.InsetBy(2.0, 2.0); - } else - _DrawFrame(r, background, background, background, background); - float width = Bounds().Width(); - float height = Bounds().Height(); - // bitmap - BRegion originalClippingRegion; + if (bitmap && bitmap->IsValid()) { - float x = floorf((width - bitmap->Bounds().Width()) / 2.0 + 0.5); - float y = floorf((height - bitmap->Bounds().Height()) / 2.0 + 0.5); + 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) { - FillRect(r, B_SOLID_LOW); + if (bitmap->ColorSpace() == B_RGBA32 + || bitmap->ColorSpace() == B_RGBA32_BIG) { SetDrawingMode(B_OP_ALPHA); SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY); } DrawBitmap(bitmap, point); - // constrain clipping region - BRegion region= originalClippingRegion; - GetClippingRegion(®ion); - region.Exclude(bitmap->Bounds().OffsetByCopy(point)); - ConstrainClippingRegion(®ion); - } - // background - SetDrawingMode(B_OP_COPY); - FillRect(r, B_SOLID_LOW); - ConstrainClippingRegion(NULL); - // label - if (fLabel.CountChars() > 0) { - SetDrawingMode(B_OP_COPY); - font_height fh; - GetFontHeight(&fh); - float y = Bounds().bottom - 4.0; - y -= fh.descent; - float x = (width - StringWidth(fLabel.String())) / 2.0; - DrawString(fLabel.String(), BPoint(x, y)); } } -// MouseDown + +bool +BIconButton::ShouldDrawBorder() const +{ + return ((IsEnabled() && (_HasFlags(STATE_INSIDE) + || _HasFlags(STATE_TRACKING))) || _HasFlags(STATE_FORCE_PRESSED)); +} + + void -IconButton::MouseDown(BPoint where) +BIconButton::DrawBorder(BRect& frame, const BRect& updateRect, + const rgb_color& backgroundColor, uint32 flags) +{ + be_control_look->DrawButtonFrame(this, frame, updateRect, backgroundColor, + backgroundColor, flags); +} + + +void +BIconButton::DrawBackground(BRect& frame, const BRect& updateRect, + const rgb_color& backgroundColor, uint32 flags) +{ + be_control_look->DrawButtonBackground(this, frame, updateRect, + backgroundColor, flags); +} + + +void +BIconButton::MouseDown(BPoint where) { if (!IsValid()) return; - if (_HasFlags(STATE_ENABLED)/* && !_HasFlags(STATE_FORCE_PRESSED)*/) { + if (_HasFlags(STATE_ENABLED)) { if (Bounds().Contains(where)) { SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); _AddFlags(STATE_PRESSED | STATE_TRACKING); @@ -233,25 +168,24 @@ IconButton::MouseDown(BPoint where) } } -// MouseUp + void -IconButton::MouseUp(BPoint where) +BIconButton::MouseUp(BPoint where) { if (!IsValid()) return; -// if (!_HasFlags(STATE_FORCE_PRESSED)) { - if (_HasFlags(STATE_ENABLED) && _HasFlags(STATE_PRESSED) && Bounds().Contains(where)) - Invoke(); - else if (Bounds().Contains(where)) - _AddFlags(STATE_INSIDE); - _ClearFlags(STATE_PRESSED | STATE_TRACKING); -// } + if (_HasFlags(STATE_ENABLED) && _HasFlags(STATE_PRESSED) + && Bounds().Contains(where)) { + Invoke(); + } else if (Bounds().Contains(where)) + _AddFlags(STATE_INSIDE); + _ClearFlags(STATE_PRESSED | STATE_TRACKING); } -// MouseMoved + void -IconButton::MouseMoved(BPoint where, uint32 transit, const BMessage* message) +BIconButton::MouseMoved(BPoint where, uint32 transit, const BMessage* message) { if (!IsValid()) return; @@ -278,25 +212,25 @@ IconButton::MouseMoved(BPoint where, uint32 transit, const BMessage* message) } } -#define MIN_SPACE 15.0 -// GetPreferredSize void -IconButton::GetPreferredSize(float* width, float* height) +BIconButton::GetPreferredSize(float* width, float* height) { - float minWidth = 0.0; - float minHeight = 0.0; + float minWidth = 0.0f; + float minHeight = 0.0f; if (IsValid()) { - minWidth += fNormalBitmap->Bounds().IntegerWidth() + 1.0; - minHeight += fNormalBitmap->Bounds().IntegerHeight() + 1.0; + minWidth += fNormalBitmap->Bounds().IntegerWidth() + 1.0f; + minHeight += fNormalBitmap->Bounds().IntegerHeight() + 1.0f; } - if (minWidth < MIN_SPACE) - minWidth = MIN_SPACE; - if (minHeight < MIN_SPACE) - minHeight = MIN_SPACE; - float hPadding = max_c(6.0, ceilf(minHeight / 4.0)); - float vPadding = max_c(6.0, ceilf(minWidth / 4.0)); + const float kMinSpace = 15.0f; + if (minWidth < kMinSpace) + minWidth = kMinSpace; + if (minHeight < kMinSpace) + minHeight = kMinSpace; + + float hPadding = max_c(6.0f, ceilf(minHeight / 4.0f)); + float vPadding = max_c(6.0f, ceilf(minWidth / 4.0f)); if (fLabel.CountChars() > 0) { font_height fh; @@ -311,29 +245,29 @@ IconButton::GetPreferredSize(float* width, float* height) *height = minHeight + vPadding; } -// MinSize + BSize -IconButton::MinSize() +BIconButton::MinSize() { BSize size; GetPreferredSize(&size.width, &size.height); return size; } -// MaxSize + BSize -IconButton::MaxSize() +BIconButton::MaxSize() { return MinSize(); } -// Invoke + status_t -IconButton::Invoke(BMessage* message) +BIconButton::Invoke(BMessage* message) { - if (!message) + if (message == NULL) message = Message(); - if (message) { + if (message != NULL) { BMessage clone(*message); clone.AddInt64("be:when", system_time()); clone.AddPointer("be:source", (BView*)this); @@ -344,9 +278,9 @@ IconButton::Invoke(BMessage* message) return BInvoker::Invoke(message); } -// SetPressed + void -IconButton::SetPressed(bool pressed) +BIconButton::SetPressed(bool pressed) { if (pressed) _AddFlags(STATE_FORCE_PRESSED); @@ -354,16 +288,48 @@ IconButton::SetPressed(bool pressed) _ClearFlags(STATE_FORCE_PRESSED); } -// IsPressed + bool -IconButton::IsPressed() const +BIconButton::IsPressed() const { return _HasFlags(STATE_FORCE_PRESSED); } -// SetIcon + status_t -IconButton::SetIcon(const char* pathToBitmap) +BIconButton::SetIcon(int32 resourceID) +{ + app_info info; + status_t status = be_app->GetAppInfo(&info); + if (status != B_OK) + return status; + + BResources resources(&info.ref); + status = resources.InitCheck(); + if (status != B_OK) + return status; + + size_t size; + const void* data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, + &size); + if (data != NULL) { + BBitmap bitmap(BRect(0, 0, 31, 31), B_BITMAP_NO_SERVER_LINK, B_RGBA32); + status = bitmap.InitCheck(); + if (status != B_OK) + return status; + status = BIconUtils::GetVectorIcon(reinterpret_cast(data), + size, &bitmap); + if (status != B_OK) + return status; + return SetIcon(&bitmap); + } +// const void* data = resources.LoadResource(B_BITMAP_TYPE, resourceID, &size); + return B_ERROR; +} + + +status_t +BIconButton::SetIcon(const char* pathToBitmap) { if (pathToBitmap == NULL) return B_BAD_VALUE; @@ -386,18 +352,22 @@ IconButton::SetIcon(const char* pathToBitmap) status = path.Append(pathToBitmap, true); if (status == B_OK) fileBitmap = BTranslationUtils::GetBitmap(path.Path()); - else - printf("IconButton::SetIcon() - " - "path.Append() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - " - "path.GetParent() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - " - "path.InitCheck() failed: %s\n", strerror(status)); - } else - printf("IconButton::SetIcon() - " - "be_app->GetAppInfo() failed: %s\n", strerror(status)); + else { + printf("BIconButton::SetIcon() - path.Append() failed: " + "%s\n", strerror(status)); + } + } else { + printf("BIconButton::SetIcon() - path.GetParent() failed: " + "%s\n", strerror(status)); + } + } else { + printf("BIconButton::SetIcon() - path.InitCheck() failed: " + "%s\n", strerror(status)); + } + } else { + printf("BIconButton::SetIcon() - be_app->GetAppInfo() failed: " + "%s\n", strerror(status)); + } } else fileBitmap = BTranslationUtils::GetBitmap(pathToBitmap); if (fileBitmap) { @@ -408,9 +378,9 @@ IconButton::SetIcon(const char* pathToBitmap) return status; } -// SetIcon + status_t -IconButton::SetIcon(const BBitmap* bitmap) +BIconButton::SetIcon(const BBitmap* bitmap) { if (bitmap && bitmap->ColorSpace() == B_CMAP8) { status_t status = bitmap->InitCheck(); @@ -426,55 +396,64 @@ IconButton::SetIcon(const BBitmap* bitmap) return _MakeBitmaps(bitmap); } -// SetIcon + status_t -IconButton::SetIcon(const BMimeType* fileType, bool small) +BIconButton::SetIcon(const BMimeType* fileType, bool small) { status_t status = fileType ? fileType->InitCheck() : B_BAD_VALUE; if (status >= B_OK) { - BBitmap* mimeBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, 15.0, 15.0), B_CMAP8); + BBitmap* mimeBitmap = new(std::nothrow) BBitmap(BRect(0.0, 0.0, 15.0, + 15.0), B_CMAP8); if (mimeBitmap && mimeBitmap->IsValid()) { - status = fileType->GetIcon(mimeBitmap, small ? B_MINI_ICON : B_LARGE_ICON); + status = fileType->GetIcon(mimeBitmap, small ? B_MINI_ICON + : B_LARGE_ICON); if (status >= B_OK) { if (BBitmap* bitmap = _ConvertToRGB32(mimeBitmap)) { status = _MakeBitmaps(bitmap); delete bitmap; - } else - printf("IconButton::SetIcon() - " - "B_RGB32 bitmap is not valid\n"); - } else - printf("IconButton::SetIcon() - " - "fileType->GetIcon() failed: %s\n", strerror(status)); + } else { + printf("BIconButton::SetIcon() - B_RGB32 bitmap is not " + "valid\n"); + } + } else { + printf("BIconButton::SetIcon() - fileType->GetIcon() failed: " + "%s\n", strerror(status)); + } } else - printf("IconButton::SetIcon() - " - "B_CMAP8 bitmap is not valid\n"); + printf("BIconButton::SetIcon() - B_CMAP8 bitmap is not valid\n"); delete mimeBitmap; - } else - printf("IconButton::SetIcon() - " - "fileType is not valid: %s\n", strerror(status)); + } else { + printf("BIconButton::SetIcon() - fileType is not valid: %s\n", + strerror(status)); + } return status; } -// SetIcon + status_t -IconButton::SetIcon(const unsigned char* bitsFromQuickRes, +BIconButton::SetIcon(const unsigned char* bitsFromQuickRes, uint32 width, uint32 height, color_space format, bool convertToBW) { status_t status = B_BAD_VALUE; if (bitsFromQuickRes && width > 0 && height > 0) { - BBitmap* quickResBitmap = new(nothrow) BBitmap(BRect(0.0, 0.0, width - 1.0, height - 1.0), format); + BBitmap* quickResBitmap = new(std::nothrow) BBitmap(BRect(0.0, 0.0, + width - 1.0, height - 1.0), format); status = quickResBitmap ? quickResBitmap->InitCheck() : B_ERROR; if (status >= B_OK) { // It doesn't look right to copy BitsLength() bytes, but bitmaps - // exported from QuickRes still contain their padding, so it is alright. - memcpy(quickResBitmap->Bits(), bitsFromQuickRes, quickResBitmap->BitsLength()); - if (format != B_RGB32 && format != B_RGBA32 && format != B_RGB32_BIG && format != B_RGBA32_BIG) { + // exported from QuickRes still contain their padding, so it is + // alright. + memcpy(quickResBitmap->Bits(), bitsFromQuickRes, + quickResBitmap->BitsLength()); + if (format != B_RGB32 && format != B_RGBA32 + && format != B_RGB32_BIG && format != B_RGBA32_BIG) { // colorspace needs conversion - BBitmap* bitmap = new(nothrow) BBitmap(quickResBitmap->Bounds(), B_RGB32, true); + BBitmap* bitmap = new(std::nothrow) BBitmap( + quickResBitmap->Bounds(), B_RGB32, true); if (bitmap && bitmap->IsValid()) { + BView* helper = new BView(bitmap->Bounds(), "helper", + B_FOLLOW_NONE, B_WILL_DRAW); if (bitmap->Lock()) { - BView* helper = new BView(bitmap->Bounds(), "helper", - B_FOLLOW_NONE, B_WILL_DRAW); bitmap->AddChild(helper); helper->SetHighColor(ui_color(B_PANEL_BACKGROUND_COLOR)); helper->FillRect(helper->Bounds()); @@ -484,8 +463,10 @@ IconButton::SetIcon(const unsigned char* bitsFromQuickRes, bitmap->Unlock(); } status = _MakeBitmaps(bitmap); - } else - printf("IconButton::SetIcon() - B_RGB32 bitmap is not valid\n"); + } else { + printf("BIconButton::SetIcon() - B_RGB32 bitmap is not " + "valid\n"); + } delete bitmap; } else { // native colorspace (32 bits) @@ -497,7 +478,8 @@ IconButton::SetIcon(const unsigned char* bitsFromQuickRes, uint8* handle = bits; uint8 gray; for (uint32 x = 0; x < width; x++) { - gray = uint8((116 * handle[0] + 600 * handle[1] + 308 * handle[2]) / 1024); + gray = uint8((116 * handle[0] + 600 * handle[1] + + 308 * handle[2]) / 1024); handle[0] = gray; handle[1] = gray; handle[2] = gray; @@ -508,31 +490,106 @@ IconButton::SetIcon(const unsigned char* bitsFromQuickRes, } status = _MakeBitmaps(quickResBitmap); } - } else - printf("IconButton::SetIcon() - " - "error allocating bitmap: %s\n", strerror(status)); + } else { + printf("BIconButton::SetIcon() - error allocating bitmap: " + "%s\n", strerror(status)); + } delete quickResBitmap; } return status; } -// ClearIcon + void -IconButton::ClearIcon() +BIconButton::ClearIcon() { _DeleteBitmaps(); _Update(); } -// Bitmap + +void +BIconButton::TrimIcon(bool keepAspect) +{ + if (fNormalBitmap == NULL) + return; + + uint8* bits = (uint8*)fNormalBitmap->Bits(); + uint32 bpr = fNormalBitmap->BytesPerRow(); + uint32 width = fNormalBitmap->Bounds().IntegerWidth() + 1; + uint32 height = fNormalBitmap->Bounds().IntegerHeight() + 1; + BRect trimmed(LONG_MAX, LONG_MAX, LONG_MIN, LONG_MIN); + for (uint32 y = 0; y < height; y++) { + uint8* b = bits + 3; + bool rowHasAlpha = false; + for (uint32 x = 0; x < width; x++) { + if (*b) { + rowHasAlpha = true; + if (x < trimmed.left) + trimmed.left = x; + if (x > trimmed.right) + trimmed.right = x; + } + b += 4; + } + if (rowHasAlpha) { + if (y < trimmed.top) + trimmed.top = y; + if (y > trimmed.bottom) + trimmed.bottom = y; + } + bits += bpr; + } + if (!trimmed.IsValid()) + return; + if (keepAspect) { + float minInset = trimmed.left; + minInset = min_c(minInset, trimmed.top); + minInset = min_c(minInset, fNormalBitmap->Bounds().right + - trimmed.right); + minInset = min_c(minInset, fNormalBitmap->Bounds().bottom + - trimmed.bottom); + trimmed = fNormalBitmap->Bounds().InsetByCopy(minInset, minInset); + } + trimmed = trimmed & fNormalBitmap->Bounds(); + BBitmap trimmedBitmap(trimmed.OffsetToCopy(B_ORIGIN), + B_BITMAP_NO_SERVER_LINK, B_RGBA32); + bits = (uint8*)fNormalBitmap->Bits(); + bits += 4 * (int32)trimmed.left + bpr * (int32)trimmed.top; + uint8* dst = (uint8*)trimmedBitmap.Bits(); + uint32 trimmedWidth = trimmedBitmap.Bounds().IntegerWidth() + 1; + uint32 trimmedHeight = trimmedBitmap.Bounds().IntegerHeight() + 1; + uint32 trimmedBPR = trimmedBitmap.BytesPerRow(); + for (uint32 y = 0; y < trimmedHeight; y++) { + memcpy(dst, bits, trimmedWidth * 4); + dst += trimmedBPR; + bits += bpr; + } + SetIcon(&trimmedBitmap); +} + + +bool +BIconButton::IsValid() const +{ + return (fNormalBitmap && fDisabledBitmap && fClickedBitmap + && fDisabledClickedBitmap + && fNormalBitmap->IsValid() + && fDisabledBitmap->IsValid() + && fClickedBitmap->IsValid() + && fDisabledClickedBitmap->IsValid()); +} + + BBitmap* -IconButton::Bitmap() const +BIconButton::Bitmap() const { BBitmap* bitmap = NULL; if (fNormalBitmap && fNormalBitmap->IsValid()) { - bitmap = new(nothrow) BBitmap(fNormalBitmap); - if (bitmap->IsValid()) { - // TODO: remove this functionality when we use real transparent bitmaps + bitmap = new(std::nothrow) BBitmap(fNormalBitmap); + if (bitmap != NULL && bitmap->IsValid()) { + // TODO: remove this functionality when we use real transparent + // bitmaps uint8* bits = (uint8*)bitmap->Bits(); uint32 bpr = bitmap->BytesPerRow(); uint32 width = bitmap->Bounds().IntegerWidth() + 1; @@ -547,7 +604,8 @@ IconButton::Bitmap() const if (bitsHandle[0] == 216 && bitsHandle[1] == 216 && bitsHandle[2] == 216) { - bitsHandle[3] = 0; // make this pixel completely transparent + // make this pixel completely transparent + bitsHandle[3] = 0; } bitsHandle += 4; } @@ -562,54 +620,23 @@ IconButton::Bitmap() const return bitmap; } -// DrawBorder -bool -IconButton::DrawBorder() const + +const BString& +BIconButton::Label() const { - return ((IsEnabled() && (_HasFlags(STATE_INSIDE) - || _HasFlags(STATE_TRACKING))) || _HasFlags(STATE_FORCE_PRESSED)); + return fLabel; } -// DrawNormalBorder -void -IconButton::DrawNormalBorder(BRect r, rgb_color background, - rgb_color shadow, rgb_color darkShadow, - rgb_color lightShadow, rgb_color light) -{ - _DrawFrame(r, shadow, darkShadow, light, lightShadow); -} -// DrawPressedBorder -void -IconButton::DrawPressedBorder(BRect r, rgb_color background, - rgb_color shadow, rgb_color darkShadow, - rgb_color lightShadow, rgb_color light) -{ - _DrawFrame(r, shadow, light, darkShadow, background); -} - -// IsValid -bool -IconButton::IsValid() const -{ - return (fNormalBitmap && fDisabledBitmap && fClickedBitmap - && fDisabledClickedBitmap - && fNormalBitmap->IsValid() - && fDisabledBitmap->IsValid() - && fClickedBitmap->IsValid() - && fDisabledClickedBitmap->IsValid()); -} - -// Value int32 -IconButton::Value() const +BIconButton::Value() const { return _HasFlags(STATE_PRESSED) ? B_CONTROL_ON : B_CONTROL_OFF; } -// SetValue + void -IconButton::SetValue(int32 value) +BIconButton::SetValue(int32 value) { if (value) _AddFlags(STATE_PRESSED); @@ -617,16 +644,16 @@ IconButton::SetValue(int32 value) _ClearFlags(STATE_PRESSED); } -// IsEnabled + bool -IconButton::IsEnabled() const +BIconButton::IsEnabled() const { return _HasFlags(STATE_ENABLED) ? B_CONTROL_ON : B_CONTROL_OFF; } -// SetEnabled + void -IconButton::SetEnabled(bool enabled) +BIconButton::SetEnabled(bool enabled) { if (enabled) _AddFlags(STATE_ENABLED); @@ -634,17 +661,20 @@ IconButton::SetEnabled(bool enabled) _ClearFlags(STATE_ENABLED | STATE_TRACKING | STATE_INSIDE); } -// _ConvertToRGB32 + +// #pragma mark - private + + BBitmap* -IconButton::_ConvertToRGB32(const BBitmap* bitmap) const +BIconButton::_ConvertToRGB32(const BBitmap* bitmap) const { - BBitmap* convertedBitmap = new(nothrow) BBitmap(bitmap->Bounds(), + BBitmap* convertedBitmap = new(std::nothrow) BBitmap(bitmap->Bounds(), B_BITMAP_ACCEPTS_VIEWS, B_RGBA32); if (convertedBitmap && convertedBitmap->IsValid()) { memset(convertedBitmap->Bits(), 0, convertedBitmap->BitsLength()); + BView* helper = new BView(bitmap->Bounds(), "helper", + B_FOLLOW_NONE, B_WILL_DRAW); if (convertedBitmap->Lock()) { - BView* helper = new BView(bitmap->Bounds(), "helper", - B_FOLLOW_NONE, B_WILL_DRAW); convertedBitmap->AddChild(helper); helper->SetDrawingMode(B_OP_OVER); helper->DrawBitmap(bitmap, BPoint(0.0, 0.0)); @@ -658,9 +688,9 @@ IconButton::_ConvertToRGB32(const BBitmap* bitmap) const return convertedBitmap; } -// _MakeBitmaps + status_t -IconButton::_MakeBitmaps(const BBitmap* bitmap) +BIconButton::_MakeBitmaps(const BBitmap* bitmap) { status_t status = bitmap ? bitmap->InitCheck() : B_BAD_VALUE; if (status >= B_OK) { @@ -668,10 +698,10 @@ IconButton::_MakeBitmaps(const BBitmap* bitmap) BRect b(bitmap->Bounds()); _DeleteBitmaps(); color_space format = bitmap->ColorSpace(); - fNormalBitmap = new(nothrow) BBitmap(b, format); - fDisabledBitmap = new(nothrow) BBitmap(b, format); - fClickedBitmap = new(nothrow) BBitmap(b, format); - fDisabledClickedBitmap = new(nothrow) BBitmap(b, format); + fNormalBitmap = new(std::nothrow) BBitmap(b, format); + fDisabledBitmap = new(std::nothrow) BBitmap(b, format); + fClickedBitmap = new(std::nothrow) BBitmap(b, format); + fDisabledClickedBitmap = new(std::nothrow) BBitmap(b, format); if (IsValid()) { // copy bitmaps from file bitmap uint8* nBits = (uint8*)fNormalBitmap->Bits(); @@ -695,9 +725,12 @@ IconButton::_MakeBitmaps(const BBitmap* bitmap) nBits[nOffset + 2] = fBits[fOffset + 2]; nBits[nOffset + 3] = 255; // clicked bits are darker (lame method...) - cBits[nOffset + 0] = (uint8)((float)nBits[nOffset + 0] * 0.8); - cBits[nOffset + 1] = (uint8)((float)nBits[nOffset + 1] * 0.8); - cBits[nOffset + 2] = (uint8)((float)nBits[nOffset + 2] * 0.8); + cBits[nOffset + 0] = (uint8)((float)nBits[nOffset + 0] + * 0.8); + cBits[nOffset + 1] = (uint8)((float)nBits[nOffset + 1] + * 0.8); + cBits[nOffset + 2] = (uint8)((float)nBits[nOffset + 2] + * 0.8); cBits[nOffset + 3] = 255; // disabled bits have less contrast (lame method...) uint8 grey = 216; @@ -741,15 +774,22 @@ IconButton::_MakeBitmaps(const BBitmap* bitmap) cBits[nOffset + 2] = (uint8)(nBits[nOffset + 2] * 0.8); cBits[nOffset + 3] = fBits[fOffset + 3]; // disabled bits have less opacity - dBits[nOffset + 0] = fBits[fOffset + 0]; - dBits[nOffset + 1] = fBits[fOffset + 1]; - dBits[nOffset + 2] = fBits[fOffset + 2]; - dBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.5); + + uint8 grey = ((uint16)nBits[nOffset + 0] * 10 + + nBits[nOffset + 1] * 60 + + nBits[nOffset + 2] * 30) / 100; + float dist = (nBits[nOffset + 0] - grey) * 0.3; + dBits[nOffset + 0] = (uint8)(grey + dist); + dist = (nBits[nOffset + 1] - grey) * 0.3; + dBits[nOffset + 1] = (uint8)(grey + dist); + dist = (nBits[nOffset + 2] - grey) * 0.3; + dBits[nOffset + 2] = (uint8)(grey + dist); + dBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); // disabled bits have less contrast (lame method...) - dcBits[nOffset + 0] = (uint8)(nBits[nOffset + 0] * 0.8); - dcBits[nOffset + 1] = (uint8)(nBits[nOffset + 1] * 0.8); - dcBits[nOffset + 2] = (uint8)(nBits[nOffset + 2] * 0.8); - dcBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.5); + dcBits[nOffset + 0] = (uint8)(dBits[nOffset + 0] * 0.8); + dcBits[nOffset + 1] = (uint8)(dBits[nOffset + 1] * 0.8); + dcBits[nOffset + 2] = (uint8)(dBits[nOffset + 2] * 0.8); + dcBits[nOffset + 3] = (uint8)(fBits[fOffset + 3] * 0.3); } nBits += nbpr; dBits += nbpr; @@ -759,26 +799,25 @@ IconButton::_MakeBitmaps(const BBitmap* bitmap) } // unsupported format } else { - printf("IconButton::_MakeBitmaps() - " - "bitmap has unsupported colorspace\n"); + printf("BIconButton::_MakeBitmaps() - bitmap has unsupported " + "colorspace\n"); status = B_MISMATCHED_VALUES; _DeleteBitmaps(); } } else { - printf("IconButton::_MakeBitmaps() - " - "error allocating local bitmaps\n"); + printf("BIconButton::_MakeBitmaps() - error allocating local " + "bitmaps\n"); status = B_NO_MEMORY; _DeleteBitmaps(); } } else - printf("IconButton::_MakeBitmaps() - " - "bitmap is not valid\n"); + printf("BIconButton::_MakeBitmaps() - bitmap is not valid\n"); return status; } -// _DeleteBitmaps + void -IconButton::_DeleteBitmaps() +BIconButton::_DeleteBitmaps() { delete fNormalBitmap; fNormalBitmap = NULL; @@ -790,9 +829,9 @@ IconButton::_DeleteBitmaps() fDisabledClickedBitmap = NULL; } -// _Update + void -IconButton::_Update() +BIconButton::_Update() { if (LockLooper()) { Invalidate(); @@ -800,47 +839,30 @@ IconButton::_Update() } } -// _AddFlags + void -IconButton::_AddFlags(uint32 flags) +BIconButton::_AddFlags(uint32 flags) { - if (!(fButtonState & flags)) { + if (!_HasFlags(flags)) { fButtonState |= flags; _Update(); } } -// _ClearFlags + void -IconButton::_ClearFlags(uint32 flags) +BIconButton::_ClearFlags(uint32 flags) { - if (fButtonState & flags) { + if (_HasFlags(flags)) { fButtonState &= ~flags; _Update(); } } -// _HasFlags + bool -IconButton::_HasFlags(uint32 flags) const +BIconButton::_HasFlags(uint32 flags) const { - return (fButtonState & flags); + return (fButtonState & flags) != 0; } -// _DrawFrame -void -IconButton::_DrawFrame(BRect r, rgb_color col1, rgb_color col2, - rgb_color col3, rgb_color col4) -{ - BeginLineArray(8); - AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col1); - AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col1); - AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col2); - AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col2); - r.InsetBy(1.0, 1.0); - AddLine(BPoint(r.left, r.bottom), BPoint(r.left, r.top), col3); - AddLine(BPoint(r.left + 1.0, r.top), BPoint(r.right, r.top), col3); - AddLine(BPoint(r.right, r.top + 1.0), BPoint(r.right, r.bottom), col4); - AddLine(BPoint(r.right - 1.0, r.bottom), BPoint(r.left + 1.0, r.bottom), col4); - EndLineArray(); -} diff --git a/src/kits/shared/Jamfile b/src/kits/shared/Jamfile index 22e6eeebd2..d26c4085a8 100644 --- a/src/kits/shared/Jamfile +++ b/src/kits/shared/Jamfile @@ -3,7 +3,7 @@ SubDir HAIKU_TOP src kits shared ; SetSubDirSupportedPlatformsBeOSCompatible ; AddSubDirSupportedPlatforms libbe_test ; -UseLibraryHeaders agg ; +UseLibraryHeaders agg icon ; UsePrivateHeaders shared libbe ; UseHeaders [ FDirName $(HAIKU_COMMON_DEBUG_OBJECT_DIR) servers input ] ; UseHeaders [ FDirName $(HAIKU_TOP) src kits ] ; @@ -19,6 +19,7 @@ StaticLibrary libshared.a : CommandPipe.cpp DragTrackingFilter.cpp HashString.cpp + IconButton.cpp Keymap.cpp NaturalCompare.cpp QueryFile.cpp