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