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
183dbcc100SAndrew 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;
25*6afa94a0SAndrew Lindesay BitmapHolderRef SharedIcons::sNative16Scaled;
2666ee6532SAndrew Lindesay
2766ee6532SAndrew Lindesay
2866ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconStarBlue12Scaled()293dbcc100SAndrew Lindesay SharedIcons::IconStarBlue12Scaled()
303dbcc100SAndrew Lindesay {
313dbcc100SAndrew Lindesay if (!SharedIcons::sIconStarBlue12Scaled.IsSet()) {
323dbcc100SAndrew Lindesay SharedIcons::sIconStarBlue12Scaled
333dbcc100SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_BLUE, 12);
343dbcc100SAndrew Lindesay }
353dbcc100SAndrew Lindesay return SharedIcons::sIconStarBlue12Scaled;
363dbcc100SAndrew Lindesay }
373dbcc100SAndrew Lindesay
383dbcc100SAndrew Lindesay
393dbcc100SAndrew Lindesay /*static*/ BitmapHolderRef
IconStarBlue16Scaled()4066ee6532SAndrew Lindesay SharedIcons::IconStarBlue16Scaled()
4166ee6532SAndrew Lindesay {
4266ee6532SAndrew Lindesay if (!SharedIcons::sIconStarBlue16Scaled.IsSet()) {
4366ee6532SAndrew Lindesay SharedIcons::sIconStarBlue16Scaled
4466ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_BLUE, 16);
4566ee6532SAndrew Lindesay }
4666ee6532SAndrew Lindesay return SharedIcons::sIconStarBlue16Scaled;
4766ee6532SAndrew Lindesay }
4866ee6532SAndrew Lindesay
4966ee6532SAndrew Lindesay
5066ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconStarGrey16Scaled()5166ee6532SAndrew Lindesay SharedIcons::IconStarGrey16Scaled()
5266ee6532SAndrew Lindesay {
5366ee6532SAndrew Lindesay if (!SharedIcons::sIconStarGrey16Scaled.IsSet()) {
5466ee6532SAndrew Lindesay SharedIcons::sIconStarGrey16Scaled
5566ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_STAR_GREY, 16);
5666ee6532SAndrew Lindesay }
5766ee6532SAndrew Lindesay return SharedIcons::sIconStarGrey16Scaled;
5866ee6532SAndrew Lindesay }
5966ee6532SAndrew Lindesay
6066ee6532SAndrew Lindesay
6166ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconInstalled16Scaled()6266ee6532SAndrew Lindesay SharedIcons::IconInstalled16Scaled()
6366ee6532SAndrew Lindesay {
6466ee6532SAndrew Lindesay if (!SharedIcons::sIconInstalled16Scaled.IsSet()) {
6566ee6532SAndrew Lindesay SharedIcons::sIconInstalled16Scaled
6666ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_INSTALLED, 16);
6766ee6532SAndrew Lindesay }
6866ee6532SAndrew Lindesay return SharedIcons::sIconInstalled16Scaled;
6966ee6532SAndrew Lindesay }
7066ee6532SAndrew Lindesay
7166ee6532SAndrew Lindesay
7266ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconArrowLeft22Scaled()7366ee6532SAndrew Lindesay SharedIcons::IconArrowLeft22Scaled()
7466ee6532SAndrew Lindesay {
7566ee6532SAndrew Lindesay if (!SharedIcons::sIconArrowLeft22Scaled.IsSet()) {
7666ee6532SAndrew Lindesay SharedIcons::sIconArrowLeft22Scaled
7766ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_ARROW_LEFT, 22);
7866ee6532SAndrew Lindesay }
7966ee6532SAndrew Lindesay return SharedIcons::sIconArrowLeft22Scaled;
8066ee6532SAndrew Lindesay }
8166ee6532SAndrew Lindesay
8266ee6532SAndrew Lindesay
8366ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconArrowRight22Scaled()8466ee6532SAndrew Lindesay SharedIcons::IconArrowRight22Scaled()
8566ee6532SAndrew Lindesay {
8666ee6532SAndrew Lindesay if (!SharedIcons::sIconArrowRight22Scaled.IsSet()) {
8766ee6532SAndrew Lindesay SharedIcons::sIconArrowRight22Scaled
8866ee6532SAndrew Lindesay = SharedIcons::_CreateIconForResource(RSRC_ARROW_RIGHT, 22);
8966ee6532SAndrew Lindesay }
9066ee6532SAndrew Lindesay return SharedIcons::sIconArrowRight22Scaled;
9166ee6532SAndrew Lindesay }
9266ee6532SAndrew Lindesay
9366ee6532SAndrew Lindesay
9466ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
IconHTMLPackage16Scaled()9566ee6532SAndrew Lindesay SharedIcons::IconHTMLPackage16Scaled()
9666ee6532SAndrew Lindesay {
9766ee6532SAndrew Lindesay if (!SharedIcons::sIconHTMLPackage16Scaled.IsSet()) {
9866ee6532SAndrew Lindesay SharedIcons::sIconHTMLPackage16Scaled
9966ee6532SAndrew Lindesay = SharedIcons::_CreateIconForMimeType("text/html", 16);
10066ee6532SAndrew Lindesay }
10166ee6532SAndrew Lindesay return SharedIcons::sIconHTMLPackage16Scaled;
10266ee6532SAndrew Lindesay }
10366ee6532SAndrew Lindesay
10466ee6532SAndrew Lindesay
105*6afa94a0SAndrew Lindesay /*static*/ BitmapHolderRef
IconNative16Scaled()106*6afa94a0SAndrew Lindesay SharedIcons::IconNative16Scaled()
107*6afa94a0SAndrew Lindesay {
108*6afa94a0SAndrew Lindesay if (!SharedIcons::sNative16Scaled.IsSet())
109*6afa94a0SAndrew Lindesay SharedIcons::sNative16Scaled = SharedIcons::_CreateIconForResource(RSRC_NATIVE, 16);
110*6afa94a0SAndrew Lindesay return SharedIcons::sNative16Scaled;
111*6afa94a0SAndrew Lindesay }
112*6afa94a0SAndrew Lindesay
113*6afa94a0SAndrew Lindesay
11466ee6532SAndrew Lindesay /*static*/ void
UnsetAllIcons()11566ee6532SAndrew Lindesay SharedIcons::UnsetAllIcons()
11666ee6532SAndrew Lindesay {
1173dbcc100SAndrew Lindesay sIconStarBlue12Scaled.Unset();
11866ee6532SAndrew Lindesay sIconStarBlue16Scaled.Unset();
11966ee6532SAndrew Lindesay sIconStarGrey16Scaled.Unset();
12066ee6532SAndrew Lindesay sIconInstalled16Scaled.Unset();
12166ee6532SAndrew Lindesay sIconArrowLeft22Scaled.Unset();
12266ee6532SAndrew Lindesay sIconArrowRight22Scaled.Unset();
123*6afa94a0SAndrew Lindesay sNative16Scaled.Unset();
12466ee6532SAndrew Lindesay
12566ee6532SAndrew Lindesay sIconHTMLPackage16Scaled.Unset();
12666ee6532SAndrew Lindesay }
12766ee6532SAndrew Lindesay
12866ee6532SAndrew Lindesay
12966ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
_CreateIconForResource(int32 resourceID,uint32 size)13066ee6532SAndrew Lindesay SharedIcons::_CreateIconForResource(int32 resourceID, uint32 size)
13166ee6532SAndrew Lindesay {
13266ee6532SAndrew Lindesay BitmapHolderRef result(NULL);
13366ee6532SAndrew Lindesay
13466ee6532SAndrew Lindesay if (SharedIcons::_CreateIconForResourceChecked(resourceID, size, &result) != B_OK) {
13566ee6532SAndrew Lindesay HDERROR("unable to create bitmap for resource [%d]", resourceID);
13666ee6532SAndrew Lindesay debugger("unable to create bitmap for resource");
13766ee6532SAndrew Lindesay // the resource is bundled into the build product so not being able to find it is an
13866ee6532SAndrew Lindesay // illegal state.
13966ee6532SAndrew Lindesay }
14066ee6532SAndrew Lindesay
14166ee6532SAndrew Lindesay return result;
14266ee6532SAndrew Lindesay }
14366ee6532SAndrew Lindesay
14466ee6532SAndrew Lindesay
14566ee6532SAndrew Lindesay /*static*/ BitmapHolderRef
_CreateIconForMimeType(const char * mimeType,uint32 size)14666ee6532SAndrew Lindesay SharedIcons::_CreateIconForMimeType(const char* mimeType, uint32 size)
14766ee6532SAndrew Lindesay {
14866ee6532SAndrew Lindesay BitmapHolderRef result(NULL);
14966ee6532SAndrew Lindesay
15066ee6532SAndrew Lindesay if (SharedIcons::_CreateIconForMimeTypeChecked(mimeType, size, &result) != B_OK)
15166ee6532SAndrew Lindesay HDERROR("unable to create bitmap for mime type [%s]", mimeType);
15266ee6532SAndrew Lindesay
15366ee6532SAndrew Lindesay return result;
15466ee6532SAndrew Lindesay }
15566ee6532SAndrew Lindesay
15666ee6532SAndrew Lindesay
15766ee6532SAndrew Lindesay /*static*/ status_t
_CreateIconForResourceChecked(int32 resourceID,uint32 size,BitmapHolderRef * bitmapHolderRef)15866ee6532SAndrew Lindesay SharedIcons::_CreateIconForResourceChecked(int32 resourceID, uint32 size,
15966ee6532SAndrew Lindesay BitmapHolderRef* bitmapHolderRef)
16066ee6532SAndrew Lindesay {
16166ee6532SAndrew Lindesay if (size > MAX_IMAGE_SIZE || size == 0)
16266ee6532SAndrew Lindesay return B_BAD_VALUE;
16366ee6532SAndrew Lindesay
16466ee6532SAndrew Lindesay BResources resources;
16566ee6532SAndrew Lindesay status_t status = get_app_resources(resources);
16666ee6532SAndrew Lindesay
16766ee6532SAndrew Lindesay size_t dataSize;
16866ee6532SAndrew Lindesay const void* data = NULL;
16966ee6532SAndrew Lindesay
17066ee6532SAndrew Lindesay if (status == B_OK)
17166ee6532SAndrew Lindesay data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, &dataSize);
17266ee6532SAndrew Lindesay
17366ee6532SAndrew Lindesay if (data == NULL) {
17466ee6532SAndrew Lindesay HDERROR("unable to read the resource [%d]", resourceID);
17566ee6532SAndrew Lindesay status = B_ERROR;
17666ee6532SAndrew Lindesay }
17766ee6532SAndrew Lindesay
178c3cad236SAndrew Lindesay BSize iconSize = BControlLook::ComposeIconSize(size);
179c3cad236SAndrew Lindesay BBitmap* bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32);
18066ee6532SAndrew Lindesay status = bitmap->InitCheck();
18166ee6532SAndrew Lindesay
18266ee6532SAndrew Lindesay if (status == B_OK)
18366ee6532SAndrew Lindesay status = BIconUtils::GetVectorIcon(reinterpret_cast<const uint8*>(data), dataSize, bitmap);
18466ee6532SAndrew Lindesay
18566ee6532SAndrew Lindesay if (status != B_OK) {
18666ee6532SAndrew Lindesay HDERROR("unable to parse the resource [%d] as a vector icon", resourceID);
18766ee6532SAndrew Lindesay delete bitmap;
18866ee6532SAndrew Lindesay bitmap = NULL;
18966ee6532SAndrew Lindesay } else {
19066ee6532SAndrew Lindesay *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true);
19166ee6532SAndrew Lindesay }
19266ee6532SAndrew Lindesay
19366ee6532SAndrew Lindesay return status;
19466ee6532SAndrew Lindesay }
19566ee6532SAndrew Lindesay
19666ee6532SAndrew Lindesay
19766ee6532SAndrew Lindesay /*static*/ status_t
_CreateIconForMimeTypeChecked(const char * mimeTypeStr,uint32 size,BitmapHolderRef * bitmapHolderRef)19866ee6532SAndrew Lindesay SharedIcons::_CreateIconForMimeTypeChecked(const char* mimeTypeStr, uint32 size,
19966ee6532SAndrew Lindesay BitmapHolderRef* bitmapHolderRef)
20066ee6532SAndrew Lindesay {
20166ee6532SAndrew Lindesay if (size > MAX_IMAGE_SIZE || size == 0)
20266ee6532SAndrew Lindesay return B_BAD_VALUE;
20366ee6532SAndrew Lindesay
20466ee6532SAndrew Lindesay BMimeType mimeType(mimeTypeStr);
20566ee6532SAndrew Lindesay status_t status = mimeType.InitCheck();
20666ee6532SAndrew Lindesay
20766ee6532SAndrew Lindesay uint8* data;
20866ee6532SAndrew Lindesay size_t dataSize;
20966ee6532SAndrew Lindesay
21066ee6532SAndrew Lindesay if (status == B_OK)
21166ee6532SAndrew Lindesay status = mimeType.GetIcon(&data, &dataSize);
21266ee6532SAndrew Lindesay
21366ee6532SAndrew Lindesay BBitmap* bitmap = NULL;
21466ee6532SAndrew Lindesay
21566ee6532SAndrew Lindesay if (status == B_OK) {
216c3cad236SAndrew Lindesay BSize iconSize = BControlLook::ComposeIconSize(size);
217c3cad236SAndrew Lindesay bitmap = new BBitmap(BRect(BPoint(0, 0), iconSize), 0, B_RGBA32);
21866ee6532SAndrew Lindesay status = bitmap->InitCheck();
21966ee6532SAndrew Lindesay }
22066ee6532SAndrew Lindesay
22166ee6532SAndrew Lindesay if (status == B_OK)
22266ee6532SAndrew Lindesay status = BIconUtils::GetVectorIcon(data, dataSize, bitmap);
22366ee6532SAndrew Lindesay
22466ee6532SAndrew Lindesay if (status != B_OK) {
22566ee6532SAndrew Lindesay delete bitmap;
22666ee6532SAndrew Lindesay bitmap = NULL;
22766ee6532SAndrew Lindesay } else {
22866ee6532SAndrew Lindesay *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true);
22966ee6532SAndrew Lindesay }
23066ee6532SAndrew Lindesay
23166ee6532SAndrew Lindesay return status;
23266ee6532SAndrew Lindesay }
233