xref: /haiku/src/apps/haikudepot/ui/SharedIcons.cpp (revision 344ded80d400028c8f561b4b876257b94c12db4a)
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