From 97bf0ce362dbcc6f8ee0e6a94a831214eae2431f Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 22 Dec 2013 14:44:27 +0100 Subject: [PATCH] BControl: Move icon code to separate class BIcon --- headers/os/interface/Control.h | 13 +- src/kits/interface/Control.cpp | 482 +-------------------------------- src/kits/interface/Jamfile | 1 + 3 files changed, 21 insertions(+), 475 deletions(-) diff --git a/headers/os/interface/Control.h b/headers/os/interface/Control.h index 3bd9a10472..a82bbb4e69 100644 --- a/headers/os/interface/Control.h +++ b/headers/os/interface/Control.h @@ -19,6 +19,10 @@ enum { class BBitmap; class BWindow; +namespace BPrivate { + class BIcon; +}; + class BControl : public BView, public BInvoker { public: @@ -88,13 +92,6 @@ private: struct IconData; private: - static BBitmap* _ConvertToRGB32(const BBitmap* bitmap, - bool noAppServerLink = false); - static status_t _TrimBitmap(const BBitmap* bitmap, - bool keepAspect, BBitmap*& _trimmedBitmap); - status_t _MakeBitmaps(const BBitmap* bitmap, - uint32 flags); - virtual void _ReservedControl2(); virtual void _ReservedControl3(); virtual void _ReservedControl4(); @@ -110,7 +107,7 @@ private: bool fFocusChanging; bool fTracking; bool fWantsNav; - IconData* fIconData; + BPrivate::BIcon* fIcon; #ifdef B_HAIKU_64_BIT uint32 _reserved[2]; diff --git a/src/kits/interface/Control.cpp b/src/kits/interface/Control.cpp index 0d81e501d8..7e416078c5 100644 --- a/src/kits/interface/Control.cpp +++ b/src/kits/interface/Control.cpp @@ -4,7 +4,6 @@ * * Authors: * Marc Flerackers, mflerackers@androme.be - * Stephan Aßmus, superstippi@gmx.de * Ingo Weinhold, ingo_weinhold@gmx.de */ @@ -14,14 +13,12 @@ #include #include -#include #include -#include #include #include -#include #include +#include static property_info sPropertyList[] = { @@ -50,85 +47,6 @@ static property_info sPropertyList[] = { }; -struct BControl::IconData { -public: - IconData() - : - fEnabledBitmaps(8, true), - fDisabledBitmaps(8, true) - { - } - - ~IconData() - { - DeleteBitmaps(); - } - - BBitmap* CreateBitmap(const BRect& bounds, color_space colorSpace, - uint32 which) - { - BBitmap* bitmap = new(std::nothrow) BBitmap(bounds, colorSpace); - if (bitmap == NULL || !bitmap->IsValid() || !SetBitmap(bitmap, which)) { - delete bitmap; - return NULL; - } - - return bitmap; - } - - BBitmap* CopyBitmap(const BBitmap& bitmapToClone, uint32 which) - { - BBitmap* bitmap = new(std::nothrow) BBitmap(bitmapToClone); - if (bitmap == NULL || !bitmap->IsValid() || !SetBitmap(bitmap, which)) { - delete bitmap; - return NULL; - } - - return bitmap; - } - - bool SetBitmap(BBitmap* bitmap, uint32 which) - { - IconList& list = (which & B_DISABLED_ICON_BITMAP) == 0 - ? fEnabledBitmaps : fDisabledBitmaps; - which &= ~uint32(B_DISABLED_ICON_BITMAP); - - int32 count = list.CountItems(); - if ((int32)which < count) { - list.ReplaceItem(which, bitmap); - return true; - } - - while (list.CountItems() < (int32)which) { - if (!list.AddItem((BBitmap*)NULL)) - return false; - } - - return list.AddItem(bitmap); - } - - BBitmap* Bitmap(uint32 which) const - { - const IconList& list = (which & B_DISABLED_ICON_BITMAP) == 0 - ? fEnabledBitmaps : fDisabledBitmaps; - return list.ItemAt(which & ~uint32(B_DISABLED_ICON_BITMAP)); - } - - void DeleteBitmaps() - { - fEnabledBitmaps.MakeEmpty(true); - fDisabledBitmaps.MakeEmpty(true); - } - -private: - typedef BObjectList IconList; - -private: - IconList fEnabledBitmaps; - IconList fDisabledBitmaps; -}; - - BControl::BControl(BRect frame, const char *name, const char *label, BMessage *message, uint32 resizingMode, uint32 flags) : BView(frame, name, resizingMode, flags) @@ -154,7 +72,7 @@ BControl::BControl(const char *name, const char *label, BMessage *message, BControl::~BControl() { free(fLabel); - delete fIconData; + delete fIcon; SetMessage(NULL); } @@ -608,88 +526,13 @@ BControl::Perform(perform_code code, void* _data) status_t BControl::SetIcon(const BBitmap* bitmap, uint32 flags) { - if (bitmap == NULL) { - delete fIconData; - fIconData = NULL; - return B_OK; + status_t error = BIcon::UpdateIcon(bitmap, flags, fIcon); + + if (error == B_OK) { + InvalidateLayout(); + Invalidate(); } - if (!bitmap->IsValid()) - return B_BAD_VALUE; - - // check the color space - bool hasAlpha = false; - bool canUseForMakeBitmaps = false; - - switch (bitmap->ColorSpace()) { - case B_RGBA32: - case B_RGBA32_BIG: - hasAlpha = true; - // fall through - case B_RGB32: - case B_RGB32_BIG: - canUseForMakeBitmaps = true; - break; - - case B_UVLA32: - case B_LABA32: - case B_HSIA32: - case B_HSVA32: - case B_HLSA32: - case B_CMYA32: - case B_RGBA15: - case B_RGBA15_BIG: - case B_CMAP8: - hasAlpha = true; - break; - - default: - break; - } - - BBitmap* trimmedBitmap = NULL; - - // trim the bitmap, if requested and the bitmap actually has alpha - status_t error; - if ((flags & (B_TRIM_ICON_BITMAP | B_TRIM_ICON_BITMAP_KEEP_ASPECT)) != 0 - && hasAlpha) { - if (bitmap->ColorSpace() == B_RGBA32) { - error = _TrimBitmap(bitmap, - (flags & B_TRIM_ICON_BITMAP_KEEP_ASPECT) != 0, trimmedBitmap); - } else { - BBitmap* rgb32Bitmap = _ConvertToRGB32(bitmap, true); - if (rgb32Bitmap != NULL) { - error = _TrimBitmap(rgb32Bitmap, - (flags & B_TRIM_ICON_BITMAP_KEEP_ASPECT) != 0, - trimmedBitmap); - delete rgb32Bitmap; - } else - error = B_NO_MEMORY; - } - - if (error != B_OK) - return error; - - bitmap = trimmedBitmap; - canUseForMakeBitmaps = true; - } - - // create the bitmaps - if (canUseForMakeBitmaps) { - error = _MakeBitmaps(bitmap, flags); - } else { - if (BBitmap* rgb32Bitmap = _ConvertToRGB32(bitmap, true)) { - error = _MakeBitmaps(rgb32Bitmap, flags); - delete rgb32Bitmap; - } else - error = B_NO_MEMORY; - } - - delete trimmedBitmap; - - InvalidateLayout(); - Invalidate(); - return error; } @@ -697,43 +540,21 @@ BControl::SetIcon(const BBitmap* bitmap, uint32 flags) status_t BControl::SetIconBitmap(const BBitmap* bitmap, uint32 which, uint32 flags) { - if (fIconData == NULL) { - fIconData = new(std::nothrow) IconData; - if (fIconData == NULL) - return B_NO_MEMORY; + status_t error = BIcon::SetIconBitmap(bitmap, which, flags, fIcon); + + if (error != B_OK) { + InvalidateLayout(); + Invalidate(); } - BBitmap* ourBitmap = NULL; - if (bitmap != NULL) { - if (!bitmap->IsValid()) - return B_BAD_VALUE; - - if ((flags & B_KEEP_ICON_BITMAP) != 0) { - ourBitmap = const_cast(bitmap); - } else { - ourBitmap = _ConvertToRGB32(bitmap); - if (ourBitmap == NULL) - return B_NO_MEMORY; - } - } - - if (!fIconData->SetBitmap(ourBitmap, which)) { - if (ourBitmap != bitmap) - delete ourBitmap; - return B_NO_MEMORY; - } - - InvalidateLayout(); - Invalidate(); - - return B_OK; + return error; } const BBitmap* BControl::IconBitmap(uint32 which) const { - return fIconData != NULL ? fIconData->Bitmap(which) : NULL; + return fIcon != NULL ? fIcon->Bitmap(which) : NULL; } @@ -770,279 +591,6 @@ B_IF_GCC_2(_ReservedControl1__8BControl, _ZN8BControl17_ReservedControl1Ev)( } -/*static*/ BBitmap* -BControl::_ConvertToRGB32(const BBitmap* bitmap, bool noAppServerLink) -{ - BBitmap* rgb32Bitmap = new(std::nothrow) BBitmap(bitmap->Bounds(), - noAppServerLink ? B_BITMAP_NO_SERVER_LINK : 0, B_RGBA32); - if (rgb32Bitmap == NULL) - return NULL; - - if (!rgb32Bitmap->IsValid() || rgb32Bitmap->ImportBits(bitmap)!= B_OK) { - delete rgb32Bitmap; - return NULL; - } - - return rgb32Bitmap; -} - - -/*static*/ status_t -BControl::_TrimBitmap(const BBitmap* bitmap, bool keepAspect, - BBitmap*& _trimmedBitmap) -{ - if (bitmap == NULL || !bitmap->IsValid() - || bitmap->ColorSpace() != B_RGBA32) { - return B_BAD_VALUE; - } - - uint8* bits = (uint8*)bitmap->Bits(); - uint32 bpr = bitmap->BytesPerRow(); - uint32 width = bitmap->Bounds().IntegerWidth() + 1; - uint32 height = bitmap->Bounds().IntegerHeight() + 1; - BRect trimmed(INT32_MAX, INT32_MAX, INT32_MIN, INT32_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 B_BAD_VALUE; - - if (keepAspect) { - float minInset = trimmed.left; - minInset = min_c(minInset, trimmed.top); - minInset = min_c(minInset, bitmap->Bounds().right - trimmed.right); - minInset = min_c(minInset, bitmap->Bounds().bottom - trimmed.bottom); - trimmed = bitmap->Bounds().InsetByCopy(minInset, minInset); - } - trimmed = trimmed & bitmap->Bounds(); - - BBitmap* trimmedBitmap = new(std::nothrow) BBitmap( - trimmed.OffsetToCopy(B_ORIGIN), B_BITMAP_NO_SERVER_LINK, B_RGBA32); - if (trimmedBitmap == NULL) - return B_NO_MEMORY; - - bits = (uint8*)bitmap->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; - } - - _trimmedBitmap = trimmedBitmap; - return B_OK; -} - - -status_t -BControl::_MakeBitmaps(const BBitmap* bitmap, uint32 flags) -{ - // make our own versions of the bitmap - BRect b(bitmap->Bounds()); - - IconData* iconData = new(std::nothrow) IconData; - if (iconData == NULL) - return B_NO_MEMORY; - ObjectDeleter iconDataDeleter(iconData); - - color_space format = bitmap->ColorSpace(); - BBitmap* normalBitmap = iconData->CreateBitmap(b, format, - B_INACTIVE_ICON_BITMAP); - if (normalBitmap == NULL) - return B_NO_MEMORY; - - BBitmap* disabledBitmap = NULL; - if ((flags & B_CREATE_DISABLED_ICON_BITMAPS) != 0) { - disabledBitmap = iconData->CreateBitmap(b, format, - B_INACTIVE_ICON_BITMAP | B_DISABLED_ICON_BITMAP); - if (disabledBitmap == NULL) - return B_NO_MEMORY; - } - - BBitmap* clickedBitmap = NULL; - if ((flags & (B_CREATE_ACTIVE_ICON_BITMAP - | B_CREATE_PARTIALLY_ACTIVE_ICON_BITMAP)) != 0) { - clickedBitmap = iconData->CreateBitmap(b, format, B_ACTIVE_ICON_BITMAP); - if (clickedBitmap == NULL) - return B_NO_MEMORY; - } - - BBitmap* disabledClickedBitmap = NULL; - if (disabledBitmap != NULL && clickedBitmap != NULL) { - disabledClickedBitmap = iconData->CreateBitmap(b, format, - B_ACTIVE_ICON_BITMAP | B_DISABLED_ICON_BITMAP); - if (disabledClickedBitmap == NULL) - return B_NO_MEMORY; - } - - // copy bitmaps from file bitmap - uint8* nBits = normalBitmap != NULL ? (uint8*)normalBitmap->Bits() : NULL; - uint8* dBits = disabledBitmap != NULL - ? (uint8*)disabledBitmap->Bits() : NULL; - uint8* cBits = clickedBitmap != NULL ? (uint8*)clickedBitmap->Bits() : NULL; - uint8* dcBits = disabledClickedBitmap != NULL - ? (uint8*)disabledClickedBitmap->Bits() : NULL; - uint8* fBits = (uint8*)bitmap->Bits(); - int32 nbpr = normalBitmap->BytesPerRow(); - int32 fbpr = bitmap->BytesPerRow(); - int32 pixels = b.IntegerWidth() + 1; - int32 lines = b.IntegerHeight() + 1; - if (format == B_RGB32 || format == B_RGB32_BIG) { - // nontransparent version - - // iterate over color components - for (int32 y = 0; y < lines; y++) { - for (int32 x = 0; x < pixels; x++) { - int32 nOffset = 4 * x; - int32 fOffset = 4 * x; - nBits[nOffset + 0] = fBits[fOffset + 0]; - nBits[nOffset + 1] = fBits[fOffset + 1]; - nBits[nOffset + 2] = fBits[fOffset + 2]; - nBits[nOffset + 3] = 255; - - // clicked bits are darker (lame method...) - if (cBits != NULL) { - 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...) - if (dBits != NULL) { - uint8 grey = 216; - float dist = (nBits[nOffset + 0] - grey) * 0.4; - dBits[nOffset + 0] = (uint8)(grey + dist); - dist = (nBits[nOffset + 1] - grey) * 0.4; - dBits[nOffset + 1] = (uint8)(grey + dist); - dist = (nBits[nOffset + 2] - grey) * 0.4; - dBits[nOffset + 2] = (uint8)(grey + dist); - dBits[nOffset + 3] = 255; - } - - // disabled bits have less contrast (lame method...) - if (dcBits != NULL) { - uint8 grey = 188; - float dist = (nBits[nOffset + 0] - grey) * 0.4; - dcBits[nOffset + 0] = (uint8)(grey + dist); - dist = (nBits[nOffset + 1] - grey) * 0.4; - dcBits[nOffset + 1] = (uint8)(grey + dist); - dist = (nBits[nOffset + 2] - grey) * 0.4; - dcBits[nOffset + 2] = (uint8)(grey + dist); - dcBits[nOffset + 3] = 255; - } - } - fBits += fbpr; - nBits += nbpr; - if (cBits != NULL) - cBits += nbpr; - if (dBits != NULL) - dBits += nbpr; - if (dcBits != NULL) - dcBits += nbpr; - } - } else if (format == B_RGBA32 || format == B_RGBA32_BIG) { - // transparent version - - // iterate over color components - for (int32 y = 0; y < lines; y++) { - for (int32 x = 0; x < pixels; x++) { - int32 nOffset = 4 * x; - int32 fOffset = 4 * x; - nBits[nOffset + 0] = fBits[fOffset + 0]; - nBits[nOffset + 1] = fBits[fOffset + 1]; - nBits[nOffset + 2] = fBits[fOffset + 2]; - nBits[nOffset + 3] = fBits[fOffset + 3]; - - // clicked bits are darker (lame method...) - if (cBits != NULL) { - cBits[nOffset + 0] = (uint8)(nBits[nOffset + 0] * 0.8); - cBits[nOffset + 1] = (uint8)(nBits[nOffset + 1] * 0.8); - cBits[nOffset + 2] = (uint8)(nBits[nOffset + 2] * 0.8); - cBits[nOffset + 3] = fBits[fOffset + 3]; - } - - // disabled bits have less opacity - if (dBits != NULL) { - 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...) - if (dcBits != NULL) { - 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); - } - } - fBits += fbpr; - nBits += nbpr; - if (cBits != NULL) - cBits += nbpr; - if (dBits != NULL) - dBits += nbpr; - if (dcBits != NULL) - dcBits += nbpr; - } - } else { - // unsupported format - return B_BAD_VALUE; - } - - // make the partially-on bitmaps a copy of the on bitmaps - if ((flags & B_CREATE_PARTIALLY_ACTIVE_ICON_BITMAP) != 0) { - if (iconData->CopyBitmap(clickedBitmap, - B_PARTIALLY_ACTIVATE_ICON_BITMAP) == NULL) { - return B_NO_MEMORY; - } - if ((flags & B_CREATE_DISABLED_ICON_BITMAPS) != 0) { - if (iconData->CopyBitmap(disabledClickedBitmap, - B_PARTIALLY_ACTIVATE_ICON_BITMAP | B_DISABLED_ICON_BITMAP) - == NULL) { - return B_NO_MEMORY; - } - } - } - - delete fIconData; - fIconData = iconDataDeleter.Detach(); - return B_OK; -} - - void BControl::_ReservedControl2() {} void BControl::_ReservedControl3() {} void BControl::_ReservedControl4() {} @@ -1065,7 +613,7 @@ BControl::InitData(BMessage *data) fFocusChanging = false; fTracking = false; fWantsNav = Flags() & B_NAVIGABLE; - fIconData = NULL; + fIcon = NULL; if (data && data->HasString("_fname")) SetFont(be_plain_font, B_FONT_FAMILY_AND_STYLE); diff --git a/src/kits/interface/Jamfile b/src/kits/interface/Jamfile index ad31fd28f3..15eb964c2b 100644 --- a/src/kits/interface/Jamfile +++ b/src/kits/interface/Jamfile @@ -74,6 +74,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { GroupLayout.cpp GroupLayoutBuilder.cpp GroupView.cpp + Icon.cpp Input.cpp InterfaceDefs.cpp Layout.cpp