Merge lp:~nick-dedekind/unity/lp863412.dash-result-dnd-icon into lp:unity

Proposed by Nick Dedekind
Status: Merged
Approved by: Francis Ginther
Approved revision: no longer in the source branch.
Merged at revision: 2967
Proposed branch: lp:~nick-dedekind/unity/lp863412.dash-result-dnd-icon
Merge into: lp:unity
Diff against target: 742 lines (+332/-124)
15 files modified
UnityCore/ModelRowAdaptor-inl.h (+3/-3)
UnityCore/ModelRowAdaptor.cpp (+14/-0)
UnityCore/ModelRowAdaptor.h (+11/-6)
UnityCore/Result.cpp (+15/-7)
UnityCore/Result.h (+9/-0)
dash/ResultRenderer.cpp (+95/-0)
dash/ResultRenderer.h (+3/-0)
dash/ResultRendererHorizontalTile.cpp (+21/-1)
dash/ResultRendererHorizontalTile.h (+2/-0)
dash/ResultRendererTile.cpp (+18/-5)
dash/ResultRendererTile.h (+4/-0)
dash/ResultViewGrid.cpp (+11/-101)
dash/ResultViewGrid.h (+1/-1)
tests/CMakeLists.txt (+1/-0)
tests/test_result_renderer.cpp (+124/-0)
To merge this branch: bzr merge lp:~nick-dedekind/unity/lp863412.dash-result-dnd-icon
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Needs Fixing
Brandon Schaefer (community) Approve
Review via email: mp+138527@code.launchpad.net

Commit message

Use the dash rendered icon as the source for the drag icon.

Description of the change

= Problem description =

Dash result drag icon is not the same as the icon rendered onto the dash.
https://bugs.launchpad.net/unity/+bug/863412

= The fix =

Use the dash rendered icon as the source for the drag icon.

= Test coverage =

Cannot directly test the drag icon.
Added unit test harness for result renderer. Includes tests for result renderer construction and dnd icon return.

To post a comment you must log in.
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

Looks good, just couple things:

60 + virtual ~RowAdaptorBase();

Could we make this pure? Or just define it in the header, with a {}?

437 + , drag_index_(~0)
585 + drag_index_ = ~0;

Why not just -1? As the bit complement of 0 is a bit less readable. (Though I like it :)
Unless you change all the -1 usage to ~0, it should be consistent.

review: Needs Fixing
Revision history for this message
Nick Dedekind (nick-dedekind) wrote :

> Looks good, just couple things:
>
> 60 + virtual ~RowAdaptorBase();
>
> Could we make this pure? Or just define it in the header, with a {}?
>

Pure virtual would require the derived classes to implement a destructor.
I don't see any benifit from inlining the destructor in a non-abstract class.

> 437 + , drag_index_(~0)
> 585 + drag_index_ = ~0;
>
> Why not just -1? As the bit complement of 0 is a bit less readable. (Though I
> like it :)
> Unless you change all the -1 usage to ~0, it should be consistent.

-1 is not an unsigned value.
I believe a comparison of "-1 == (unsigned)value" will cause an overflow error on 64bit systems.
There are a few instances of ~0 for unsigned values around the code
And they should all be changed, but I'm not going to go around and find them. :)

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

O I didn't notice it was an unsigned int...cool looks good then!

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Francis Ginther (fginther) wrote :

