Merge lp:~3v1n0/unity/icon-dragging-cancellation into lp:unity
- icon-dragging-cancellation
- Merge into trunk
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 |
Related bugs: |
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
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.
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, ¤t); |
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 | } |
Looks good and works.