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