Merge lp:~mhr3/unity/icon-loader-width-and-height into lp:unity

Proposed by Michal Hruby on 2012-09-12
Status: Merged
Approved by: Omer Akram on 2012-09-14
Approved revision: 2687
Merged at revision: 2690
Proposed branch: lp:~mhr3/unity/icon-loader-width-and-height
Merge into: lp:unity
Prerequisite: lp:~nick-dedekind/unity/dash-results.focus+size
Diff against target: 1235 lines (+416/-178)
15 files modified
dash/ResultRendererTile.cpp (+11/-17)
dash/ResultRendererTile.h (+1/-1)
launcher/DeviceNotificationDisplayImp.cpp (+4/-3)
plugins/unityshell/resources/emblem_apps.svg (+19/-0)
plugins/unityshell/resources/emblem_books.svg (+9/-0)
plugins/unityshell/resources/emblem_clothes.svg (+8/-0)
plugins/unityshell/resources/emblem_music.svg (+15/-0)
plugins/unityshell/resources/emblem_video.svg (+17/-0)
tests/test_icon_loader.cpp (+6/-6)
unity-shared/CoverArt.cpp (+16/-10)
unity-shared/CoverArt.h (+3/-3)
unity-shared/IconLoader.cpp (+290/-127)
unity-shared/IconLoader.h (+9/-5)
unity-shared/IconTexture.cpp (+7/-5)
unity-shared/IconTexture.h (+1/-1)
To merge this branch: bzr merge lp:~mhr3/unity/icon-loader-width-and-height
Reviewer Review Type Date Requested Status
Omer Akram (community) Approve on 2012-09-14
John Lea (community) design Approve on 2012-09-13
Nick Dedekind (community) 2012-09-12 Approve on 2012-09-13
Review via email: mp+124013@code.launchpad.net

Commit Message

Change the IconLoader methods to allow specifying both maximum width and height. Updated rendering of the icon ribbons.

Description of the Change

Change the IconLoader methods to allow specifying both maximum width and height. Also updated rendering of the icon ribbons.

To post a comment you must log in.
Nick Dedekind (nick-dedekind) wrote :

502 + int size = max_height < 0 ? max_width : max_height;
510 + int size = max_height < 0 ? max_width : max_height;

I think it should use the minimum of the values if max_height < 0. so.
int size = max_height < 0 ? max_width : (max_width < 0 ? max_height : MIN(max_height, max_width));

784 switch (category)
785 {
786 + case UNITY_PROTOCOL_CATEGORY_TYPE_BOOK:
787 + helper_handle =
788 + impl->LoadFromFilename(PKGDATADIR"/emblem_books.svg", -1, cat_size, helper_slot);
789 + break;
790 case UNITY_PROTOCOL_CATEGORY_TYPE_MUSIC:

Could we put the category->resource mapping in the Dash Style?

Other than these the code looks good. I trust it meets visual design requirements :)

Nick Dedekind (nick-dedekind) wrote :

LGTM

review: Approve
John Lea (johnlea) :
review: Approve (design)
Unity Merger (unity-merger) wrote :

The prerequisite lp:~nick-dedekind/unity/dash-results.focus+size has not yet been merged into lp:unity.

Unity Merger (unity-merger) wrote :

No proposals found for merge of lp:~nick-dedekind/unity/dash-results.focus+size into lp:unity.

