Merge lp:~3v1n0/unity/icon-dragging-cancellation into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Marco Trevisan (Treviño)
Approved revision: no longer in the source branch.
Merged at revision: 2651
Proposed branch: lp:~3v1n0/unity/icon-dragging-cancellation
Merge into: lp:unity
Diff against target: 700 lines (+372/-46)
11 files modified
launcher/Launcher.cpp (+47/-24)
launcher/Launcher.h (+3/-1)
launcher/LauncherDragWindow.cpp (+30/-3)
launcher/LauncherDragWindow.h (+8/-2)
launcher/LauncherModel.cpp (+35/-0)
launcher/LauncherModel.h (+2/-0)
launcher/MockLauncherIcon.h (+8/-2)
tests/CMakeLists.txt (+1/-0)
tests/test_launcher.cpp (+124/-14)
tests/test_launcher_drag_window.cpp (+70/-0)
tests/test_launcher_model.cpp (+44/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/icon-dragging-cancellation
Reviewer Review Type Date Requested Status
Brandon Schaefer (community) Approve
Review via email: mp+122328@code.launchpad.net

Commit message

LauncherDragWindow: emit cancelled signal when the Escape key has been pressed during drag

Launcher: restore an icon position after that the dragging has been cancelled

Description of the change

Added drag-n-drop cancellation for the launcher icons: now a LauncherDragWindow grabs the keyboard and emits a signal when the escape key is pressed; at this point the launcher set the dragged icon to its original position. This is done by saving this position when the dragging has begun (thanks to a new utility function I added to the model).

Unit tests added and improved.

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

Looks good and works.

review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

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

...

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/Launcher.cpp'
2--- launcher/Launcher.cpp 2012-08-31 09:05:57 +0000
3+++ launcher/Launcher.cpp 2012-08-31 20:16:18 +0000
4@@ -1102,7 +1102,6 @@
5 {
6 RenderArg arg;
7 AbstractLauncherIcon::Ptr icon = *it;
8-
9 FillRenderArg(icon, arg, center, parent_abs_geo, folding_threshold, folded_size, folded_spacing,
10 autohide_offset, folded_z_distance, animation_neg_rads, current);
11 arg.colorify = colorify;
12@@ -1773,9 +1772,8 @@
13 if (_drag_icon && _render_drag_window)
14 {
15 RenderIconToTexture(GfxContext, _drag_icon, _offscreen_drag_texture);
16- _drag_window->ShowWindow(true);
17-
18 _render_drag_window = false;
19+ ShowDragWindow();
20 }
21
22 // clear region
23@@ -1970,9 +1968,7 @@
24
25 void Launcher::OnDragWindowAnimCompleted()
26 {
27- if (_drag_window)
28- _drag_window->ShowWindow(false);
29-
30+ HideDragWindow();
31 EnsureAnimation();
32 }
33
34@@ -2018,12 +2014,8 @@
35 }
36 else
37 {
38- _drag_icon = NULL;
39- if (_drag_window)
40- {
41- _drag_window->ShowWindow(false);
42- _drag_window = nullptr;
43- }
44+ _drag_icon = nullptr;
45+ HideDragWindow();
46 }
47 }
48
49@@ -2035,11 +2027,7 @@
50 _hide_machine.SetQuirk(LauncherHideMachine::INTERNAL_DND_ACTIVE, true);
51 _drag_icon = icon;
52
53- if (_drag_window)
54- {
55- _drag_window->ShowWindow(false);
56- }
57-
58+ HideDragWindow();
59 _offscreen_drag_texture = nux::GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableDeviceTexture(_icon_size, _icon_size, 1, nux::BITFMT_R8G8B8A8);
60 _drag_window = new LauncherDragWindow(_offscreen_drag_texture);
61
62@@ -2052,7 +2040,10 @@
63 {
64 if (_drag_window)
65 {
66- AbstractLauncherIcon::Ptr hovered_icon = MouseIconIntersection(_mouse_position.x, _mouse_position.y);
67+ AbstractLauncherIcon::Ptr hovered_icon;
68+
69+ if (!_drag_window->Cancelled())
70+ hovered_icon = MouseIconIntersection(_mouse_position.x, _mouse_position.y);
71
72 if (hovered_icon && hovered_icon->GetIconType() == AbstractLauncherIcon::IconType::TRASH)
73 {
74@@ -2060,20 +2051,21 @@
75
76 launcher_removerequest.emit(_drag_icon);
77
78- _drag_window->ShowWindow(false);
79+ HideDragWindow();
80 EnsureAnimation();
81 }
82 else
83 {
84- _model->Save();
85-
86- _drag_window->SetAnimationTarget((int)(_drag_icon->GetCenter(monitor).x),
87- (int)(_drag_icon->GetCenter(monitor).y));
88- _drag_window->StartAnimation();
89+ if (!_drag_window->Cancelled())
90+ _model->Save();
91
92 if (_drag_window->on_anim_completed.connected())
93 _drag_window->on_anim_completed.disconnect();
94 _drag_window->on_anim_completed = _drag_window->anim_completed.connect(sigc::mem_fun(this, &Launcher::OnDragWindowAnimCompleted));
95+
96+ auto const& icon_center = _drag_icon->GetCenter(monitor);
97+ _drag_window->SetAnimationTarget(icon_center.x, icon_center.y),
98+ _drag_window->StartAnimation();
99 }
100 }
101
102@@ -2086,6 +2078,37 @@
103 ubus_.SendMessage(UBUS_LAUNCHER_ICON_END_DND);
104 }
105
106+void Launcher::ShowDragWindow()
107+{
108+ if (!_drag_window || _drag_window->IsVisible())
109+ return;
110+
111+ _drag_window->GrabKeyboard();
112+ _drag_window->ShowWindow(true);
113+ _drag_window->PushToFront();
114+
115+ bool is_before;
116+ AbstractLauncherIcon::Ptr const& closer = _model->GetClosestIcon(_drag_icon, is_before);
117+ _drag_window->drag_cancel_request.connect([this, closer, is_before] {
118+ if (is_before)
119+ _model->ReorderAfter(_drag_icon, closer);
120+ else
121+ _model->ReorderBefore(_drag_icon, closer, true);
122+
123+ ResetMouseDragState();
124+ });
125+}
126+
127+void Launcher::HideDragWindow()
128+{
129+ if (!_drag_window)
130+ return;
131+
132+ _drag_window->UnGrabKeyboard();
133+ _drag_window->ShowWindow(false);
134+ _drag_window = nullptr;
135+}
136+
137 void Launcher::UpdateDragWindowPosition(int x, int y)
138 {
139 if (!_drag_window)
140
141=== modified file 'launcher/Launcher.h'
142--- launcher/Launcher.h 2012-08-25 15:54:29 +0000
143+++ launcher/Launcher.h 2012-08-31 20:16:18 +0000
144@@ -294,7 +294,7 @@
145
146 void OnActionDone(GVariant* data);
147
148- AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y);
149+ virtual AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y);
150 void EventLogic();
151 void MouseDownLogic(int x, int y, unsigned long button_flags, unsigned long key_flags);
152 void MouseUpLogic(int x, int y, unsigned long button_flags, unsigned long key_flags);
153@@ -302,7 +302,9 @@
154 void StartIconDragRequest(int x, int y);
155 void StartIconDrag(AbstractLauncherIcon::Ptr icon);
156 void EndIconDrag();
157+ void ShowDragWindow();
158 void UpdateDragWindowPosition(int x, int y);
159+ void HideDragWindow();
160
161 void ResetMouseDragState();
162
163
164=== modified file 'launcher/LauncherDragWindow.cpp'
165--- launcher/LauncherDragWindow.cpp 2012-06-18 02:57:23 +0000
166+++ launcher/LauncherDragWindow.cpp 2012-08-31 20:16:18 +0000
167@@ -1,6 +1,6 @@
168 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
169 /*
170-* Copyright (C) 2010 Canonical Ltd
171+* Copyright (C) 2010-2012 Canonical Ltd
172 *
173 * This program is free software: you can redistribute it and/or modify
174 * it under the terms of the GNU General Public License version 3 as
175@@ -15,6 +15,7 @@
176 * along with this program. If not, see <http://www.gnu.org/licenses/>.
177 *
178 * Authored by: Jason Smith <jason.smith@canonical.com>
179+* Marco Trevisan <marco.trevisan@canonical.com>
180 */
181
182 #include <Nux/Nux.h>
183@@ -33,22 +34,38 @@
184
185 LauncherDragWindow::LauncherDragWindow(nux::ObjectPtr<nux::IOpenGLBaseTexture> icon)
186 : nux::BaseWindow("")
187+ , _cancelled(false)
188 , _icon(icon)
189 {
190 SetBaseSize(_icon->GetWidth(), _icon->GetHeight());
191+
192+ key_down.connect([this] (unsigned long, unsigned long keysym, unsigned long, const char*, unsigned short) {
193+ if (keysym == NUX_VK_ESCAPE)
194+ {
195+ _cancelled = true;
196+ drag_cancel_request.emit();
197+ }
198+ });
199 }
200
201 LauncherDragWindow::~LauncherDragWindow()
202 {
203 if (on_anim_completed.connected())
204 on_anim_completed.disconnect();
205+
206+ UnGrabKeyboard();
207 }
208
209-bool LauncherDragWindow::Animating()
210+bool LauncherDragWindow::Animating() const
211 {
212 return bool(animation_timer_);
213 }
214
215+bool LauncherDragWindow::Cancelled() const
216+{
217+ return _cancelled;
218+}
219+
220 void LauncherDragWindow::SetAnimationTarget(int x, int y)
221 {
222 _animation_target = nux::Point2(x, y);
223@@ -86,8 +103,8 @@
224
225 if (new_geo.x == target_x && new_geo.y == target_y)
226 {
227+ animation_timer_.reset();
228 anim_completed.emit();
229- animation_timer_.reset();
230
231 return false;
232 }
233@@ -118,5 +135,15 @@
234 GfxContext.PopClippingRectangle();
235 }
236
237+bool LauncherDragWindow::InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char* character)
238+{
239+ return (event_type == nux::NUX_KEYDOWN);
240+}
241+
242+bool LauncherDragWindow::AcceptKeyNavFocus()
243+{
244+ return true;
245+}
246+
247 } // namespace launcher
248 } // namespace unity
249
250=== modified file 'launcher/LauncherDragWindow.h'
251--- launcher/LauncherDragWindow.h 2012-06-18 02:57:23 +0000
252+++ launcher/LauncherDragWindow.h 2012-08-31 20:16:18 +0000
253@@ -37,7 +37,6 @@
254 NUX_DECLARE_OBJECT_TYPE(LauncherDragWindow, nux::BaseWindow);
255 public:
256 LauncherDragWindow(nux::ObjectPtr<nux::IOpenGLBaseTexture> icon);
257-
258 ~LauncherDragWindow();
259
260 void DrawContent(nux::GraphicsEngine& gfxContext, bool forceDraw);
261@@ -45,14 +44,21 @@
262 void SetAnimationTarget(int x, int y);
263 void StartAnimation();
264
265- bool Animating();
266+ bool Animating() const;
267+ bool Cancelled() const;
268
269 sigc::signal<void> anim_completed;
270+ sigc::signal<void> drag_cancel_request;
271 sigc::connection on_anim_completed;
272
273+protected:
274+ bool InspectKeyEvent(unsigned int event_type, unsigned int keysym, const char* character);
275+ bool AcceptKeyNavFocus();
276+
277 private:
278 bool OnAnimationTimeout();
279
280+ bool _cancelled;
281 nux::ObjectPtr<nux::IOpenGLBaseTexture> _icon;
282 nux::Point2 _animation_target;
283 glib::Source::UniquePtr animation_timer_;
284
285=== modified file 'launcher/LauncherModel.cpp'
286--- launcher/LauncherModel.cpp 2012-08-10 09:58:49 +0000
287+++ launcher/LauncherModel.cpp 2012-08-31 20:16:18 +0000
288@@ -387,6 +387,41 @@
289 }
290 }
291
292+AbstractLauncherIcon::Ptr LauncherModel::GetClosestIcon(AbstractLauncherIcon::Ptr icon, bool& is_before) const
293+{
294+ AbstractLauncherIcon::Ptr prev, next;
295+ bool found_target = false;
296+
297+ for (auto const& current : _inner)
298+ {
299+ if (current->GetIconType() != icon->GetIconType())
300+ continue;
301+
302+ if (!found_target)
303+ {
304+ if (current == icon)
305+ {
306+ found_target = true;
307+
308+ if (prev)
309+ break;
310+ }
311+ else
312+ {
313+ prev = current;
314+ }
315+ }
316+ else
317+ {
318+ next = current;
319+ break;
320+ }
321+ }
322+
323+ is_before = next.IsNull();
324+
325+ return is_before ? prev : next;
326+}
327
328 /* iterators */
329
330
331=== modified file 'launcher/LauncherModel.h'
332--- launcher/LauncherModel.h 2012-07-04 02:37:23 +0000
333+++ launcher/LauncherModel.h 2012-08-31 20:16:18 +0000
334@@ -62,6 +62,8 @@
335 void SelectNext();
336 void SelectPrevious();
337
338+ AbstractLauncherIcon::Ptr GetClosestIcon(AbstractLauncherIcon::Ptr icon, bool& is_before) const;
339+
340 iterator begin();
341 iterator end();
342 iterator at(int index);
343
344=== modified file 'launcher/MockLauncherIcon.h'
345--- launcher/MockLauncherIcon.h 2012-08-15 02:51:33 +0000
346+++ launcher/MockLauncherIcon.h 2012-08-31 20:16:18 +0000
347@@ -130,11 +130,16 @@
348 return false;
349 }
350
351- void SetCenter(nux::Point3 center, int monitor, nux::Geometry geo) {}
352+ void SetCenter(nux::Point3 center, int monitor, nux::Geometry geo)
353+ {
354+ center.x += geo.x;
355+ center.y += geo.y;
356+ center_[monitor] = center;
357+ }
358
359 nux::Point3 GetCenter(int monitor)
360 {
361- return nux::Point3();
362+ return center_[monitor];
363 }
364
365 nux::Point3 GetSavedCenter(int monitor)
366@@ -346,6 +351,7 @@
367 IconType type_;
368 bool quirks_[unsigned(Quirk::LAST)];
369 timespec quirk_times_[unsigned(Quirk::LAST)];
370+ std::map<int, nux::Point3> center_;
371 };
372
373 }
374
375=== modified file 'tests/CMakeLists.txt'
376--- tests/CMakeLists.txt 2012-08-31 09:15:33 +0000
377+++ tests/CMakeLists.txt 2012-08-31 20:16:18 +0000
378@@ -213,6 +213,7 @@
379 test_icon_loader.cpp
380 test_im_text_entry.cpp
381 test_launcher_controller.cpp
382+ test_launcher_drag_window.cpp
383 test_keyboard_util.cpp
384 test_panel_style.cpp
385 test_previews_application.cpp
386
387=== modified file 'tests/test_launcher.cpp'
388--- tests/test_launcher.cpp 2012-08-21 17:45:42 +0000
389+++ tests/test_launcher.cpp 2012-08-31 20:16:18 +0000
390@@ -15,10 +15,12 @@
391 * along with this program. If not, see <http://www.gnu.org/licenses/>.
392 *
393 * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
394+ * Marco Trevisan <marco.trevisan@canonical.com>
395 */
396
397 #include <list>
398 #include <gmock/gmock.h>
399+#include "test_uscreen_mock.h"
400 using namespace testing;
401
402 #include <Nux/Nux.h>
403@@ -29,6 +31,7 @@
404 #include "launcher/Launcher.h"
405 #include "unity-shared/PanelStyle.h"
406 #include "unity-shared/UnitySettings.h"
407+#include "unity-shared/IconRenderer.h"
408 #include "test_utils.h"
409 using namespace unity;
410
411@@ -54,29 +57,76 @@
412 class TestLauncher : public Test
413 {
414 public:
415+ class MockLauncher : public launcher::Launcher
416+ {
417+ public:
418+ MockLauncher(nux::BaseWindow* parent, nux::ObjectPtr<DNDCollectionWindow> const& collection_window)
419+ : Launcher(parent, collection_window)
420+ {}
421+
422+ AbstractLauncherIcon::Ptr MouseIconIntersection(int x, int y)
423+ {
424+ for (auto const& icon : *_model)
425+ {
426+ auto const& center = icon->GetCenter(monitor());
427+
428+ if (y > center.y - GetIconSize()/2.0f && y < center.y + GetIconSize()/2.0f)
429+ return icon;
430+ }
431+
432+ return AbstractLauncherIcon::Ptr();
433+ }
434+
435+ float IconBackgroundIntensity(AbstractLauncherIcon::Ptr icon, timespec const& current) const
436+ {
437+ return Launcher::IconBackgroundIntensity(icon, current);
438+ }
439+
440+ void StartIconDrag(AbstractLauncherIcon::Ptr icon)
441+ {
442+ Launcher::StartIconDrag(icon);
443+ }
444+
445+ void ShowDragWindow()
446+ {
447+ Launcher::ShowDragWindow();
448+ }
449+
450+ void UpdateDragWindowPosition(int x, int y)
451+ {
452+ Launcher::UpdateDragWindowPosition(x, y);
453+ }
454+
455+ void HideDragWindow()
456+ {
457+ Launcher::HideDragWindow();
458+ }
459+
460+ void ResetMouseDragState()
461+ {
462+ Launcher::ResetMouseDragState();
463+ }
464+ };
465+
466 TestLauncher()
467 : parent_window_(new nux::BaseWindow("TestLauncherWindow"))
468 , dnd_collection_window_(new DNDCollectionWindow)
469 , model_(new LauncherModel)
470 , options_(new Options)
471- , launcher_(new Launcher(parent_window_, dnd_collection_window_))
472+ , launcher_(new MockLauncher(parent_window_, dnd_collection_window_))
473 {
474 launcher_->options = options_;
475 launcher_->SetModel(model_);
476 }
477
478- float IconBackgroundIntensity(AbstractLauncherIcon::Ptr icon, timespec const& current) const
479- {
480- return launcher_->IconBackgroundIntensity(icon, current);
481- }
482-
483+ MockUScreen uscreen;
484 nux::BaseWindow* parent_window_;
485 nux::ObjectPtr<DNDCollectionWindow> dnd_collection_window_;
486 Settings settings;
487 panel::Style panel_style;
488 LauncherModel::Ptr model_;
489 Options::Ptr options_;
490- nux::ObjectPtr<Launcher> launcher_;
491+ nux::ObjectPtr<MockLauncher> launcher_;
492 };
493
494 TEST_F(TestLauncher, TestQuirksDuringDnd)
495@@ -149,10 +199,70 @@
496 timespec current;
497 clock_gettime(CLOCK_MONOTONIC, &current);
498
499- EXPECT_THAT(IconBackgroundIntensity(first, current), Gt(0.0f));
500- EXPECT_THAT(IconBackgroundIntensity(second, current), Gt(0.0f));
501- EXPECT_EQ(IconBackgroundIntensity(third, current), 0.0f);
502-}
503-
504-}
505-}
506+ EXPECT_THAT(launcher_->IconBackgroundIntensity(first, current), Gt(0.0f));
507+ EXPECT_THAT(launcher_->IconBackgroundIntensity(second, current), Gt(0.0f));
508+ EXPECT_EQ(launcher_->IconBackgroundIntensity(third, current), 0.0f);
509+}
510+
511+TEST_F(TestLauncher, CancellingDragLauncherIcon)
512+{
513+ MockMockLauncherIcon::Ptr icon1(new MockMockLauncherIcon);
514+ MockMockLauncherIcon::Ptr icon2(new MockMockLauncherIcon);
515+ MockMockLauncherIcon::Ptr icon3(new MockMockLauncherIcon);
516+
517+ icon1->SetSortPriority(0);
518+ icon2->SetSortPriority(1);
519+ icon3->SetSortPriority(2);
520+
521+ model_->AddIcon(icon1);
522+ model_->AddIcon(icon2);
523+ model_->AddIcon(icon3);
524+
525+ // Set the icon centers
526+ int icon_size = launcher_->GetIconSize();
527+ icon1->SetCenter(nux::Point3(icon_size/2.0f, icon_size/2.0f * 1 + 1, 0), launcher_->monitor(), launcher_->GetGeometry());
528+ icon2->SetCenter(nux::Point3(icon_size/2.0f, icon_size/2.0f * 2 + 1, 0), launcher_->monitor(), launcher_->GetGeometry());
529+ icon3->SetCenter(nux::Point3(icon_size/2.0f, icon_size/2.0f * 3 + 1, 0), launcher_->monitor(), launcher_->GetGeometry());
530+
531+ // Start dragging icon2
532+ launcher_->StartIconDrag(icon2);
533+ launcher_->ShowDragWindow();
534+
535+ // Moving icon2 at the end
536+ auto const& center3 = icon3->GetCenter(launcher_->monitor());
537+ launcher_->UpdateDragWindowPosition(center3.x, center3.y);
538+
539+ auto it = model_->begin();
540+ ASSERT_EQ(*it, icon1); it++;
541+ ASSERT_EQ(*it, icon3); it++;
542+ ASSERT_EQ(*it, icon2);
543+
544+ // Moving icon2 at the begin
545+ auto const& center1 = icon1->GetCenter(launcher_->monitor());
546+ launcher_->UpdateDragWindowPosition(center1.x, center1.y);
547+
548+ it = model_->begin();
549+ ASSERT_EQ(*it, icon2); it++;
550+ ASSERT_EQ(*it, icon1); it++;
551+ ASSERT_EQ(*it, icon3);
552+
553+ bool model_saved = false;
554+ model_->saved.connect([&model_saved] { model_saved = true; });
555+
556+ // Emitting the drag cancel request
557+ launcher_->GetDraggedIcon()->drag_cancel_request.emit();
558+
559+ // The icon order should be reset
560+ it = model_->begin();
561+ ASSERT_EQ(*it, icon1); it++;
562+ ASSERT_EQ(*it, icon2); it++;
563+ ASSERT_EQ(*it, icon3);
564+
565+ EXPECT_FALSE(model_saved);
566+
567+ launcher_->HideDragWindow();
568+}
569+
570+}
571+}
572+
573
574=== added file 'tests/test_launcher_drag_window.cpp'
575--- tests/test_launcher_drag_window.cpp 1970-01-01 00:00:00 +0000
576+++ tests/test_launcher_drag_window.cpp 2012-08-31 20:16:18 +0000
577@@ -0,0 +1,70 @@
578+/*
579+ * Copyright 2012 Canonical Ltd.
580+ *
581+ * This program is free software: you can redistribute it and/or modify it
582+ * under the terms of the GNU General Public License version 3, as published
583+ * by the Free Software Foundation.
584+ *
585+ * This program is distributed in the hope that it will be useful, but
586+ * WITHOUT ANY WARRANTY; without even the implied warranties of
587+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
588+ * PURPOSE. See the GNU General Public License for more details.
589+ *
590+ * You should have received a copy of the GNU General Public License
591+ * version 3 along with this program. If not, see
592+ * <http://www.gnu.org/licenses/>
593+ *
594+ * Authored by: Marco Trevisan (Treviño) <marco.trevisan@canonical.com>
595+ */
596+
597+#include <gmock/gmock.h>
598+
599+#include "LauncherDragWindow.h"
600+
601+using namespace unity::launcher;
602+using namespace testing;
603+
604+namespace
605+{
606+const int ICON_WIDTH = 10;
607+const int ICON_HEIGHT = 15;
608+}
609+
610+namespace unity
611+{
612+namespace launcher
613+{
614+struct TestLauncherDragWindow : public testing::Test
615+{
616+ TestLauncherDragWindow()
617+ : drag_window(nux::ObjectPtr<nux::IOpenGLBaseTexture>(new nux::IOpenGLBaseTexture(nux::RTTEXTURE, ICON_WIDTH, ICON_HEIGHT, 24, 1, nux::BITFMT_B8G8R8A8)))
618+ {}
619+
620+ LauncherDragWindow drag_window;
621+};
622+}
623+
624+TEST_F(TestLauncherDragWindow, Construction)
625+{
626+ EXPECT_EQ(drag_window.GetBaseWidth(), ICON_WIDTH);
627+ EXPECT_EQ(drag_window.GetBaseHeight(), ICON_HEIGHT);
628+ EXPECT_FALSE(drag_window.Animating());
629+ EXPECT_FALSE(drag_window.Cancelled());
630+}
631+
632+TEST_F(TestLauncherDragWindow, EscapeRequestsCancellation)
633+{
634+ nux::Event cancel;
635+ cancel.type = nux::NUX_KEYDOWN;
636+ cancel.x11_keysym = NUX_VK_ESCAPE;
637+ bool got_signal;
638+
639+ drag_window.drag_cancel_request.connect([&got_signal] { got_signal = true; });
640+ drag_window.GrabKeyboard();
641+ nux::GetWindowCompositor().ProcessEvent(cancel);
642+
643+ EXPECT_TRUE(got_signal);
644+ EXPECT_TRUE(drag_window.Cancelled());
645+}
646+
647+}
648
649=== modified file 'tests/test_launcher_model.cpp'
650--- tests/test_launcher_model.cpp 2012-02-12 10:43:11 +0000
651+++ tests/test_launcher_model.cpp 2012-08-31 20:16:18 +0000
652@@ -213,4 +213,48 @@
653 EXPECT_EQ(fourth, *it);
654 }
655
656+TEST(TestLauncherModel, TestGetClosestIcon)
657+{
658+ LauncherModel::Ptr model(new LauncherModel());
659+ AbstractLauncherIcon::Ptr first(new MockLauncherIcon());
660+ AbstractLauncherIcon::Ptr second(new MockLauncherIcon());
661+ AbstractLauncherIcon::Ptr third(new MockLauncherIcon());
662+ AbstractLauncherIcon::Ptr fourth(new MockLauncherIcon());
663+
664+ first->SetSortPriority(0);
665+ second->SetSortPriority(1);
666+ third->SetSortPriority(2);
667+ fourth->SetSortPriority(3);
668+
669+ model->AddIcon(first);
670+ model->AddIcon(second);
671+ model->AddIcon(third);
672+ model->AddIcon(fourth);
673+
674+ bool before;
675+ EXPECT_EQ(model->GetClosestIcon(first, before), second);
676+ EXPECT_FALSE(before);
677+
678+ EXPECT_EQ(model->GetClosestIcon(second, before), first);
679+ EXPECT_TRUE(before);
680+
681+ EXPECT_EQ(model->GetClosestIcon(third, before), second);
682+ EXPECT_TRUE(before);
683+
684+ EXPECT_EQ(model->GetClosestIcon(fourth, before), third);
685+ EXPECT_TRUE(before);
686+}
687+
688+TEST(TestLauncherModel, TestGetClosestIconWithOneIcon)
689+{
690+ LauncherModel::Ptr model(new LauncherModel());
691+ AbstractLauncherIcon::Ptr first(new MockLauncherIcon());
692+
693+ model->AddIcon(first);
694+
695+ bool before;
696+ EXPECT_EQ(model->GetClosestIcon(first, before), nullptr);
697+ EXPECT_TRUE(before);
698+}
699+
700 }