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