Omer Akram (om26er) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dash/ResultRendererTile.cpp'
2--- dash/ResultRendererTile.cpp 2012-09-13 10:12:22 +0000
3+++ dash/ResultRendererTile.cpp 2012-09-13 10:12:22 +0000
4@@ -204,7 +204,7 @@
5 void ResultRendererTile::LoadIcon(Result& row)
6 {
7 Style& style = Style::Instance();
8- std::string const& icon_hint = row.icon_hint;
9+ std::string icon_hint(row.icon_hint);
10 #define DEFAULT_GICON ". GThemedIcon text-x-preview"
11 std::string icon_name;
12 if (G_UNLIKELY(neko))
13@@ -222,26 +222,20 @@
14 icon_name = !icon_hint.empty() ? icon_hint : DEFAULT_GICON;
15 }
16
17- GIcon* icon = g_icon_new_for_string(icon_name.c_str(), NULL);
18+ glib::Object<GIcon> icon(g_icon_new_for_string(icon_name.c_str(), NULL));
19 TextureContainer* container = row.renderer<TextureContainer*>();
20
21 IconLoader::IconLoaderCallback slot = sigc::bind(sigc::mem_fun(this, &ResultRendererTile::IconLoaded), icon_hint, row);
22
23- if (g_strrstr(icon_name.c_str(), "://"))
24- {
25- container->slot_handle = IconLoader::GetDefault().LoadFromURI(icon_name, style.GetTileImageSize(), slot);
26- }
27- else if (G_IS_ICON(icon))
28- {
29- container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name, g_str_has_prefix(icon_name.c_str(), "/") ? style.GetTileImageSize() : style.GetTileGIconSize(), slot);
30+ if (icon.IsType(G_TYPE_ICON))
31+ {
32+ bool use_large_icon = icon.IsType(G_TYPE_FILE_ICON) || !icon.IsType(G_TYPE_THEMED_ICON);
33+ container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(icon_name, style.GetTileImageSize(), use_large_icon ? style.GetTileImageSize() : style.GetTileGIconSize(), slot);
34 }
35 else
36 {
37- container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name, style.GetTileGIconSize(), slot);
38+ container->slot_handle = IconLoader::GetDefault().LoadFromIconName(icon_name, -1, style.GetTileGIconSize(), slot);
39 }
40-
41- if (icon != NULL)
42- g_object_unref(icon);
43 }
44
45 nux::BaseTexture* ResultRendererTile::CreateTextureCallback(std::string const& texid,
46@@ -321,7 +315,8 @@
47
48
49 void ResultRendererTile::IconLoaded(std::string const& texid,
50- unsigned size,
51+ int max_width,
52+ int max_height,
53 glib::Object<GdkPixbuf> const& pixbuf,
54 std::string icon_name,
55 Result& row)
56@@ -333,7 +328,7 @@
57 if (pixbuf && container)
58 {
59 TextureCache& cache = TextureCache::GetDefault();
60- BaseTexturePtr texture(cache.FindTexture(icon_name, size, size,
61+ BaseTexturePtr texture(cache.FindTexture(icon_name, max_width, max_height,
62 sigc::bind(sigc::mem_fun(this, &ResultRendererTile::CreateTextureCallback), pixbuf)));
63
64 BaseTexturePtr texture_prelight(cache.FindTexture("resultview_prelight", style.GetTileIconHightlightWidth(), style.GetTileIconHightlightHeight(), sigc::mem_fun(this, &ResultRendererTile::DrawHighlight)));
65@@ -350,9 +345,8 @@
66 {
67 // we need to load a missing icon
68 IconLoader::IconLoaderCallback slot = sigc::bind(sigc::mem_fun(this, &ResultRendererTile::IconLoaded), icon_name, row);
69- container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(". GThemedIcon text-x-preview", size, slot);
70+ container->slot_handle = IconLoader::GetDefault().LoadFromGIconString(". GThemedIcon text-x-preview", max_width, max_height, slot);
71 }
72-
73 }
74
75
76
77=== modified file 'dash/ResultRendererTile.h'
78--- dash/ResultRendererTile.h 2012-09-13 10:12:22 +0000
79+++ dash/ResultRendererTile.h 2012-09-13 10:12:22 +0000
80@@ -90,7 +90,7 @@
81 nux::ObjectPtr<nux::BaseTexture> normal_cache_;
82 private:
83 //icon loading callbacks
84- void IconLoaded(std::string const& texid, unsigned size,
85+ void IconLoaded(std::string const& texid, int max_width, int max_height,
86 glib::Object<GdkPixbuf> const& pixbuf,
87 std::string icon_name, Result& row);
88 nux::BaseTexture* CreateTextureCallback(std::string const& texid,
89
90=== modified file 'launcher/DeviceNotificationDisplayImp.cpp'
91--- launcher/DeviceNotificationDisplayImp.cpp 2012-08-22 09:03:25 +0000
92+++ launcher/DeviceNotificationDisplayImp.cpp 2012-09-13 10:12:22 +0000
93@@ -40,12 +40,13 @@
94 void Show(std::string const& icon_name, std::string const& volume_name)
95 {
96 int icon_size = 48;
97- IconLoader::GetDefault().LoadFromGIconString(icon_name, icon_size,
98+ IconLoader::GetDefault().LoadFromGIconString(icon_name, -1, icon_size,
99 sigc::bind(sigc::mem_fun(this, &Impl::ShowNotificationWhenIconIsReady), volume_name));
100 }
101
102 void ShowNotificationWhenIconIsReady(std::string const& icon_name,
103- unsigned size,
104+ int max_width,
105+ int max_height,
106 glib::Object<GdkPixbuf> const& pixbuf,
107 std::string const& volume_name)
108 {
109@@ -55,7 +56,7 @@
110
111 notify_notification_set_hint(notification, "x-canonical-private-synchronous", g_variant_new_boolean(TRUE));
112
113- if (GDK_IS_PIXBUF(pixbuf.RawPtr()))
114+ if (pixbuf)
115 notify_notification_set_image_from_pixbuf(notification, pixbuf);
116
117 notify_notification_show(notification, nullptr);
118
119=== added file 'plugins/unityshell/resources/emblem_apps.svg'
120--- plugins/unityshell/resources/emblem_apps.svg 1970-01-01 00:00:00 +0000
121+++ plugins/unityshell/resources/emblem_apps.svg 2012-09-13 10:12:22 +0000
122@@ -0,0 +1,19 @@
123+<?xml version="1.0" encoding="utf-8"?>
124+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
125+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
126+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
127+ width="14px" height="14px" viewBox="0 0 14 14" enable-background="new 0 0 14 14" xml:space="preserve">
128+<path fill="#DC4A26" d="M8.5,4.504v7.997c0,0.55-0.469,0.999-1.018,0.999H6.498c-0.55,0-0.998-0.449-0.998-0.999V4.504H8.5z"/>
129+<g>
130+ <path fill="#DC4A26" d="M4.5,4.504h-2v-1h2V1.505c0-0.55-0.45-1-1-1H1.501c-0.55,0-1,0.45-1,1L0.5,12.501
131+ c0,0.55,0.45,0.999,1,0.999h1.999c0.55,0,1-0.449,1-0.999V10.5L2.5,10.502v-1L4.499,9.5V7.503H2.5v-1h2"/>
132+</g>
133+<path fill="#DC4A26" d="M4.5,6.503v-1l0,0V6.503L4.5,6.503z"/>
134+<path fill="#DC4A26" d="M4.5,9.502v-1h0L4.5,9.502L4.5,9.502z"/>
135+<path fill="#DC4A26" d="M4.5,12.499L4.5,12.499L4.5,12.499L4.5,12.499L4.5,12.499z"/>
136+<path fill="#DC4A26" d="M11.866,0.508v1.237C12.102,1.856,12.3,2.052,12.3,2.286c0,0.354-0.358,0.64-0.8,0.64s-0.8-0.286-0.8-0.64
137+ c0-0.234,0.198-0.43,0.433-0.541V0.508C10.66,0.972,9.5,2.321,9.5,2.917c0,0.884,1.116,1.6,2,1.6s2-0.716,2-1.6
138+ C13.5,2.321,12.34,0.972,11.866,0.508z"/>
139+<path fill="#DC4A26" d="M5.501,3.499L7.047,0.5L8.5,3.499H5.501z"/>
140+<path fill="#DC4A26" d="M13.5,5.503v6.998c0,0.55-0.45,0.999-1,0.999h-2c-0.55,0-1-0.449-1-0.999V5.503H13.5z"/>
141+</svg>
142
143=== added file 'plugins/unityshell/resources/emblem_books.svg'
144--- plugins/unityshell/resources/emblem_books.svg 1970-01-01 00:00:00 +0000
145+++ plugins/unityshell/resources/emblem_books.svg 2012-09-13 10:12:22 +0000
146@@ -0,0 +1,9 @@
147+<?xml version="1.0" encoding="utf-8"?>
148+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
149+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
150+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
151+ width="14px" height="14px" viewBox="0 0 14 14" enable-background="new 0 0 14 14" xml:space="preserve">
152+<path fill="#DC4A26" d="M7,1.879C6.961,1.473,6.427,0.227,1,1.5c0,3.222,0,7.449,0,11C7.009,10.945,7,13,7,13s-0.009-2.055,6-0.5
153+ c0-3.551,0-7.778,0-11C7.574,0.227,7.039,1.473,7,1.879z M5,9H2V8h3V9z M5,7H2V6h3V7z M5,5H2V4h3V5z M7.5,12h-1V2h1V12z M12,9H9V8h3
154+ V9z M12,7H9V6h3V7z M12,5H9V4h3V5z"/>
155+</svg>
156
157=== added file 'plugins/unityshell/resources/emblem_clothes.svg'
158--- plugins/unityshell/resources/emblem_clothes.svg 1970-01-01 00:00:00 +0000
159+++ plugins/unityshell/resources/emblem_clothes.svg 2012-09-13 10:12:22 +0000
160@@ -0,0 +1,8 @@
161+<?xml version="1.0" encoding="utf-8"?>
162+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
163+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
164+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
165+ width="14px" height="14px" viewBox="0 0 14 14" enable-background="new 0 0 14 14" xml:space="preserve">
166+<path fill="#DC4A26" d="M10.997,13V5.013l1.505,0.772L14,2.942L10.974,1L8.988,1.002c0,1.121-0.916,2.029-2.046,2.029
167+ S5.012,2.123,5.012,1.002L2.969,1L0,2.942l1.498,2.843l1.447-0.772V13H10.997z"/>
168+</svg>
169
170=== added file 'plugins/unityshell/resources/emblem_music.svg'
171--- plugins/unityshell/resources/emblem_music.svg 1970-01-01 00:00:00 +0000
172+++ plugins/unityshell/resources/emblem_music.svg 2012-09-13 10:12:22 +0000
173@@ -0,0 +1,15 @@
174+<?xml version="1.0" encoding="utf-8"?>
175+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
176+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
177+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
178+ width="14px" height="14px" viewBox="0 0 14 14" enable-background="new 0 0 14 14" xml:space="preserve">
179+<g>
180+ <g>
181+ <path fill="#DC4A26" d="M13,0.598c0-0.386-0.307-0.651-0.683-0.588L5.672,1.186C5.296,1.249,5,1.617,5,2.005v7.249
182+ C4.228,8.862,3.14,8.925,2.157,9.52c-1.393,0.841-2.033,2.413-1.43,3.506c0.603,1.094,2.223,1.299,3.615,0.455
183+ c1.078-0.65,1.697-1.735,1.648-2.699L6,10.789V3.624c0-0.386,0.277-0.756,0.653-0.818l4.684-0.823C11.712,1.919,12,2.184,12,2.57
184+ v4.684c-0.771-0.393-1.86-0.329-2.843,0.265C7.764,8.36,7.123,9.931,7.727,11.024c0.603,1.094,2.222,1.3,3.615,0.456
185+ c1.069-0.646,1.689-1.721,1.649-2.68L13,8.808V0.598z"/>
186+ </g>
187+</g>
188+</svg>
189
190=== added file 'plugins/unityshell/resources/emblem_video.svg'
191--- plugins/unityshell/resources/emblem_video.svg 1970-01-01 00:00:00 +0000
192+++ plugins/unityshell/resources/emblem_video.svg 2012-09-13 10:12:22 +0000
193@@ -0,0 +1,17 @@
194+<?xml version="1.0" encoding="utf-8"?>
195+<!-- Generator: Adobe Illustrator 15.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
196+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
197+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
198+ width="14px" height="14px" viewBox="0 0 14 14" enable-background="new 0 0 14 14" xml:space="preserve">
199+<g>
200+ <g>
201+ <path fill="#DC4A26" d="M12.301,2.5H1.7C1.315,2.5,1,2.813,1,3.196v7.608C1,11.188,1.315,11.5,1.7,11.5h10.601
202+ c0.385,0,0.699-0.312,0.699-0.696V3.196C13,2.813,12.686,2.5,12.301,2.5z M2.989,10.455H1.994V9.498h0.996V10.455z M2.989,8.49
203+ H1.994V7.5h0.996V8.49z M2.989,6.494H1.994V5.535h0.996V6.494z M2.989,4.496H1.994V3.538h0.996V4.496z M8.006,7.841
204+ C7.659,8.126,7.308,8.404,6.954,8.677C6.6,8.947,6.255,9.197,5.92,9.426c-0.335,0.229-0.64,0.422-0.913,0.579V4.026
205+ c0.261,0.158,0.559,0.35,0.894,0.578c0.335,0.229,0.68,0.476,1.034,0.74c0.354,0.265,0.708,0.54,1.061,0.825
206+ c0.355,0.286,0.687,0.565,0.998,0.836C8.684,7.276,8.354,7.555,8.006,7.841z M11.992,10.455h-0.996V9.498h0.996V10.455z
207+ M11.992,8.49h-0.996V7.5h0.996V8.49z M11.992,6.494h-0.996V5.535h0.996V6.494z M11.992,4.496h-0.996V3.538h0.996V4.496z"/>
208+ </g>
209+</g>
210+</svg>
211
212=== modified file 'tests/test_icon_loader.cpp'
213--- tests/test_icon_loader.cpp 2012-08-20 18:41:49 +0000
214+++ tests/test_icon_loader.cpp 2012-09-13 10:12:22 +0000
215@@ -47,7 +47,7 @@
216 bool got_callback;
217
218 LoadResult() : pixbuf(NULL), got_callback(false) {}
219- void IconLoaded(std::string const& icon_name, unsigned size,
220+ void IconLoaded(std::string const& icon_name, int max_width, int max_height,
221 glib::Object<GdkPixbuf> const& buf)
222 {
223 pixbuf = buf;
224@@ -71,7 +71,7 @@
225 IconLoader& icon_loader = IconLoader::GetDefault();
226 volatile bool timeout_reached = false;
227
228- icon_loader.LoadFromIconName("gedit-icon", 48, sigc::mem_fun(load_result,
229+ icon_loader.LoadFromIconName("gedit-icon", -1, 48, sigc::mem_fun(load_result,
230 &LoadResult::IconLoaded));
231
232 guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
233@@ -93,7 +93,7 @@
234 volatile bool timeout_reached = false;
235
236
237- icon_loader.LoadFromGIconString(". UnityProtocolAnnotatedIcon %7B'base-icon':%20%3C'gedit-icon'%3E,%20'ribbon':%20%3C'foo'%3E%7D", 48, sigc::mem_fun(load_result,
238+ icon_loader.LoadFromGIconString(". UnityProtocolAnnotatedIcon %7B'base-icon':%20%3C'gedit-icon'%3E,%20'ribbon':%20%3C'foo'%3E%7D", -1, 48, sigc::mem_fun(load_result,
239 &LoadResult::IconLoaded));
240
241 guint tid = g_timeout_add (10000, TimeoutReached, (gpointer)(&timeout_reached));
242@@ -125,7 +125,7 @@
243 // be cached already!
244 for (int i = 0; i < load_count; i++)
245 {
246- handles[i] = icon_loader.LoadFromIconName("web-browser", 48,
247+ handles[i] = icon_loader.LoadFromIconName("web-browser", -1, 48,
248 sigc::mem_fun(results[i], &LoadResult::IconLoaded));
249 }
250
251@@ -190,7 +190,7 @@
252 for (GList *it = icons; it != NULL; it = it->next)
253 {
254 const char *icon_name = static_cast<char*>(it->data);
255- icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(results[i++],
256+ icon_loader.LoadFromIconName(icon_name, -1, 48, sigc::mem_fun(results[i++],
257 &LoadResult::IconLoaded));
258 if (i >= icon_count) break;
259 }
260@@ -235,7 +235,7 @@
261 for (GList *it = icons; it != NULL; it = it->next)
262 {
263 const char *icon_name = static_cast<char*>(it->data);
264- int handle = icon_loader.LoadFromIconName(icon_name, 48, sigc::mem_fun(
265+ int handle = icon_loader.LoadFromIconName(icon_name, -1, 48, sigc::mem_fun(
266 results[i], &LoadResult::IconLoaded));
267 handles[i++] = handle;
268 if (i >= icon_count) break;
269
270=== modified file 'unity-shared/CoverArt.cpp'
271--- unity-shared/CoverArt.cpp 2012-09-03 22:45:44 +0000
272+++ unity-shared/CoverArt.cpp 2012-09-13 10:12:22 +0000
273@@ -41,7 +41,7 @@
274 {
275 nux::logging::Logger logger("unity.dash.previews.coverart");
276
277-const int icon_width = 256;
278+const int ICON_SIZE = 256;
279 }
280
281 NUX_IMPLEMENT_OBJECT_TYPE(CoverArt);
282@@ -109,9 +109,9 @@
283
284 // texture from file.
285 if (bLoadTexture)
286- {
287+ {
288 StartWaiting();
289- slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, ~0, sigc::mem_fun(this, &CoverArt::TextureLoaded));
290+ slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, -1, -1, sigc::mem_fun(this, &CoverArt::TextureLoaded));
291 }
292 else if (!image_hint.empty())
293 {
294@@ -121,12 +121,12 @@
295 if (G_IS_ICON(icon))
296 {
297 StartWaiting();
298- slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, icon_width, sigc::mem_fun(this, &CoverArt::IconLoaded));
299+ slot_handle_ = IconLoader::GetDefault().LoadFromGIconString(image_hint, ICON_SIZE, ICON_SIZE, sigc::mem_fun(this, &CoverArt::IconLoaded));
300 }
301 else
302 {
303 StartWaiting();
304- slot_handle_ = IconLoader::GetDefault().LoadFromIconName(image_hint, icon_width, sigc::mem_fun(this, &CoverArt::IconLoaded));
305+ slot_handle_ = IconLoader::GetDefault().LoadFromIconName(image_hint, ICON_SIZE, ICON_SIZE, sigc::mem_fun(this, &CoverArt::IconLoaded));
306 }
307 }
308 else
309@@ -195,7 +195,10 @@
310 }
311 }
312
313-void CoverArt::IconLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf)
314+void CoverArt::IconLoaded(std::string const& texid,
315+ int max_width,
316+ int max_height,
317+ glib::Object<GdkPixbuf> const& pixbuf)
318 {
319 // Finished waiting
320 StopWaiting();
321@@ -207,7 +210,7 @@
322 return;
323 }
324
325- int height = size;
326+ int height = max_height;
327
328 int pixbuf_width, pixbuf_height;
329 pixbuf_width = gdk_pixbuf_get_width(pixbuf);
330@@ -232,7 +235,7 @@
331 float aspect = static_cast<float>(pixbuf_height) / pixbuf_width; // already sanitized width/height so can not be 0.0
332 if (aspect < 1.0f)
333 {
334- pixbuf_width = icon_width;
335+ pixbuf_width = ICON_SIZE;
336 pixbuf_height = pixbuf_width * aspect;
337
338 if (pixbuf_height > height)
339@@ -274,7 +277,10 @@
340 }
341 }
342
343-void CoverArt::TextureLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf)
344+void CoverArt::TextureLoaded(std::string const& texid,
345+ int max_width,
346+ int max_height,
347+ glib::Object<GdkPixbuf> const& pixbuf)
348 {
349 // Finished waiting
350 StopWaiting();
351@@ -489,4 +495,4 @@
352
353 }
354 }
355-}
356\ No newline at end of file
357+}
358
359=== modified file 'unity-shared/CoverArt.h'
360--- unity-shared/CoverArt.h 2012-08-28 10:15:19 +0000
361+++ unity-shared/CoverArt.h 2012-09-13 10:12:22 +0000
362@@ -70,8 +70,8 @@
363 void OnThumbnailError(std::string const& error_hint);
364 bool OnFrameTimeout();
365
366- void IconLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf);
367- void TextureLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf);
368+ void IconLoaded(std::string const& texid, int max_width, int max_height, glib::Object<GdkPixbuf> const& pixbuf);
369+ void TextureLoaded(std::string const& texid, int max_width, int max_height, glib::Object<GdkPixbuf> const& pixbuf);
370
371 void StartWaiting();
372 void StopWaiting();
373@@ -105,4 +105,4 @@
374 }
375 }
376
377-#endif // APPLICATIONSCREENSHOT_H
378\ No newline at end of file
379+#endif // APPLICATIONSCREENSHOT_H
380
381=== modified file 'unity-shared/IconLoader.cpp'
382--- unity-shared/IconLoader.cpp 2012-08-20 18:41:49 +0000
383+++ unity-shared/IconLoader.cpp 2012-09-13 10:12:22 +0000
384@@ -18,6 +18,7 @@
385 */
386
387 #include "IconLoader.h"
388+#include "config.h"
389
390 #include <queue>
391 #include <sstream>
392@@ -39,7 +40,8 @@
393 namespace
394 {
395 nux::logging::Logger logger("unity.iconloader");
396-const unsigned MIN_ICON_SIZE = 2;
397+const int MIN_ICON_SIZE = 2;
398+const int RIBBON_PADDING = 2;
399 }
400
401 class IconLoader::Impl
402@@ -48,25 +50,29 @@
403 // The Handle typedef is used to explicitly indicate which integers are
404 // infact our opaque handles.
405 typedef int Handle;
406- static const int FONT_SIZE = 10;
407- static const int MIN_FONT_SIZE = 6;
408+ static const int FONT_SIZE = 8;
409+ static const int MIN_FONT_SIZE = 5;
410
411 Impl();
412
413 Handle LoadFromIconName(std::string const& icon_name,
414- unsigned size,
415+ int max_width,
416+ int max_height,
417 IconLoaderCallback slot);
418
419 Handle LoadFromGIconString(std::string const& gicon_string,
420- unsigned size,
421+ int max_width,
422+ int max_height,
423 IconLoaderCallback slot);
424
425 Handle LoadFromFilename(std::string const& filename,
426- unsigned size,
427+ int max_width,
428+ int max_height,
429 IconLoaderCallback slot);
430
431 Handle LoadFromURI(std::string const& uri,
432- unsigned size,
433+ int max_width,
434+ int max_height,
435 IconLoaderCallback slot);
436
437 void DisconnectHandle(Handle handle);
438@@ -88,7 +94,8 @@
439
440 IconLoaderRequestType type;
441 std::string data;
442- unsigned int size;
443+ int max_width;
444+ int max_height;
445 std::string key;
446 IconLoaderCallback slot;
447 Handle handle;
448@@ -103,12 +110,14 @@
449
450 IconLoaderTask(IconLoaderRequestType type_,
451 std::string const& data_,
452- unsigned size_,
453+ int max_width_,
454+ int max_height_,
455 std::string const& key_,
456 IconLoaderCallback slot_,
457 Handle handle_,
458 Impl* self_)
459- : type(type_), data(data_), size(size_), key(key_)
460+ : type(type_), data(data_), max_width(max_width_)
461+ , max_height(max_height_), key(key_)
462 , slot(slot_), handle(handle_), impl(self_)
463 , icon_info(nullptr), no_cache(false), helper_handle(0), idle_id(0)
464 {}
465@@ -126,13 +135,16 @@
466 void InvokeSlot()
467 {
468 if (slot)
469- slot(data, size, result);
470+ slot(data, max_width, max_height, result);
471
472 // notify shadow tasks
473 for (auto shadow_task : shadow_tasks)
474 {
475 if (shadow_task->slot)
476- shadow_task->slot(shadow_task->data, shadow_task->size, result);
477+ shadow_task->slot(shadow_task->data,
478+ shadow_task->max_width,
479+ shadow_task->max_height,
480+ result);
481
482 impl->task_map_.erase(shadow_task->handle);
483 }
484@@ -143,10 +155,10 @@
485 bool Process()
486 {
487 // Check the cache again, as previous tasks might have wanted the same
488- if (impl->CacheLookup(key, data, size, slot))
489+ if (impl->CacheLookup(key, data, max_width, max_height, slot))
490 return true;
491
492- LOG_DEBUG(logger) << "Processing " << data << " at size " << size;
493+ LOG_DEBUG(logger) << "Processing " << data << " at size " << max_height;
494
495 // Rely on the compiler to tell us if we miss a new type
496 switch (type)
497@@ -161,7 +173,7 @@
498
499 LOG_WARNING(logger) << "Request type " << type
500 << " is not supported (" << data
501- << " " << size << ")";
502+ << " " << max_width << "x" << max_height << ")";
503 result = nullptr;
504 InvokeSlot();
505
506@@ -170,6 +182,7 @@
507
508 bool ProcessIconNameTask()
509 {
510+ int size = max_height < 0 ? max_width : (max_width < 0 ? max_height : MIN(max_height, max_width));
511 GtkIconInfo* info = ::gtk_icon_theme_lookup_icon(impl->theme_, data.c_str(),
512 size, static_cast<GtkIconLookupFlags>(0));
513 if (info)
514@@ -195,6 +208,7 @@
515 {
516 glib::Error error;
517 glib::Object<GIcon> icon(::g_icon_new_for_string(data.c_str(), &error));
518+ int size = max_height < 0 ? max_width : (max_width < 0 ? max_height : MIN(max_height, max_width));
519
520 if (icon.IsType(UNITY_PROTOCOL_TYPE_ANNOTATED_ICON))
521 {
522@@ -205,8 +219,12 @@
523
524 no_cache = true;
525 auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::BaseIconLoaded), glib::object_cast<UnityProtocolAnnotatedIcon>(icon));
526+ int base_icon_width = max_width > 0 ? max_width - RIBBON_PADDING * 2 : -1;
527+ int base_icon_height = base_icon_width < 0 ? max_height - RIBBON_PADDING *2 : max_height;
528 helper_handle = impl->LoadFromGIconString(gicon_string.Str(),
529- size, helper_slot);
530+ base_icon_width,
531+ base_icon_height,
532+ helper_slot);
533
534 return false;
535 }
536@@ -271,40 +289,32 @@
537 return false;
538 }
539
540- void CategoryIconLoaded(std::string const& base_icon_string, unsigned size,
541+ void CategoryIconLoaded(std::string const& base_icon_string,
542+ int max_width, int max_height,
543 glib::Object<GdkPixbuf> const& category_pixbuf,
544 glib::Object<UnityProtocolAnnotatedIcon> const& anno_icon)
545 {
546 helper_handle = 0;
547- if (category_pixbuf)
548- {
549- // assuming the category pixbuf is smaller than result
550- gdk_pixbuf_composite(category_pixbuf, result, // src, dest
551- 0, 0, // dest_x, dest_y
552- gdk_pixbuf_get_width(category_pixbuf), // dest_w
553- gdk_pixbuf_get_height(category_pixbuf), // dest_h
554- 0.0, 0.0, // offset_x, offset_y
555- 1.0, 1.0, // scale_x, scale_y
556- GDK_INTERP_NEAREST, // interpolation
557- 255); // src_alpha
558- }
559+ bool has_emblem = category_pixbuf;
560
561 const gchar* detail_text = unity_protocol_annotated_icon_get_ribbon(anno_icon);
562 if (detail_text)
563 {
564+ const int SHADOW_BOTTOM_PADDING = 2;
565+ const int SHADOW_SIDE_PADDING = 1;
566 int icon_w = gdk_pixbuf_get_width(result);
567 int icon_h = gdk_pixbuf_get_height(result);
568
569 int max_font_height;
570 CalculateTextHeight(nullptr, &max_font_height);
571
572- max_font_height = max_font_height * 9 / 8; // let's have some padding on the stripe
573- int pixbuf_size = static_cast<int>(
574- sqrt(max_font_height*max_font_height*8));
575- if (pixbuf_size > icon_w) pixbuf_size = icon_w;
576+ // FIXME: design wants the tags 2px wider than the original icon
577+ int pixbuf_width = icon_w;
578+ int pixbuf_height = max_font_height * 5 / 4 + SHADOW_BOTTOM_PADDING;
579+ if (pixbuf_height > icon_h) pixbuf_height = icon_h;
580
581 nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32,
582- pixbuf_size, pixbuf_size);
583+ pixbuf_width, pixbuf_height);
584 std::shared_ptr<cairo_t> cr(cairo_graphics.GetContext(), cairo_destroy);
585
586 glib::Object<PangoLayout> layout;
587@@ -325,10 +335,9 @@
588 pango_layout_set_font_description(layout, desc.get());
589 pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
590
591- double size_dbl = static_cast<double>(pixbuf_size);
592- // we'll allow tiny bit of overflow since the text is rotated and there
593- // is some space left... FIXME: 10/9? / 11/10?
594- double max_text_width = sqrt(size_dbl*size_dbl / 2) * 9/8;
595+ // magic constant for the text width based on the white curve
596+ double max_text_width = has_emblem ?
597+ pixbuf_width * 0.72 : pixbuf_width;
598
599 pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
600 pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
601@@ -337,9 +346,8 @@
602 pango_layout_set_markup(layout, escaped_text, -1);
603
604 pango_context = pango_layout_get_context(layout); // is not ref'ed
605- // FIXME: for reasons unknown, it looks better without this
606- //pango_cairo_context_set_font_options(pango_context,
607- // gdk_screen_get_font_options(screen));
608+ pango_cairo_context_set_font_options(pango_context,
609+ gdk_screen_get_font_options(screen));
610 pango_cairo_context_set_resolution(pango_context,
611 dpi == -1 ? 96.0f : dpi/(float) PANGO_SCALE);
612 pango_layout_context_changed(layout);
613@@ -361,32 +369,117 @@
614
615 cairo_set_operator(cr.get(), CAIRO_OPERATOR_OVER);
616
617- // draw the trapezoid
618- cairo_move_to(cr.get(), 0.0, size_dbl);
619- cairo_line_to(cr.get(), size_dbl, 0.0);
620- cairo_line_to(cr.get(), size_dbl, size_dbl / 2.0);
621- cairo_line_to(cr.get(), size_dbl / 2.0, size_dbl);
622- cairo_close_path(cr.get());
623-
624 // this should be #dd4814
625- cairo_set_source_rgba(cr.get(), 0.86666f, 0.28235f, 0.07843f, 1.0f);
626+ const double ORANGE_R = 0.86666;
627+ const double ORANGE_G = 0.28235;
628+ const double ORANGE_B = 0.07843;
629+
630+ double belt_w = static_cast<double>(pixbuf_width - SHADOW_SIDE_PADDING * 2);
631+ double belt_h = static_cast<double>(pixbuf_height - SHADOW_BOTTOM_PADDING);
632+
633+ // translate to make space for the shadow
634+ cairo_save(cr.get());
635+ cairo_translate(cr.get(), 1.0, 1.0);
636+
637+ cairo_set_source_rgba(cr.get(), ORANGE_R, ORANGE_G, ORANGE_B, 1.0);
638+
639+ cairo_rectangle(cr.get(), 0.0, 0.0, belt_w, belt_h);
640+ cairo_fill_preserve(cr.get());
641+
642+ std::shared_ptr<cairo_pattern_t> pattern(
643+ cairo_pattern_create_linear(0.0, 0.0, belt_w, 0.0),
644+ cairo_pattern_destroy);
645+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.0, 1.0, 1.0, 1.0, 0.235294);
646+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.02, 1.0, 1.0, 1.0, 0.0);
647+ if (!has_emblem)
648+ {
649+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.98, 1.0, 1.0, 1.0, 0.0);
650+ cairo_pattern_add_color_stop_rgba(pattern.get(), 1.0, 1.0, 1.0, 1.0, 0.235294);
651+ }
652+ cairo_pattern_add_color_stop_rgba(pattern.get(), 1.0, 1.0, 1.0, 1.0, 0.0);
653+
654+ cairo_set_source(cr.get(), pattern.get());
655 cairo_fill(cr.get());
656
657- // draw the text (rotated!)
658- cairo_set_source_rgba(cr.get(), 1.0f, 1.0f, 1.0f, 1.0f);
659- cairo_move_to(cr.get(), size_dbl * 0.25, size_dbl);
660- cairo_rotate(cr.get(), -G_PI_4); // rotate by -45 degrees
661-
662- pango_cairo_update_layout(cr.get(), layout);
663+ if (has_emblem)
664+ {
665+ // paint the curve
666+ const double CURVE_START_XPOS = 0.631163; // 0.651163
667+ const double CURVE_CP1_XPOS = CURVE_START_XPOS + 0.068023;
668+ const double CURVE_CP2_XPOS = CURVE_START_XPOS + 0.07;
669+ const double CURVE_CP3_XPOS = CURVE_START_XPOS + 0.102965;
670+ const double CURVE_CP4_XPOS = CURVE_START_XPOS + 0.161511;
671+ const double CURVE_CP5_XPOS = CURVE_START_XPOS + 0.197093;
672+ const double CURVE_END_XPOS = CURVE_START_XPOS + 0.265779;
673+
674+ const double CURVE_START_X = CURVE_START_XPOS * belt_w;
675+
676+ cairo_set_source_rgba(cr.get(), 1.0, 1.0, 1.0, 1.0);
677+
678+ cairo_move_to(cr.get(), CURVE_START_XPOS * belt_w, belt_h);
679+ cairo_curve_to(cr.get(), CURVE_CP1_XPOS * belt_w, belt_h,
680+ CURVE_CP2_XPOS * belt_w, 0.9825 * belt_h,
681+ CURVE_CP3_XPOS * belt_w, 0.72725 * belt_h);
682+ cairo_line_to(cr.get(), CURVE_CP4_XPOS * belt_w, 0.27275 * belt_h);
683+ cairo_curve_to(cr.get(), CURVE_CP5_XPOS * belt_w, 0.0,
684+ CURVE_CP5_XPOS * belt_w, 0.0,
685+ CURVE_END_XPOS * belt_w, 0.0);
686+ cairo_line_to(cr.get(), belt_w, 0.0);
687+ cairo_line_to(cr.get(), belt_w, belt_h);
688+ cairo_close_path(cr.get());
689+ cairo_fill(cr.get());
690+
691+ // and the highlight
692+ pattern.reset(cairo_pattern_create_linear(CURVE_START_X, 0.0, belt_w, 0.0),
693+ cairo_pattern_destroy);
694+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.0, 1.0, 1.0, 1.0, 0.0);
695+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.95, 1.0, 1.0, 1.0, 0.0);
696+ cairo_pattern_add_color_stop_rgba(pattern.get(), 1.0, 0.0, 0.0, 0.0, 0.235294);
697+ cairo_set_source(cr.get(), pattern.get());
698+ cairo_rectangle(cr.get(), CURVE_START_X, 0.0, belt_w - CURVE_START_X, belt_h);
699+ cairo_fill(cr.get());
700+
701+ // paint the emblem
702+ int category_pb_w = gdk_pixbuf_get_width(category_pixbuf);
703+ int category_pb_h = gdk_pixbuf_get_height(category_pixbuf);
704+ double category_pb_x =
705+ belt_w - category_pb_w > CURVE_CP4_XPOS * belt_w ?
706+ CURVE_CP4_XPOS * belt_w + ((1 - CURVE_CP4_XPOS) * belt_w - category_pb_w) / 2 : CURVE_CP4_XPOS * belt_w;
707+ gdk_cairo_set_source_pixbuf(cr.get(), category_pixbuf,
708+ category_pb_x, (belt_h - category_pb_h) / 2);
709+ cairo_paint(cr.get());
710+ }
711+
712+ cairo_set_source_rgba(cr.get(), 1.0, 1.0, 1.0, 1.0);
713+ cairo_move_to(cr.get(), 0.0, belt_h / 2);
714 pango_layout_get_pixel_size(layout, nullptr, &text_height);
715 // current point is now in the middle of the stripe, need to translate
716 // it, so that the text is centered
717 cairo_rel_move_to(cr.get(), 0.0, text_height / -2.0);
718- double diagonal = sqrt(size_dbl*size_dbl*2);
719- // x coordinate also needs to be shifted
720- cairo_rel_move_to(cr.get(), (diagonal - max_text_width) / 4, 0.0);
721 pango_cairo_show_layout(cr.get(), layout);
722
723+ // paint the shadow
724+ cairo_restore(cr.get());
725+
726+ pattern.reset(cairo_pattern_create_linear(0.0, belt_h, 0.0, belt_h + SHADOW_BOTTOM_PADDING),
727+ cairo_pattern_destroy);
728+ cairo_pattern_add_color_stop_rgba(pattern.get(), 0.0, 0.0, 0.0, 0.0, 0.2);
729+ cairo_pattern_add_color_stop_rgba(pattern.get(), 1.0, 0.0, 0.0, 0.0, 0.0);
730+
731+ cairo_set_source(cr.get(), pattern.get());
732+
733+ cairo_rectangle(cr.get(), 0.0, belt_h, belt_w, SHADOW_BOTTOM_PADDING);
734+ cairo_fill(cr.get());
735+
736+ cairo_set_source_rgba(cr.get(), 0.0, 0.0, 0.0, 0.1);
737+ cairo_move_to(cr.get(), 0.0, 1.0);
738+ cairo_line_to(cr.get(), 0.0, belt_h);
739+ cairo_stroke(cr.get());
740+
741+ cairo_move_to(cr.get(), belt_w, 1.0);
742+ cairo_line_to(cr.get(), belt_w, belt_h);
743+ cairo_stroke(cr.get());
744+
745 // FIXME: going from image_surface to pixbuf, and then to texture :(
746 glib::Object<GdkPixbuf> detail_pb(
747 gdk_pixbuf_get_from_surface(cairo_graphics.GetSurface(),
748@@ -394,13 +487,14 @@
749 cairo_graphics.GetWidth(),
750 cairo_graphics.GetHeight()));
751
752+ int y_pos = icon_h - pixbuf_height - max_font_height / 2;
753 gdk_pixbuf_composite(detail_pb, result, // src, dest
754- icon_w - pixbuf_size, // dest_x
755- icon_h - pixbuf_size, // dest_y
756- pixbuf_size, // dest_w
757- pixbuf_size, // dest_h
758- icon_w - pixbuf_size, // offset_x
759- icon_h - pixbuf_size, // offset_y
760+ 0, // dest_x
761+ y_pos, // dest_y
762+ pixbuf_width, // dest_w
763+ pixbuf_height, // dest_h
764+ 0, // offset_x
765+ y_pos, // offset_y
766 1.0, 1.0, // scale_x, scale_y
767 GDK_INTERP_NEAREST, // interpolation
768 255); // src_alpha
769@@ -409,29 +503,76 @@
770 idle_id = g_idle_add(LoadIconComplete, this);
771 }
772
773- void BaseIconLoaded(std::string const& base_icon_string, unsigned size,
774+ void BaseIconLoaded(std::string const& base_icon_string,
775+ int max_width, int max_height,
776 glib::Object<GdkPixbuf> const& base_pixbuf,
777 glib::Object<UnityProtocolAnnotatedIcon> const& anno_icon)
778 {
779 helper_handle = 0;
780 if (base_pixbuf)
781 {
782- result = gdk_pixbuf_copy(base_pixbuf);
783+ LOG_DEBUG(logger) << "Base icon loaded: '" << base_icon_string <<
784+ "' size: " << gdk_pixbuf_get_width(base_pixbuf) << 'x' <<
785+ gdk_pixbuf_get_height(base_pixbuf);
786+
787+ // we need extra space for the ribbon
788+ result = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8,
789+ gdk_pixbuf_get_width(base_pixbuf) + RIBBON_PADDING * 2,
790+ gdk_pixbuf_get_height(base_pixbuf));
791+ gdk_pixbuf_fill(result, 0x0);
792+ gdk_pixbuf_copy_area(base_pixbuf, 0, 0,
793+ gdk_pixbuf_get_width(base_pixbuf),
794+ gdk_pixbuf_get_height(base_pixbuf),
795+ result,
796+ RIBBON_PADDING, 0);
797 // FIXME: can we composite the pixbuf in helper thread?
798 UnityProtocolCategoryType category = unity_protocol_annotated_icon_get_category(anno_icon);
799 auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::CategoryIconLoaded), anno_icon);
800- unsigned cat_size = size / 4;
801- // FIXME: we still don't have the category assets
802+ int max_font_height;
803+ CalculateTextHeight(nullptr, &max_font_height);
804+ unsigned cat_size = max_font_height * 9 / 8;
805 switch (category)
806 {
807+ case UNITY_PROTOCOL_CATEGORY_TYPE_BOOK:
808+ helper_handle =
809+ impl->LoadFromFilename(PKGDATADIR"/emblem_books.svg", -1, cat_size, helper_slot);
810+ break;
811 case UNITY_PROTOCOL_CATEGORY_TYPE_MUSIC:
812 helper_handle =
813- impl->LoadFromIconName("emblem-favorite", cat_size, helper_slot);
814- break;
815+ impl->LoadFromFilename(PKGDATADIR"/emblem_music.svg", -1, cat_size, helper_slot);
816+ break;
817+ case UNITY_PROTOCOL_CATEGORY_TYPE_MOVIE:
818+ helper_handle =
819+ impl->LoadFromFilename(PKGDATADIR"/emblem_video.svg", -1, cat_size, helper_slot);
820+ break;
821+ case UNITY_PROTOCOL_CATEGORY_TYPE_CLOTHES:
822+ case UNITY_PROTOCOL_CATEGORY_TYPE_SHOES:
823+ helper_handle =
824+ impl->LoadFromFilename(PKGDATADIR"/emblem_clothes.svg", -1, cat_size, helper_slot);
825+ break;
826+ case UNITY_PROTOCOL_CATEGORY_TYPE_GAMES:
827+ case UNITY_PROTOCOL_CATEGORY_TYPE_ELECTRONICS:
828+ case UNITY_PROTOCOL_CATEGORY_TYPE_COMPUTERS:
829+ case UNITY_PROTOCOL_CATEGORY_TYPE_OFFICE:
830+ case UNITY_PROTOCOL_CATEGORY_TYPE_HOME:
831+ case UNITY_PROTOCOL_CATEGORY_TYPE_GARDEN:
832+ case UNITY_PROTOCOL_CATEGORY_TYPE_PETS:
833+ case UNITY_PROTOCOL_CATEGORY_TYPE_TOYS:
834+ case UNITY_PROTOCOL_CATEGORY_TYPE_CHILDREN:
835+ case UNITY_PROTOCOL_CATEGORY_TYPE_BABY:
836+ case UNITY_PROTOCOL_CATEGORY_TYPE_WATCHES:
837+ case UNITY_PROTOCOL_CATEGORY_TYPE_SPORTS:
838+ case UNITY_PROTOCOL_CATEGORY_TYPE_OUTDOORS:
839+ case UNITY_PROTOCOL_CATEGORY_TYPE_GROCERY:
840+ case UNITY_PROTOCOL_CATEGORY_TYPE_HEALTH:
841+ case UNITY_PROTOCOL_CATEGORY_TYPE_BEAUTY:
842+ case UNITY_PROTOCOL_CATEGORY_TYPE_DIY:
843+ case UNITY_PROTOCOL_CATEGORY_TYPE_TOOLS:
844+ case UNITY_PROTOCOL_CATEGORY_TYPE_CAR:
845 default:
846 // rest of the processing is the CategoryIconLoaded, lets invoke it
847 glib::Object<GdkPixbuf> null_pixbuf;
848- helper_slot("", cat_size, null_pixbuf);
849+ helper_slot("", -1, cat_size, null_pixbuf);
850 break;
851 }
852 }
853@@ -463,32 +604,23 @@
854 glib::String contents;
855 gsize length = 0;
856
857- if (::g_file_load_contents(file, canc, &contents, &length,
858+ if (g_file_load_contents(file, canc, &contents, &length,
859 nullptr, &task->error))
860 {
861 glib::Object<GInputStream> stream(
862- ::g_memory_input_stream_new_from_data(contents.Value(), length, nullptr));
863+ g_memory_input_stream_new_from_data(contents.Value(), length, nullptr));
864
865- if (task->size != static_cast<unsigned int>(~0))
866- {
867- task->result = ::gdk_pixbuf_new_from_stream_at_scale(stream,
868- -1,
869- task->size,
870- TRUE,
871- canc,
872- &task->error);
873- }
874- else
875- {
876- task->result = ::gdk_pixbuf_new_from_stream(stream,
877- canc,
878- &task->error);
879- }
880- ::g_input_stream_close(stream, canc, nullptr);
881+ task->result = gdk_pixbuf_new_from_stream_at_scale(stream,
882+ task->max_width,
883+ task->max_height,
884+ TRUE,
885+ canc,
886+ &task->error);
887+ g_input_stream_close(stream, canc, nullptr);
888 }
889 }
890
891- ::g_io_scheduler_job_send_to_mainloop_async (job, LoadIconComplete, task, nullptr);
892+ g_io_scheduler_job_send_to_mainloop_async (job, LoadIconComplete, task, nullptr);
893
894 return FALSE;
895 }
896@@ -509,7 +641,9 @@
897 task->result = nullptr;
898
899 LOG_WARNING(logger) << "Unable to load icon " << task->data
900- << " at size " << task->size << ": " << task->error;
901+ << " at size "
902+ << task->max_width << "x" << task->max_height
903+ << ": " << task->error;
904 }
905
906 impl->finished_tasks_.push_back(task);
907@@ -528,21 +662,24 @@
908 };
909
910 Handle ReturnCachedOrQueue(std::string const& data,
911- unsigned size,
912+ int max_width,
913+ int max_height,
914 IconLoaderCallback slot,
915 IconLoaderRequestType type);
916
917 Handle QueueTask(std::string const& key,
918 std::string const& data,
919- unsigned size,
920+ int max_width,
921+ int max_height,
922 IconLoaderCallback slot,
923 IconLoaderRequestType type);
924
925- std::string Hash(std::string const& data, unsigned size);
926+ std::string Hash(std::string const& data, int max_width, int max_height);
927
928 bool CacheLookup(std::string const& key,
929 std::string const& data,
930- unsigned size,
931+ int max_width,
932+ int max_height,
933 IconLoaderCallback slot);
934
935 // Looping idle callback function
936@@ -600,52 +737,67 @@
937 }
938
939 int IconLoader::Impl::LoadFromIconName(std::string const& icon_name,
940- unsigned size,
941+ int max_width,
942+ int max_height,
943 IconLoaderCallback slot)
944 {
945- if (no_load_ || icon_name.empty() || size < MIN_ICON_SIZE || !slot)
946+ if (no_load_ || icon_name.empty() || !slot ||
947+ ((max_width >= 0 && max_width < MIN_ICON_SIZE) ||
948+ (max_height >= 0 && max_height < MIN_ICON_SIZE)))
949 return 0;
950
951 // We need to check this because of legacy desktop files
952 if (icon_name[0] == '/')
953 {
954- return LoadFromFilename(icon_name, size, slot);
955+ return LoadFromFilename(icon_name, max_width, max_height, slot);
956 }
957
958- return ReturnCachedOrQueue(icon_name, size, slot, REQUEST_TYPE_ICON_NAME);
959+ return ReturnCachedOrQueue(icon_name, max_width, max_height, slot,
960+ REQUEST_TYPE_ICON_NAME);
961 }
962
963 int IconLoader::Impl::LoadFromGIconString(std::string const& gicon_string,
964- unsigned size,
965+ int max_width,
966+ int max_height,
967 IconLoaderCallback slot)
968 {
969- if (no_load_ || gicon_string.empty() || size < MIN_ICON_SIZE || !slot)
970+ if (no_load_ || gicon_string.empty() || !slot ||
971+ ((max_width >= 0 && max_width < MIN_ICON_SIZE) ||
972+ (max_height >= 0 && max_height < MIN_ICON_SIZE)))
973 return 0;
974
975- return ReturnCachedOrQueue(gicon_string, size, slot, REQUEST_TYPE_GICON_STRING);
976+ return ReturnCachedOrQueue(gicon_string, max_width, max_height, slot,
977+ REQUEST_TYPE_GICON_STRING);
978 }
979
980 int IconLoader::Impl::LoadFromFilename(std::string const& filename,
981- unsigned size,
982+ int max_width,
983+ int max_height,
984 IconLoaderCallback slot)
985 {
986- if (no_load_ || filename.empty() || size < MIN_ICON_SIZE || !slot)
987+ if (no_load_ || filename.empty() || !slot ||
988+ ((max_width >= 0 && max_width < MIN_ICON_SIZE) ||
989+ (max_height >= 0 && max_height < MIN_ICON_SIZE)))
990 return 0;
991
992 glib::Object<GFile> file(::g_file_new_for_path(filename.c_str()));
993 glib::String uri(::g_file_get_uri(file));
994
995- return LoadFromURI(uri.Str(), size, slot);
996+ return LoadFromURI(uri.Str(), max_width, max_height, slot);
997 }
998
999 int IconLoader::Impl::LoadFromURI(std::string const& uri,
1000- unsigned size,
1001+ int max_width,
1002+ int max_height,
1003 IconLoaderCallback slot)
1004 {
1005- if (no_load_ || uri.empty() || size < MIN_ICON_SIZE || !slot)
1006+ if (no_load_ || uri.empty() || !slot ||
1007+ ((max_width >= 0 && max_width < MIN_ICON_SIZE) ||
1008+ (max_height >= 0 && max_height < MIN_ICON_SIZE)))
1009 return 0;
1010
1011- return ReturnCachedOrQueue(uri, size, slot, REQUEST_TYPE_URI);
1012+ return ReturnCachedOrQueue(uri, max_width, max_height, slot,
1013+ REQUEST_TYPE_URI);
1014 }
1015
1016 void IconLoader::Impl::DisconnectHandle(Handle handle)
1017@@ -699,16 +851,17 @@
1018 //
1019
1020 int IconLoader::Impl::ReturnCachedOrQueue(std::string const& data,
1021- unsigned size,
1022+ int max_width,
1023+ int max_height,
1024 IconLoaderCallback slot,
1025 IconLoaderRequestType type)
1026 {
1027 Handle result = 0;
1028- std::string key(Hash(data, size));
1029+ std::string key(Hash(data, max_width, max_height));
1030
1031- if (!CacheLookup(key, data, size, slot))
1032+ if (!CacheLookup(key, data, max_width, max_height, slot))
1033 {
1034- result = QueueTask(key, data, size, slot, type);
1035+ result = QueueTask(key, data, max_width, max_height, slot, type);
1036 }
1037 return result;
1038 }
1039@@ -716,11 +869,15 @@
1040
1041 int IconLoader::Impl::QueueTask(std::string const& key,
1042 std::string const& data,
1043- unsigned size,
1044+ int max_width,
1045+ int max_height,
1046 IconLoaderCallback slot,
1047 IconLoaderRequestType type)
1048 {
1049- auto task = std::make_shared<IconLoaderTask>(type, data, size, key, slot, ++handle_counter_, this);
1050+ auto task = std::make_shared<IconLoaderTask>(type, data,
1051+ max_width, max_height,
1052+ key, slot,
1053+ ++handle_counter_, this);
1054 auto iter = queued_tasks_.find(key);
1055
1056 if (iter != queued_tasks_.end())
1057@@ -744,7 +901,8 @@
1058 tasks_.push(task);
1059 task_map_[task->handle] = task;
1060
1061- LOG_DEBUG(logger) << "Pushing task " << data << " at size " << size
1062+ LOG_DEBUG(logger) << "Pushing task " << data << " at size "
1063+ << max_width << "x" << max_height
1064 << ", queue size now at " << tasks_.size();
1065
1066 if (!idle_)
1067@@ -754,16 +912,17 @@
1068 return task->handle;
1069 }
1070
1071-std::string IconLoader::Impl::Hash(std::string const& data, unsigned size)
1072+std::string IconLoader::Impl::Hash(std::string const& data, int max_width, int max_height)
1073 {
1074 std::ostringstream sout;
1075- sout << data << ":" << size;
1076+ sout << data << ":" << max_width << "x" << max_height;
1077 return sout.str();
1078 }
1079
1080 bool IconLoader::Impl::CacheLookup(std::string const& key,
1081 std::string const& data,
1082- unsigned size,
1083+ int max_width,
1084+ int max_height,
1085 IconLoaderCallback slot)
1086 {
1087 auto iter = cache_.find(key);
1088@@ -772,7 +931,7 @@
1089 if (found && slot)
1090 {
1091 glib::Object<GdkPixbuf> const& pixbuf = iter->second;
1092- slot(data, size, pixbuf);
1093+ slot(data, max_width, max_height, pixbuf);
1094 }
1095
1096 return found;
1097@@ -848,31 +1007,35 @@
1098 }
1099
1100 int IconLoader::LoadFromIconName(std::string const& icon_name,
1101- unsigned size,
1102+ int max_width,
1103+ int max_height,
1104 IconLoaderCallback slot)
1105 {
1106- return pimpl->LoadFromIconName(icon_name, size, slot);
1107+ return pimpl->LoadFromIconName(icon_name, max_width, max_height, slot);
1108 }
1109
1110 int IconLoader::LoadFromGIconString(std::string const& gicon_string,
1111- unsigned size,
1112+ int max_width,
1113+ int max_height,
1114 IconLoaderCallback slot)
1115 {
1116- return pimpl->LoadFromGIconString(gicon_string, size, slot);
1117+ return pimpl->LoadFromGIconString(gicon_string, max_width, max_height, slot);
1118 }
1119
1120 int IconLoader::LoadFromFilename(std::string const& filename,
1121- unsigned size,
1122+ int max_width,
1123+ int max_height,
1124 IconLoaderCallback slot)
1125 {
1126- return pimpl->LoadFromFilename(filename, size, slot);
1127+ return pimpl->LoadFromFilename(filename, max_width, max_height, slot);
1128 }
1129
1130 int IconLoader::LoadFromURI(std::string const& uri,
1131- unsigned size,
1132+ int max_width,
1133+ int max_height,
1134 IconLoaderCallback slot)
1135 {
1136- return pimpl->LoadFromURI(uri, size, slot);
1137+ return pimpl->LoadFromURI(uri, max_width, max_height, slot);
1138 }
1139
1140 void IconLoader::DisconnectHandle(int handle)
1141
1142=== modified file 'unity-shared/IconLoader.h'
1143--- unity-shared/IconLoader.h 2012-07-16 11:03:32 +0000
1144+++ unity-shared/IconLoader.h 2012-09-13 10:12:22 +0000
1145@@ -32,7 +32,7 @@
1146 class IconLoader : public boost::noncopyable
1147 {
1148 public:
1149- typedef std::function<void(std::string const&, unsigned, glib::Object<GdkPixbuf> const&)> IconLoaderCallback;
1150+ typedef std::function<void(std::string const&, int, int, glib::Object<GdkPixbuf> const&)> IconLoaderCallback;
1151
1152 IconLoader();
1153 ~IconLoader();
1154@@ -45,19 +45,23 @@
1155 */
1156
1157 int LoadFromIconName(std::string const& icon_name,
1158- unsigned size,
1159+ int max_width,
1160+ int max_height,
1161 IconLoaderCallback slot);
1162
1163 int LoadFromGIconString(std::string const& gicon_string,
1164- unsigned size,
1165+ int max_width,
1166+ int max_height,
1167 IconLoaderCallback slot);
1168
1169 int LoadFromFilename(std::string const& filename,
1170- unsigned size,
1171+ int max_width,
1172+ int max_height,
1173 IconLoaderCallback slot);
1174
1175 int LoadFromURI(std::string const& uri,
1176- unsigned size,
1177+ int max_width,
1178+ int max_height,
1179 IconLoaderCallback slot);
1180
1181 void DisconnectHandle(int handle);
1182
1183=== modified file 'unity-shared/IconTexture.cpp'
1184--- unity-shared/IconTexture.cpp 2012-08-07 15:46:38 +0000
1185+++ unity-shared/IconTexture.cpp 2012-09-13 10:12:22 +0000
1186@@ -111,21 +111,21 @@
1187
1188 glib::Object<GIcon> icon(g_icon_new_for_string(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(), NULL));
1189
1190- if (G_IS_ICON(icon.RawPtr()))
1191+ if (icon.IsType(G_TYPE_ICON))
1192 {
1193 _handle = IconLoader::GetDefault().LoadFromGIconString(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(),
1194- _size,
1195+ -1, _size,
1196 sigc::mem_fun(this, &IconTexture::IconLoaded));
1197 }
1198 else if (_icon_name.find("http://") == 0)
1199 {
1200 _handle = IconLoader::GetDefault().LoadFromURI(_icon_name,
1201- _size, sigc::mem_fun(this, &IconTexture::IconLoaded));
1202+ -1, _size, sigc::mem_fun(this, &IconTexture::IconLoaded));
1203 }
1204 else
1205 {
1206 _handle = IconLoader::GetDefault().LoadFromIconName(_icon_name,
1207- _size,
1208+ -1, _size,
1209 sigc::mem_fun(this, &IconTexture::IconLoaded));
1210 }
1211 }
1212@@ -153,7 +153,9 @@
1213 _loading = false;
1214 }
1215
1216-void IconTexture::IconLoaded(std::string const& icon_name, unsigned size,
1217+void IconTexture::IconLoaded(std::string const& icon_name,
1218+ int max_width,
1219+ int max_height,
1220 glib::Object<GdkPixbuf> const& pixbuf)
1221 {
1222 _handle = 0;
1223
1224=== modified file 'unity-shared/IconTexture.h'
1225--- unity-shared/IconTexture.h 2012-08-07 15:46:38 +0000
1226+++ unity-shared/IconTexture.h 2012-09-13 10:12:22 +0000
1227@@ -79,7 +79,7 @@
1228 private:
1229 nux::BaseTexture* CreateTextureCallback(std::string const& texid, int width, int height);
1230 void Refresh(glib::Object<GdkPixbuf> const& pixbuf);
1231- void IconLoaded(std::string const& icon_name, unsigned size, glib::Object<GdkPixbuf> const& pixbuf);
1232+ void IconLoaded(std::string const& icon_name, int max_width, int max_height, glib::Object<GdkPixbuf> const& pixbuf);
1233
1234 std::string _icon_name;
1235 unsigned int _size;