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