166ee6532SAndrew Lindesay /* 266ee6532SAndrew Lindesay * Copyright 2024, Andrew Lindesay <apl@lindesay.co.nz>. 366ee6532SAndrew Lindesay * All rights reserved. Distributed under the terms of the MIT License. 466ee6532SAndrew Lindesay */ 566ee6532SAndrew Lindesay 666ee6532SAndrew Lindesay #include "SharedIcons.h" 766ee6532SAndrew Lindesay 8c3cad236SAndrew Lindesay #include <ControlLook.h> 966ee6532SAndrew Lindesay #include <IconUtils.h> 1066ee6532SAndrew Lindesay #include <Resources.h> 1166ee6532SAndrew Lindesay 1266ee6532SAndrew Lindesay #include "BitmapHolder.h" 1366ee6532SAndrew Lindesay #include "HaikuDepotConstants.h" 1466ee6532SAndrew Lindesay #include "Logger.h" 1566ee6532SAndrew Lindesay #include "support.h" 1666ee6532SAndrew Lindesay 1766ee6532SAndrew Lindesay 18*3dbcc100SAndrew Lindesay BitmapHolderRef SharedIcons::sIconStarBlue12Scaled; 1966ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconStarBlue16Scaled; 2066ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconStarGrey16Scaled; 2166ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconInstalled16Scaled; 2266ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconArrowLeft22Scaled; 2366ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconArrowRight22Scaled; 2466ee6532SAndrew Lindesay BitmapHolderRef SharedIcons::sIconHTMLPackage16Scaled; 2566ee6532SAndrew Lindesay 2666ee6532SAndrew Lindesay 2766ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 28*3dbcc100SAndrew Lindesay SharedIcons::IconStarBlue12Scaled() 29*3dbcc100SAndrew Lindesay { 30*3dbcc100SAndrew Lindesay if (!SharedIcons::sIconStarBlue12Scaled.IsSet()) { 31*3dbcc100SAndrew Lindesay SharedIcons::sIconStarBlue12Scaled 32*3dbcc100SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_BLUE, 12); 33*3dbcc100SAndrew Lindesay } 34*3dbcc100SAndrew Lindesay return SharedIcons::sIconStarBlue12Scaled; 35*3dbcc100SAndrew Lindesay } 36*3dbcc100SAndrew Lindesay 37*3dbcc100SAndrew Lindesay 38*3dbcc100SAndrew Lindesay /*static*/ BitmapHolderRef 3966ee6532SAndrew Lindesay SharedIcons::IconStarBlue16Scaled() 4066ee6532SAndrew Lindesay { 4166ee6532SAndrew Lindesay if (!SharedIcons::sIconStarBlue16Scaled.IsSet()) { 4266ee6532SAndrew Lindesay SharedIcons::sIconStarBlue16Scaled 4366ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_BLUE, 16); 4466ee6532SAndrew Lindesay } 4566ee6532SAndrew Lindesay return SharedIcons::sIconStarBlue16Scaled; 4666ee6532SAndrew Lindesay } 4766ee6532SAndrew Lindesay 4866ee6532SAndrew Lindesay 4966ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 5066ee6532SAndrew Lindesay SharedIcons::IconStarGrey16Scaled() 5166ee6532SAndrew Lindesay { 5266ee6532SAndrew Lindesay if (!SharedIcons::sIconStarGrey16Scaled.IsSet()) { 5366ee6532SAndrew Lindesay SharedIcons::sIconStarGrey16Scaled 5466ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_GREY, 16); 5566ee6532SAndrew Lindesay } 5666ee6532SAndrew Lindesay return SharedIcons::sIconStarGrey16Scaled; 5766ee6532SAndrew Lindesay } 5866ee6532SAndrew Lindesay 5966ee6532SAndrew Lindesay 6066ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 6166ee6532SAndrew Lindesay SharedIcons::IconInstalled16Scaled() 6266ee6532SAndrew Lindesay { 6366ee6532SAndrew Lindesay if (!SharedIcons::sIconInstalled16Scaled.IsSet()) { 6466ee6532SAndrew Lindesay SharedIcons::sIconInstalled16Scaled 6566ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_INSTALLED, 16); 6666ee6532SAndrew Lindesay } 6766ee6532SAndrew Lindesay return SharedIcons::sIconInstalled16Scaled; 6866ee6532SAndrew Lindesay } 6966ee6532SAndrew Lindesay 7066ee6532SAndrew Lindesay 7166ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 7266ee6532SAndrew Lindesay SharedIcons::IconArrowLeft22Scaled() 7366ee6532SAndrew Lindesay { 7466ee6532SAndrew Lindesay if (!SharedIcons::sIconArrowLeft22Scaled.IsSet()) { 7566ee6532SAndrew Lindesay SharedIcons::sIconArrowLeft22Scaled 7666ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_ARROW_LEFT, 22); 7766ee6532SAndrew Lindesay } 7866ee6532SAndrew Lindesay return SharedIcons::sIconArrowLeft22Scaled; 7966ee6532SAndrew Lindesay } 8066ee6532SAndrew Lindesay 8166ee6532SAndrew Lindesay 8266ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 8366ee6532SAndrew Lindesay SharedIcons::IconArrowRight22Scaled() 8466ee6532SAndrew Lindesay { 8566ee6532SAndrew Lindesay if (!SharedIcons::sIconArrowRight22Scaled.IsSet()) { 8666ee6532SAndrew Lindesay SharedIcons::sIconArrowRight22Scaled 8766ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_ARROW_RIGHT, 22); 8866ee6532SAndrew Lindesay } 8966ee6532SAndrew Lindesay return SharedIcons::sIconArrowRight22Scaled; 9066ee6532SAndrew Lindesay } 9166ee6532SAndrew Lindesay 9266ee6532SAndrew Lindesay 9366ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 9466ee6532SAndrew Lindesay SharedIcons::IconHTMLPackage16Scaled() 9566ee6532SAndrew Lindesay { 9666ee6532SAndrew Lindesay if (!SharedIcons::sIconHTMLPackage16Scaled.IsSet()) { 9766ee6532SAndrew Lindesay SharedIcons::sIconHTMLPackage16Scaled 9866ee6532SAndrew Lindesay = SharedIcons::_CreateIconForMimeType("text/html", 16); 9966ee6532SAndrew Lindesay } 10066ee6532SAndrew Lindesay return SharedIcons::sIconHTMLPackage16Scaled; 10166ee6532SAndrew Lindesay } 10266ee6532SAndrew Lindesay 10366ee6532SAndrew Lindesay 10466ee6532SAndrew Lindesay /*static*/ void 10566ee6532SAndrew Lindesay SharedIcons::UnsetAllIcons() 10666ee6532SAndrew Lindesay { 107*3dbcc100SAndrew Lindesay sIconStarBlue12Scaled.Unset(); 10866ee6532SAndrew Lindesay sIconStarBlue16Scaled.Unset(); 10966ee6532SAndrew Lindesay sIconStarGrey16Scaled.Unset(); 11066ee6532SAndrew Lindesay sIconInstalled16Scaled.Unset(); 11166ee6532SAndrew Lindesay sIconArrowLeft22Scaled.Unset(); 11266ee6532SAndrew Lindesay sIconArrowRight22Scaled.Unset(); 11366ee6532SAndrew Lindesay 11466ee6532SAndrew Lindesay sIconHTMLPackage16Scaled.Unset(); 11566ee6532SAndrew Lindesay } 11666ee6532SAndrew Lindesay 11766ee6532SAndrew Lindesay 11866ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 11966ee6532SAndrew Lindesay SharedIcons::_CreateIconForResource(int32 resourceID, uint32 size) 12066ee6532SAndrew Lindesay { 12166ee6532SAndrew Lindesay BitmapHolderRef result(NULL); 12266ee6532SAndrew Lindesay 12366ee6532SAndrew Lindesay if (SharedIcons::_CreateIconForResourceChecked(resourceID, size, &result) != B_OK) { 12466ee6532SAndrew Lindesay HDERROR("unable to create bitmap for resource [%d]", resourceID); 12566ee6532SAndrew Lindesay debugger("unable to create bitmap for resource"); 12666ee6532SAndrew Lindesay // the resource is bundled into the build product so not being able to find it is an 12766ee6532SAndrew Lindesay // illegal state. 12866ee6532SAndrew Lindesay } 12966ee6532SAndrew Lindesay 13066ee6532SAndrew Lindesay return result; 13166ee6532SAndrew Lindesay } 13266ee6532SAndrew Lindesay 13366ee6532SAndrew Lindesay 13466ee6532SAndrew Lindesay /*static*/ BitmapHolderRef 13566ee6532SAndrew Lindesay SharedIcons::_CreateIconForMimeType(const char* mimeType, uint32 size) 13666ee6532SAndrew Lindesay { 13766ee6532SAndrew Lindesay BitmapHolderRef result(NULL); 13866ee6532SAndrew Lindesay 13966ee6532SAndrew Lindesay if (SharedIcons::_CreateIconForMimeTypeChecked(mimeType, size, &result) != B_OK) 14066ee6532SAndrew Lindesay HDERROR("unable to create bitmap for mime type [%s]", mimeType); 14166ee6532SAndrew Lindesay 14266ee6532SAndrew Lindesay return result; 14366ee6532SAndrew Lindesay } 14466ee6532SAndrew Lindesay 14566ee6532SAndrew Lindesay 14666ee6532SAndrew Lindesay /*static*/ status_t 14766ee6532SAndrew Lindesay SharedIcons::_CreateIconForResourceChecked(int32 resourceID, uint32 size, 14866ee6532SAndrew Lindesay BitmapHolderRef* bitmapHolderRef) 14966ee6532SAndrew Lindesay { 15066ee6532SAndrew Lindesay if (size > MAX_IMAGE_SIZE || size == 0) 15166ee6532SAndrew Lindesay return B_BAD_VALUE; 15266ee6532SAndrew Lindesay 15366ee6532SAndrew Lindesay BResources resources; 15466ee6532SAndrew Lindesay status_t status = get_app_resources(resources); 15566ee6532SAndrew Lindesay 15666ee6532SAndrew Lindesay size_t dataSize; 15766ee6532SAndrew Lindesay const void* data = NULL; 15866ee6532SAndrew Lindesay 15966ee6532SAndrew Lindesay if (status == B_OK) 16066ee6532SAndrew Lindesay data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, &dataSize); 16166ee6532SAndrew Lindesay 16266ee6532SAndrew Lindesay if (data == NULL) { 16366ee6532SAndrew Lindesay HDERROR("unable to read the resource [%d]", resourceID); 16466ee6532SAndrew Lindesay status = B_ERROR; 16566ee6532SAndrew Lindesay } 16666ee6532SAndrew Lindesay 167c3cad236SAndrew Lindesay BSize iconSize = BControlLook::ComposeIconSize(size); 168c3cad236SAndrew Lindesay BBitmap* bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32); 16966ee6532SAndrew Lindesay status = bitmap->InitCheck(); 17066ee6532SAndrew Lindesay 17166ee6532SAndrew Lindesay if (status == B_OK) 17266ee6532SAndrew Lindesay status = BIconUtils::GetVectorIcon(reinterpret_cast<const uint8*>(data), dataSize, bitmap); 17366ee6532SAndrew Lindesay 17466ee6532SAndrew Lindesay if (status != B_OK) { 17566ee6532SAndrew Lindesay HDERROR("unable to parse the resource [%d] as a vector icon", resourceID); 17666ee6532SAndrew Lindesay delete bitmap; 17766ee6532SAndrew Lindesay bitmap = NULL; 17866ee6532SAndrew Lindesay } else { 17966ee6532SAndrew Lindesay *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true); 18066ee6532SAndrew Lindesay } 18166ee6532SAndrew Lindesay 18266ee6532SAndrew Lindesay return status; 18366ee6532SAndrew Lindesay } 18466ee6532SAndrew Lindesay 18566ee6532SAndrew Lindesay 18666ee6532SAndrew Lindesay /*static*/ status_t 18766ee6532SAndrew Lindesay SharedIcons::_CreateIconForMimeTypeChecked(const char* mimeTypeStr, uint32 size, 18866ee6532SAndrew Lindesay BitmapHolderRef* bitmapHolderRef) 18966ee6532SAndrew Lindesay { 19066ee6532SAndrew Lindesay if (size > MAX_IMAGE_SIZE || size == 0) 19166ee6532SAndrew Lindesay return B_BAD_VALUE; 19266ee6532SAndrew Lindesay 19366ee6532SAndrew Lindesay BMimeType mimeType(mimeTypeStr); 19466ee6532SAndrew Lindesay status_t status = mimeType.InitCheck(); 19566ee6532SAndrew Lindesay 19666ee6532SAndrew Lindesay uint8* data; 19766ee6532SAndrew Lindesay size_t dataSize; 19866ee6532SAndrew Lindesay 19966ee6532SAndrew Lindesay if (status == B_OK) 20066ee6532SAndrew Lindesay status = mimeType.GetIcon(&data, &dataSize); 20166ee6532SAndrew Lindesay 20266ee6532SAndrew Lindesay BBitmap* bitmap = NULL; 20366ee6532SAndrew Lindesay 20466ee6532SAndrew Lindesay if (status == B_OK) { 205c3cad236SAndrew Lindesay BSize iconSize = BControlLook::ComposeIconSize(size); 206c3cad236SAndrew Lindesay bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32); 20766ee6532SAndrew Lindesay status = bitmap->InitCheck(); 20866ee6532SAndrew Lindesay } 20966ee6532SAndrew Lindesay 21066ee6532SAndrew Lindesay if (status == B_OK) 21166ee6532SAndrew Lindesay status = BIconUtils::GetVectorIcon(data, dataSize, bitmap); 21266ee6532SAndrew Lindesay 21366ee6532SAndrew Lindesay if (status != B_OK) { 21466ee6532SAndrew Lindesay delete bitmap; 21566ee6532SAndrew Lindesay bitmap = NULL; 21666ee6532SAndrew Lindesay } else { 21766ee6532SAndrew Lindesay *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true); 21866ee6532SAndrew Lindesay } 21966ee6532SAndrew Lindesay 22066ee6532SAndrew Lindesay return status; 22166ee6532SAndrew Lindesay } 222