1 #include "icon_cache.hh"
2 #include "../../config_data.hh"
3 
4 namespace wapanel::applet::utils::ic {
5 
6 std::unordered_map<int, icon_cache *> _sizes;
7 
icon_cache()8 icon_cache::icon_cache() {
9 	default_icon_theme = gtk_icon_theme_get_for_screen(gdk_screen_get_default());
10 	gtk_icon_theme_append_search_path(default_icon_theme, APP_DATA_DIR "/icons");
11 }
12 
~icon_cache()13 icon_cache::~icon_cache() {
14 	for (auto &&[key, val] : icons) {
15 		g_object_unref(val);
16 	}
17 
18 	icons.clear();
19 }
20 
split(std::string text,const char * separator)21 auto split(std::string text, const char *separator) -> std::vector<std::string> {
22 	std::vector<std::string> splitted;
23 
24 	char *cpy = (char *)malloc(text.length() + 1);
25 	strncpy(cpy, text.c_str(), text.length() + 1);
26 
27 	char *token = strtok(cpy, separator);
28 
29 	while (token != NULL) {
30 		splitted.push_back(token);
31 		token = strtok(NULL, separator);
32 	}
33 
34 	free(cpy);
35 
36 	return splitted;
37 }
38 
get_icon(std::string icon_name,int icon_size)39 auto icon_cache::get_icon(std::string icon_name, int icon_size) -> GdkPixbuf * {
40 	if (icons.contains(icon_name)) {
41 		return icons[icon_name];
42 	} else {
43 		bool load_file = false;
44 		if (icon_name.length() > 0) {
45 			if (icon_name[0] == '/') { load_file = true; }
46 		}
47 
48 		GdkPixbuf *icon;
49 
50 		if (load_file) {
51 			icon = gdk_pixbuf_new_from_file_at_size(icon_name.c_str(), icon_size, icon_size, NULL);
52 		} else {
53 			icon = gtk_icon_theme_load_icon(default_icon_theme, icon_name.c_str(), icon_size,
54 											GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
55 		}
56 
57 		if (icon == NULL) {
58 			auto splt = split(icon_name, ".");
59 			if (splt.size() > 0) {
60 				icon = gtk_icon_theme_load_icon(default_icon_theme, splt[0].c_str(), icon_size,
61 												GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
62 			}
63 		}
64 
65 		if (icon == NULL) {
66 			log_error("Cannot find icon `%s`", icon_name.c_str());
67 
68 			icon = gtk_icon_theme_load_icon(default_icon_theme, "application-x-executable", icon_size,
69 											GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
70 
71 			return icon;
72 		}
73 
74 		log_info("Initialized cache for icon `%s` with size `%d`", icon_name.c_str(), icon_size);
75 
76 		icons[icon_name] = icon;
77 		return icons[icon_name];
78 	}
79 }
80 
get_icon(std::string icon_name,int icon_size)81 auto get_icon(std::string icon_name, int icon_size) -> GdkPixbuf * {
82 	if (!_sizes.contains(icon_size)) { _sizes[icon_size] = new icon_cache(); }
83 
84 	return _sizes[icon_size]->get_icon(icon_name, icon_size);
85 }
86 
clean()87 auto clean() -> void {
88 	for (auto &&[key, val] : _sizes) {
89 		delete val;
90 	}
91 
92 	_sizes.clear();
93 }
94 
95 } // namespace wapanel::applet
96