Re-approving. Autolanding failed due to a API change with compiz that was not yet reflected in unity. The API change has been resolved.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'UnityCore/ModelRowAdaptor-inl.h'
2--- UnityCore/ModelRowAdaptor-inl.h 2011-07-29 14:21:22 +0000
3+++ UnityCore/ModelRowAdaptor-inl.h 2012-12-06 18:02:23 +0000
4@@ -28,13 +28,13 @@
5 template<typename T>
6 void RowAdaptorBase::set_renderer(T renderer)
7 {
8- dee_model_set_tag(model_, iter_, tag_, renderer);
9+ set_model_tag(renderer);
10 }
11
12 template<typename T>
13-T RowAdaptorBase::renderer()
14+T RowAdaptorBase::renderer() const
15 {
16- return static_cast<T>(dee_model_get_tag(model_, iter_, tag_));
17+ return static_cast<T>(get_model_tag());
18 }
19
20 }
21
22=== modified file 'UnityCore/ModelRowAdaptor.cpp'
23--- UnityCore/ModelRowAdaptor.cpp 2012-09-02 20:34:37 +0000
24+++ UnityCore/ModelRowAdaptor.cpp 2012-12-06 18:02:23 +0000
25@@ -36,6 +36,10 @@
26 tag_ = other.tag_;
27 }
28
29+RowAdaptorBase::~RowAdaptorBase()
30+{
31+}
32+
33 RowAdaptorBase& RowAdaptorBase::operator=(RowAdaptorBase const& other)
34 {
35 model_ = other.model_;
36@@ -91,5 +95,15 @@
37 return static_cast<float>(dee_model_get_double(model_, iter_, position));
38 }
39
40+void RowAdaptorBase::set_model_tag(gpointer value)
41+{
42+ dee_model_set_tag(model_, iter_, tag_, value);
43+}
44+
45+gpointer RowAdaptorBase::get_model_tag() const
46+{
47+ return dee_model_get_tag(model_, iter_, tag_);
48+}
49+
50 }
51 }
52
53=== modified file 'UnityCore/ModelRowAdaptor.h'
54--- UnityCore/ModelRowAdaptor.h 2012-09-02 20:34:37 +0000
55+++ UnityCore/ModelRowAdaptor.h 2012-12-06 18:02:23 +0000
56@@ -50,13 +50,15 @@
57 public:
58 RowAdaptorBase(DeeModel* model=0, DeeModelIter* iter=0, DeeModelTag* tag=0);
59 RowAdaptorBase(RowAdaptorBase const& other);
60+ virtual ~RowAdaptorBase();
61+
62 RowAdaptorBase& operator=(RowAdaptorBase const& other);
63
64- std::string GetStringAt(int position) const;
65- bool GetBoolAt(int position) const;
66- int GetIntAt(int position) const;
67- unsigned int GetUIntAt(int position) const;
68- float GetFloatAt(int position) const;
69+ virtual std::string GetStringAt(int position) const;
70+ virtual bool GetBoolAt(int position) const;
71+ virtual int GetIntAt(int position) const;
72+ virtual unsigned int GetUIntAt(int position) const;
73+ virtual float GetFloatAt(int position) const;
74
75 void SetTarget(DeeModel* model, DeeModelIter* iter, DeeModelTag* tag);
76
77@@ -64,9 +66,12 @@
78 void set_renderer(T renderer);
79
80 template<typename T>
81- T renderer();
82+ T renderer() const;
83
84 protected:
85+ virtual void set_model_tag(gpointer value);
86+ virtual gpointer get_model_tag() const;
87+
88 DeeModel* model_;
89 DeeModelIter* iter_;
90 DeeModelTag* tag_;
91
92=== modified file 'UnityCore/Result.cpp'
93--- UnityCore/Result.cpp 2011-09-13 22:35:13 +0000
94+++ UnityCore/Result.cpp 2012-12-06 18:02:23 +0000
95@@ -48,14 +48,22 @@
96
97 void Result::SetupGetters()
98 {
99- uri.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 0));
100- icon_hint.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 1));
101- category_index.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetUIntAt), 2));
102- mimetype.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 3));
103- name.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 4));
104- comment.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 5));
105- dnd_uri.SetGetterFunction(sigc::bind(sigc::mem_fun(this, &RowAdaptorBase::GetStringAt), 6));
106+ uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetURI));
107+ icon_hint.SetGetterFunction(sigc::mem_fun(this, &Result::GetIconHint));
108+ category_index.SetGetterFunction(sigc::mem_fun(this, &Result::GetCategoryIndex));
109+ mimetype.SetGetterFunction(sigc::mem_fun(this, &Result::GetMimeType));
110+ name.SetGetterFunction(sigc::mem_fun(this, &Result::GetName));
111+ comment.SetGetterFunction(sigc::mem_fun(this, &Result::GetComment));
112+ dnd_uri.SetGetterFunction(sigc::mem_fun(this, &Result::GetDndURI));
113 }
114+
115+std::string Result::GetURI() const { return GetStringAt(0); }
116+std::string Result::GetIconHint() const { return GetStringAt(1); }
117+std::size_t Result::GetCategoryIndex() const { return GetUIntAt(2); }
118+std::string Result::GetMimeType() const { return GetStringAt(3); }
119+std::string Result::GetName() const { return GetStringAt(4); }
120+std::string Result::GetComment() const { return GetStringAt(5); }
121+std::string Result::GetDndURI() const { return GetStringAt(6); }
122
123 }
124 }
125
126=== modified file 'UnityCore/Result.h'
127--- UnityCore/Result.h 2011-09-13 22:35:13 +0000
128+++ UnityCore/Result.h 2012-12-06 18:02:23 +0000
129@@ -51,6 +51,15 @@
130 nux::ROProperty<std::string> comment;
131 nux::ROProperty<std::string> dnd_uri;
132
133+protected:
134+ virtual std::string GetURI() const;
135+ virtual std::string GetIconHint() const;
136+ virtual std::size_t GetCategoryIndex() const;
137+ virtual std::string GetMimeType() const;
138+ virtual std::string GetName() const;
139+ virtual std::string GetComment() const;
140+ virtual std::string GetDndURI() const;
141+
142 private:
143 void SetupGetters();
144 };
145
146=== modified file 'dash/ResultRenderer.cpp'
147--- dash/ResultRenderer.cpp 2012-10-22 12:04:55 +0000
148+++ dash/ResultRenderer.cpp 2012-12-06 18:02:23 +0000
149@@ -22,10 +22,99 @@
150
151 #include "ResultRenderer.h"
152
153+#include <gtk/gtk.h>
154+#include <unity-protocol.h>
155+#include <NuxGraphics/GdkGraphics.h>
156+
157 namespace unity
158 {
159 namespace dash
160 {
161+
162+namespace
163+{
164+#define DEFAULT_GICON ". GThemedIcon text-x-preview"
165+
166+GdkPixbuf* _icon_hint_get_drag_pixbuf(std::string icon_hint, int size)
167+{
168+ GdkPixbuf *pbuf;
169+ GtkIconTheme *theme;
170+ GtkIconInfo *info;
171+ GError *error = NULL;
172+ GIcon *icon;
173+ if (icon_hint.empty())
174+ icon_hint = DEFAULT_GICON;
175+ if (g_str_has_prefix(icon_hint.c_str(), "/"))
176+ {
177+ pbuf = gdk_pixbuf_new_from_file_at_scale (icon_hint.c_str(),
178+ size, size, TRUE, &error);
179+ if (error != NULL || !pbuf || !GDK_IS_PIXBUF (pbuf))
180+ {
181+ icon_hint = "application-default-icon";
182+ g_error_free (error);
183+ error = NULL;
184+ }
185+ else
186+ return pbuf;
187+ }
188+ theme = gtk_icon_theme_get_default();
189+ icon = g_icon_new_for_string(icon_hint.c_str(), NULL);
190+
191+ if (G_IS_ICON(icon))
192+ {
193+ if (UNITY_PROTOCOL_IS_ANNOTATED_ICON(icon))
194+ {
195+ UnityProtocolAnnotatedIcon *anno;
196+ anno = UNITY_PROTOCOL_ANNOTATED_ICON(icon);
197+
198+ GIcon *base_icon = unity_protocol_annotated_icon_get_icon(anno);
199+ info = gtk_icon_theme_lookup_by_gicon(theme, base_icon, size, (GtkIconLookupFlags)0);
200+ }
201+ else
202+ {
203+ info = gtk_icon_theme_lookup_by_gicon(theme, icon, size, (GtkIconLookupFlags)0);
204+ }
205+ g_object_unref(icon);
206+ }
207+ else
208+ {
209+ info = gtk_icon_theme_lookup_icon(theme,
210+ icon_hint.c_str(),
211+ size,
212+ (GtkIconLookupFlags) 0);
213+ }
214+
215+ if (!info)
216+ {
217+ info = gtk_icon_theme_lookup_icon(theme,
218+ "application-default-icon",
219+ size,
220+ (GtkIconLookupFlags) 0);
221+ }
222+
223+ if (gtk_icon_info_get_filename(info) == NULL)
224+ {
225+ gtk_icon_info_free(info);
226+ info = gtk_icon_theme_lookup_icon(theme,
227+ "application-default-icon",
228+ size,
229+ (GtkIconLookupFlags) 0);
230+ }
231+
232+ pbuf = gtk_icon_info_load_icon(info, &error);
233+
234+ if (error != NULL)
235+ {
236+ g_error_free (error);
237+ pbuf = NULL;
238+ }
239+
240+ gtk_icon_info_free(info);
241+ return pbuf;
242+}
243+
244+}
245+
246 NUX_IMPLEMENT_OBJECT_TYPE(ResultRenderer);
247
248 ResultRenderer::ResultRenderer(NUX_FILE_LINE_DECL)
249@@ -52,6 +141,12 @@
250 // unload any resources
251 }
252
253+nux::NBitmapData* ResultRenderer::GetDndImage(Result const& row) const
254+{
255+ nux::GdkGraphics graphics(_icon_hint_get_drag_pixbuf(row.icon_hint, 64));
256+ return graphics.GetBitmap();
257+}
258+
259 }
260 }
261
262
263=== modified file 'dash/ResultRenderer.h'
264--- dash/ResultRenderer.h 2012-10-22 12:04:55 +0000
265+++ dash/ResultRenderer.h 2012-12-06 18:02:23 +0000
266@@ -62,6 +62,9 @@
267 // unload any previous grabbed images
268 virtual void Unload(Result& row);
269
270+ // get a image to drag
271+ virtual nux::NBitmapData* GetDndImage(Result const& row) const;
272+
273 nux::Property<int> width;
274 nux::Property<int> height;
275
276
277=== modified file 'dash/ResultRendererHorizontalTile.cpp'
278--- dash/ResultRendererHorizontalTile.cpp 2012-10-22 12:04:55 +0000
279+++ dash/ResultRendererHorizontalTile.cpp 2012-12-06 18:02:23 +0000
280@@ -29,6 +29,7 @@
281
282 #include "unity-shared/CairoTexture.h"
283 #include "unity-shared/TextureCache.h"
284+#include <NuxGraphics/GdkGraphics.h>
285
286
287 namespace unity
288@@ -42,7 +43,7 @@
289 const int CARD_VIEW_HEIGHT = 74; // pixels
290 const int CARD_VIEW_HIGHLIGHT_CORNER_RADIUS = 2; // pixels
291 const int CARD_VIEW_ICON_OUTLINE_WIDTH = 1; // pixels
292-const int CARD_VIEW_TEXT_LINE_SPACING = 0; // points
293+const int CARD_VIEW_TEXT_LINE_SPACING = 0; // points
294 }
295
296 namespace dash
297@@ -297,6 +298,25 @@
298 container->text = texture_ptr_from_cairo_graphics(_cairoGraphics);
299 }
300
301+nux::NBitmapData* ResultRendererHorizontalTile::GetDndImage(Result const& row) const
302+{
303+ TextureContainer* container = row.renderer<TextureContainer*>();
304+ nux::NBitmapData* bitmap = nullptr;
305+
306+ if (container && container->drag_icon && container->drag_icon.IsType(GDK_TYPE_PIXBUF))
307+ {
308+ int width = gdk_pixbuf_get_width(container->drag_icon);
309+ int height = gdk_pixbuf_get_height(container->drag_icon);
310+
311+ if (width != CARD_VIEW_ICON_SIZE || height != CARD_VIEW_ICON_SIZE)
312+ {
313+ nux::GdkGraphics graphics(gdk_pixbuf_scale_simple(container->drag_icon, CARD_VIEW_ICON_SIZE, CARD_VIEW_ICON_SIZE, GDK_INTERP_BILINEAR));
314+ bitmap = graphics.GetBitmap();
315+ }
316+ }
317+ return bitmap ? bitmap : ResultRendererTile::GetDndImage(row);
318+}
319+
320
321 }
322 }
323
324=== modified file 'dash/ResultRendererHorizontalTile.h'
325--- dash/ResultRendererHorizontalTile.h 2012-10-22 12:04:55 +0000
326+++ dash/ResultRendererHorizontalTile.h 2012-12-06 18:02:23 +0000
327@@ -46,6 +46,8 @@
328 nux::Geometry const& geometry,
329 int x_offset, int y_offset);
330
331+ virtual nux::NBitmapData* GetDndImage(Result const& row) const;
332+
333 protected:
334 virtual void LoadText(Result& row);
335
336
337=== modified file 'dash/ResultRendererTile.cpp'
338--- dash/ResultRendererTile.cpp 2012-10-30 18:18:35 +0000
339+++ dash/ResultRendererTile.cpp 2012-12-06 18:02:23 +0000
340@@ -23,10 +23,10 @@
341 #include "ResultRendererTile.h"
342
343 #include <pango/pangocairo.h>
344-#include <gtk/gtk.h>
345
346 #include <NuxCore/Logger.h>
347 #include <UnityCore/GLibWrapper.h>
348+#include <NuxGraphics/GdkGraphics.h>
349
350 #include "unity-shared/CairoTexture.h"
351 #include "unity-shared/DashStyle.h"
352@@ -34,7 +34,8 @@
353
354 namespace
355 {
356- bool neko;
357+bool neko;
358+#define DEFAULT_GICON ". GThemedIcon text-x-preview"
359 }
360
361 namespace unity
362@@ -180,11 +181,24 @@
363 row.set_renderer<TextureContainer*>(nullptr);
364 }
365
366+nux::NBitmapData* ResultRendererTile::GetDndImage(Result const& row) const
367+{
368+ TextureContainer* container = row.renderer<TextureContainer*>();
369+ nux::NBitmapData* bitmap = nullptr;
370+
371+ if (container && container->drag_icon && container->drag_icon.IsType(GDK_TYPE_PIXBUF))
372+ {
373+ // Need to ref the drag icon because GdkGraphics will unref it.
374+ nux::GdkGraphics graphics(GDK_PIXBUF(g_object_ref(container->drag_icon)));
375+ bitmap = graphics.GetBitmap();
376+ }
377+ return bitmap ? bitmap : ResultRenderer::GetDndImage(row);
378+}
379+
380 void ResultRendererTile::LoadIcon(Result& row)
381 {
382 Style& style = Style::Instance();
383 std::string icon_hint(row.icon_hint);
384-#define DEFAULT_GICON ". GThemedIcon text-x-preview"
385 std::string icon_name;
386 if (G_UNLIKELY(neko))
387 {
388@@ -289,10 +303,8 @@
389
390 return texture_from_cairo_graphics(cairo_graphics);
391 }
392-
393 }
394
395-
396 void ResultRendererTile::IconLoaded(std::string const& texid,
397 int max_width,
398 int max_height,
399@@ -314,6 +326,7 @@
400
401 container->icon = texture;
402 container->prelight = texture_prelight;
403+ container->drag_icon = pixbuf;
404
405 NeedsRedraw.emit();
406
407
408=== modified file 'dash/ResultRendererTile.h'
409--- dash/ResultRendererTile.h 2012-10-24 15:01:10 +0000
410+++ dash/ResultRendererTile.h 2012-12-06 18:02:23 +0000
411@@ -38,6 +38,8 @@
412 BaseTexturePtr text;
413 BaseTexturePtr icon;
414 BaseTexturePtr prelight;
415+ glib::Object<GdkPixbuf> drag_icon;
416+
417 int slot_handle;
418
419 TextureContainer()
420@@ -67,6 +69,8 @@
421
422 virtual void Preload(Result& row);
423 virtual void Unload(Result& row);
424+
425+ virtual nux::NBitmapData* GetDndImage(Result const& row) const;
426
427 int spacing;
428 int padding;
429
430=== modified file 'dash/ResultViewGrid.cpp'
431--- dash/ResultViewGrid.cpp 2012-12-04 17:23:39 +0000
432+++ dash/ResultViewGrid.cpp 2012-12-06 18:02:23 +0000
433@@ -56,6 +56,7 @@
434 , last_lazy_loaded_result_(0)
435 , last_mouse_down_x_(-1)
436 , last_mouse_down_y_(-1)
437+ , drag_index_(~0)
438 , recorded_dash_width_(-1)
439 , recorded_dash_height_(-1)
440 , mouse_last_x_(-1)
441@@ -778,27 +779,23 @@
442 bool ResultViewGrid::DndSourceDragBegin()
443 {
444 #ifdef USE_X11
445- unsigned num_results = GetNumResults();
446- unsigned drag_index = GetIndexAtPosition(last_mouse_down_x_, last_mouse_down_y_);
447+ drag_index_ = GetIndexAtPosition(last_mouse_down_x_, last_mouse_down_y_);
448
449- if (drag_index >= num_results)
450+ if (drag_index_ >= GetNumResults())
451 return false;
452
453 Reference();
454
455- ResultIterator iter(GetIteratorAtRow(drag_index));
456+ ResultIterator iter(GetIteratorAtRow(drag_index_));
457 Result drag_result = *iter;
458
459 current_drag_uri_ = drag_result.dnd_uri;
460 if (current_drag_uri_ == "")
461 current_drag_uri_ = drag_result.uri().substr(drag_result.uri().find(":") + 1);
462
463- current_drag_icon_name_ = drag_result.icon_hint;
464-
465 LOG_DEBUG (logger) << "Dnd begin at " <<
466 last_mouse_down_x_ << ", " << last_mouse_down_y_ << " - using; "
467- << current_drag_uri_ << " - "
468- << current_drag_icon_name_;
469+ << current_drag_uri_;
470
471 return true;
472 #else
473@@ -806,101 +803,14 @@
474 #endif
475 }
476
477-GdkPixbuf* _icon_hint_get_drag_pixbuf(std::string icon_hint)
478-{
479- GdkPixbuf *pbuf;
480- GtkIconTheme *theme;
481- GtkIconInfo *info;
482- GError *error = NULL;
483- GIcon *icon;
484- int size = 64;
485- if (icon_hint.empty())
486- icon_hint = "application-default-icon";
487- if (g_str_has_prefix(icon_hint.c_str(), "/"))
488- {
489- pbuf = gdk_pixbuf_new_from_file_at_scale (icon_hint.c_str(),
490- size, size, FALSE, &error);
491- if (error != NULL || !pbuf || !GDK_IS_PIXBUF (pbuf))
492- {
493- icon_hint = "application-default-icon";
494- g_error_free (error);
495- error = NULL;
496- }
497- else
498- return pbuf;
499- }
500- theme = gtk_icon_theme_get_default();
501- icon = g_icon_new_for_string(icon_hint.c_str(), NULL);
502-
503- if (G_IS_ICON(icon))
504- {
505- if (UNITY_PROTOCOL_IS_ANNOTATED_ICON(icon))
506- {
507- UnityProtocolAnnotatedIcon *anno;
508- anno = UNITY_PROTOCOL_ANNOTATED_ICON(icon);
509-
510- GIcon *base_icon = unity_protocol_annotated_icon_get_icon(anno);
511- info = gtk_icon_theme_lookup_by_gicon(theme, base_icon, size, (GtkIconLookupFlags)0);
512- }
513- else
514- {
515- info = gtk_icon_theme_lookup_by_gicon(theme, icon, size, (GtkIconLookupFlags)0);
516- }
517- g_object_unref(icon);
518- }
519- else
520- {
521- info = gtk_icon_theme_lookup_icon(theme,
522- icon_hint.c_str(),
523- size,
524- (GtkIconLookupFlags) 0);
525- }
526-
527- if (!info)
528- {
529- info = gtk_icon_theme_lookup_icon(theme,
530- "application-default-icon",
531- size,
532- (GtkIconLookupFlags) 0);
533- }
534-
535- if (gtk_icon_info_get_filename(info) == NULL)
536- {
537- gtk_icon_info_free(info);
538- info = gtk_icon_theme_lookup_icon(theme,
539- "application-default-icon",
540- size,
541- (GtkIconLookupFlags) 0);
542- }
543-
544- pbuf = gtk_icon_info_load_icon(info, &error);
545-
546- if (error != NULL)
547- {
548- LOG_WARN (logger) << "could not find a pixbuf for " << icon_hint;
549- g_error_free (error);
550- pbuf = NULL;
551- }
552-
553- gtk_icon_info_free(info);
554- return pbuf;
555-}
556-
557 nux::NBitmapData*
558 ResultViewGrid::DndSourceGetDragImage()
559 {
560- nux::NBitmapData* result = 0;
561- GdkPixbuf* pbuf;
562- pbuf = _icon_hint_get_drag_pixbuf (current_drag_icon_name_);
563-
564- if (pbuf && GDK_IS_PIXBUF(pbuf))
565- {
566- // we don't free the pbuf as GdkGraphics will do it for us will do it for us
567- nux::GdkGraphics graphics(pbuf);
568- result = graphics.GetBitmap();
569- }
570-
571- return result;
572+ if (drag_index_ >= GetNumResults())
573+ return nullptr;
574+
575+ Result result(*GetIteratorAtRow(drag_index_));
576+ return renderer_->GetDndImage(result);
577 }
578
579 std::list<const char*>
580@@ -934,7 +844,7 @@
581 last_mouse_down_x_ = -1;
582 last_mouse_down_y_ = -1;
583 current_drag_uri_.clear();
584- current_drag_icon_name_.clear();
585+ drag_index_ = ~0;
586
587 // We need this because the drag can start in a ResultViewGrid and can
588 // end in another ResultViewGrid
589
590=== modified file 'dash/ResultViewGrid.h'
591--- dash/ResultViewGrid.h 2012-11-19 18:54:19 +0000
592+++ dash/ResultViewGrid.h 2012-12-06 18:02:23 +0000
593@@ -106,7 +106,7 @@
594 int last_mouse_down_x_;
595 int last_mouse_down_y_;
596 std::string current_drag_uri_;
597- std::string current_drag_icon_name_;
598+ unsigned drag_index_;
599
600 int recorded_dash_width_;
601 int recorded_dash_height_;
602
603=== modified file 'tests/CMakeLists.txt'
604--- tests/CMakeLists.txt 2012-12-05 09:10:04 +0000
605+++ tests/CMakeLists.txt 2012-12-06 18:02:23 +0000
606@@ -230,6 +230,7 @@
607 test_overlay_scrollbar.cpp
608 test_quicklist_menu_item.cpp
609 test_quicklist_view.cpp
610+ test_result_renderer.cpp
611 test_resultviewgrid.cpp
612 test_shortcut_controller.cpp
613 test_single_monitor_launcher_icon.cpp
614
615=== added file 'tests/test_result_renderer.cpp'
616--- tests/test_result_renderer.cpp 1970-01-01 00:00:00 +0000
617+++ tests/test_result_renderer.cpp 2012-12-06 18:02:23 +0000
618@@ -0,0 +1,124 @@
619+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
620+/*
621+ * Copyright 2012 Canonical Ltd.
622+ *
623+ * This program is free software: you can redistribute it and/or modify it
624+ * under the terms of the GNU Lesser General Public License version 3, as
625+ * published by the Free Software Foundation.
626+ *
627+ * This program is distributed in the hope that it will be useful, but
628+ * WITHOUT ANY WARRANTY; without even the implied warranties of
629+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
630+ * PURPOSE. See the applicable version of the GNU Lesser General Public
631+ * License for more details.
632+ *
633+ * You should have received a copy of both the GNU Lesser General Public
634+ * License version 3 along with this program. If not, see
635+ * <http://www.gnu.org/licenses/>
636+ *
637+ * Authored by: Nick Dedekind <nick.dedekind@canonical.com>
638+ *
639+ */
640+#include <gmock/gmock.h>
641+#include <glib-object.h>
642+
643+#include "unity-shared/DashStyle.h"
644+#include "unity-shared/UnitySettings.h"
645+#include "UnityCore/Result.h"
646+#include "dash/ResultRendererTile.h"
647+
648+#include "test_utils.h"
649+
650+using namespace std;
651+using namespace unity;
652+using namespace testing;
653+
654+namespace unity
655+{
656+
657+namespace
658+{
659+
660+#define DEFAULT_GICON ". GThemedIcon text-x-preview"
661+
662+GdkPixbuf* GetIconData(std::string icon_hint, int size)
663+{
664+ GdkPixbuf *pbuf;
665+ GtkIconTheme *theme;
666+ GError *error = NULL;
667+
668+ theme = gtk_icon_theme_get_default();
669+ glib::Object<GIcon> icon(g_icon_new_for_string(icon_hint.c_str(), NULL));
670+
671+ if (icon.IsType(G_TYPE_ICON))
672+ {
673+ GtkIconInfo *info = gtk_icon_theme_lookup_by_gicon(theme, icon, size, (GtkIconLookupFlags)0);
674+ pbuf = gtk_icon_info_load_icon(info, &error);
675+ if (error != NULL)
676+ {
677+ g_error_free (error);
678+ pbuf = NULL;
679+ }
680+ gtk_icon_info_free(info);
681+ }
682+
683+ return pbuf;
684+}
685+
686+} // namespace [anonymous]
687+
688+class TestResultRenderer : public testing::Test
689+{
690+public:
691+ TestResultRenderer() {}
692+
693+ unity::Settings settings;
694+ dash::Style style;
695+};
696+
697+class MockResult : public dash::Result
698+{
699+public:
700+ MockResult()
701+ : Result(NULL, NULL, NULL)
702+ , renderer_(new dash::TextureContainer())
703+ {
704+ ON_CALL (*this, GetURI ()).WillByDefault (Return ("file:///result_render_test"));
705+ ON_CALL (*this, GetIconHint()).WillByDefault (Return (DEFAULT_GICON));
706+ ON_CALL (*this, GetCategoryIndex ()).WillByDefault (Return (0));
707+ ON_CALL (*this, GetName ()).WillByDefault (Return ("Result Render Test"));
708+ ON_CALL (*this, GetDndURI ()).WillByDefault (Return ("file:///result_render_test_dnd"));
709+ }
710+
711+ MOCK_CONST_METHOD0(GetURI, std::string());
712+ MOCK_CONST_METHOD0(GetIconHint, std::string());
713+ MOCK_CONST_METHOD0(GetCategoryIndex, std::size_t());
714+ MOCK_CONST_METHOD0(GetMimeType, std::string());
715+ MOCK_CONST_METHOD0(GetName, std::string());
716+ MOCK_CONST_METHOD0(GetComment, std::string());
717+ MOCK_CONST_METHOD0(GetDndURI, std::string());
718+
719+ virtual gpointer get_model_tag() const
720+ {
721+ return renderer_.get();
722+ }
723+
724+private:
725+ std::auto_ptr<dash::TextureContainer> renderer_;
726+};
727+
728+TEST_F(TestResultRenderer, TestConstruction)
729+{
730+ dash::ResultRendererTile renderer;
731+}
732+
733+TEST_F(TestResultRenderer, TestDndIcon)
734+{
735+ dash::ResultRendererTile renderer;
736+ NiceMock<MockResult> result;
737+
738+ nux::NBitmapData* bitmap = renderer.GetDndImage(result);
739+ ASSERT_NE(bitmap, nullptr);
740+}
741+
742+}