1 /* 2 * Copyright 2024, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 6 #include "SharedIcons.h" 7 8 #include <IconUtils.h> 9 #include <Resources.h> 10 11 #include "BitmapHolder.h" 12 #include "HaikuDepotConstants.h" 13 #include "Logger.h" 14 #include "support.h" 15 16 17 BitmapHolderRef SharedIcons::sIconStarBlue16Scaled; 18 BitmapHolderRef SharedIcons::sIconStarGrey16Scaled; 19 BitmapHolderRef SharedIcons::sIconInstalled16Scaled; 20 BitmapHolderRef SharedIcons::sIconArrowLeft22Scaled; 21 BitmapHolderRef SharedIcons::sIconArrowRight22Scaled; 22 BitmapHolderRef SharedIcons::sIconHTMLPackage16Scaled; 23 24 25 /*static*/ BitmapHolderRef 26 SharedIcons::IconStarBlue16Scaled() 27 { 28 if (!SharedIcons::sIconStarBlue16Scaled.IsSet()) { 29 SharedIcons::sIconStarBlue16Scaled 30 = SharedIcons::_CreateIconForResource(RSRC_STAR_BLUE, 16); 31 } 32 return SharedIcons::sIconStarBlue16Scaled; 33 } 34 35 36 /*static*/ BitmapHolderRef 37 SharedIcons::IconStarGrey16Scaled() 38 { 39 if (!SharedIcons::sIconStarGrey16Scaled.IsSet()) { 40 SharedIcons::sIconStarGrey16Scaled 41 = SharedIcons::_CreateIconForResource(RSRC_STAR_GREY, 16); 42 } 43 return SharedIcons::sIconStarGrey16Scaled; 44 } 45 46 47 /*static*/ BitmapHolderRef 48 SharedIcons::IconInstalled16Scaled() 49 { 50 if (!SharedIcons::sIconInstalled16Scaled.IsSet()) { 51 SharedIcons::sIconInstalled16Scaled 52 = SharedIcons::_CreateIconForResource(RSRC_INSTALLED, 16); 53 } 54 return SharedIcons::sIconInstalled16Scaled; 55 } 56 57 58 /*static*/ BitmapHolderRef 59 SharedIcons::IconArrowLeft22Scaled() 60 { 61 if (!SharedIcons::sIconArrowLeft22Scaled.IsSet()) { 62 SharedIcons::sIconArrowLeft22Scaled 63 = SharedIcons::_CreateIconForResource(RSRC_ARROW_LEFT, 22); 64 } 65 return SharedIcons::sIconArrowLeft22Scaled; 66 } 67 68 69 /*static*/ BitmapHolderRef 70 SharedIcons::IconArrowRight22Scaled() 71 { 72 if (!SharedIcons::sIconArrowRight22Scaled.IsSet()) { 73 SharedIcons::sIconArrowRight22Scaled 74 = SharedIcons::_CreateIconForResource(RSRC_ARROW_RIGHT, 22); 75 } 76 return SharedIcons::sIconArrowRight22Scaled; 77 } 78 79 80 /*static*/ BitmapHolderRef 81 SharedIcons::IconHTMLPackage16Scaled() 82 { 83 if (!SharedIcons::sIconHTMLPackage16Scaled.IsSet()) { 84 SharedIcons::sIconHTMLPackage16Scaled 85 = SharedIcons::_CreateIconForMimeType("text/html", 16); 86 } 87 return SharedIcons::sIconHTMLPackage16Scaled; 88 } 89 90 91 /*static*/ void 92 SharedIcons::UnsetAllIcons() 93 { 94 sIconStarBlue16Scaled.Unset(); 95 sIconStarGrey16Scaled.Unset(); 96 sIconInstalled16Scaled.Unset(); 97 sIconArrowLeft22Scaled.Unset(); 98 sIconArrowRight22Scaled.Unset(); 99 100 sIconHTMLPackage16Scaled.Unset(); 101 } 102 103 104 /*static*/ BitmapHolderRef 105 SharedIcons::_CreateIconForResource(int32 resourceID, uint32 size) 106 { 107 BitmapHolderRef result(NULL); 108 109 if (SharedIcons::_CreateIconForResourceChecked(resourceID, size, &result) != B_OK) { 110 HDERROR("unable to create bitmap for resource [%d]", resourceID); 111 debugger("unable to create bitmap for resource"); 112 // the resource is bundled into the build product so not being able to find it is an 113 // illegal state. 114 } 115 116 return result; 117 } 118 119 120 /*static*/ BitmapHolderRef 121 SharedIcons::_CreateIconForMimeType(const char* mimeType, uint32 size) 122 { 123 BitmapHolderRef result(NULL); 124 125 if (SharedIcons::_CreateIconForMimeTypeChecked(mimeType, size, &result) != B_OK) 126 HDERROR("unable to create bitmap for mime type [%s]", mimeType); 127 128 return result; 129 } 130 131 132 /*static*/ status_t 133 SharedIcons::_CreateIconForResourceChecked(int32 resourceID, uint32 size, 134 BitmapHolderRef* bitmapHolderRef) 135 { 136 if (size > MAX_IMAGE_SIZE || size == 0) 137 return B_BAD_VALUE; 138 139 BResources resources; 140 status_t status = get_app_resources(resources); 141 142 size_t dataSize; 143 const void* data = NULL; 144 145 if (status == B_OK) 146 data = resources.LoadResource(B_VECTOR_ICON_TYPE, resourceID, &dataSize); 147 148 if (data == NULL) { 149 HDERROR("unable to read the resource [%d]", resourceID); 150 status = B_ERROR; 151 } 152 153 BBitmap* bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, B_RGBA32); 154 status = bitmap->InitCheck(); 155 156 if (status == B_OK) 157 status = BIconUtils::GetVectorIcon(reinterpret_cast<const uint8*>(data), dataSize, bitmap); 158 159 if (status != B_OK) { 160 HDERROR("unable to parse the resource [%d] as a vector icon", resourceID); 161 delete bitmap; 162 bitmap = NULL; 163 } else { 164 *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true); 165 } 166 167 return status; 168 } 169 170 171 /*static*/ status_t 172 SharedIcons::_CreateIconForMimeTypeChecked(const char* mimeTypeStr, uint32 size, 173 BitmapHolderRef* bitmapHolderRef) 174 { 175 if (size > MAX_IMAGE_SIZE || size == 0) 176 return B_BAD_VALUE; 177 178 BMimeType mimeType(mimeTypeStr); 179 status_t status = mimeType.InitCheck(); 180 181 uint8* data; 182 size_t dataSize; 183 184 if (status == B_OK) 185 status = mimeType.GetIcon(&data, &dataSize); 186 187 BBitmap* bitmap = NULL; 188 189 if (status == B_OK) { 190 bitmap = new BBitmap(BRect(0, 0, size - 1, size - 1), 0, B_RGBA32); 191 status = bitmap->InitCheck(); 192 } 193 194 if (status == B_OK) 195 status = BIconUtils::GetVectorIcon(data, dataSize, bitmap); 196 197 if (status != B_OK) { 198 delete bitmap; 199 bitmap = NULL; 200 } else { 201 *bitmapHolderRef = BitmapHolderRef(new(std::nothrow) BitmapHolder(bitmap), true); 202 } 203 204 return status; 205 } 206