Merge lp:~3v1n0/unity/dynamic-ws-shortcuts into lp:unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Andrea Azzarone
Approved revision: no longer in the source branch.
Merged at revision: 3054
Proposed branch: lp:~3v1n0/unity/dynamic-ws-shortcuts
Merge into: lp:unity
Diff against target: 1644 lines (+537/-264)
18 files modified
launcher/LauncherController.cpp (+0/-4)
launcher/LauncherController.h (+0/-2)
plugins/unityshell/src/unityshell.cpp (+40/-42)
shortcuts/AbstractShortcutHint.h (+7/-7)
shortcuts/MockShortcutHint.h (+9/-9)
shortcuts/ShortcutController.cpp (+30/-7)
shortcuts/ShortcutController.h (+4/-0)
shortcuts/ShortcutHint.cpp (+5/-5)
shortcuts/ShortcutModel.cpp (+12/-3)
shortcuts/ShortcutModel.h (+3/-2)
shortcuts/ShortcutView.cpp (+65/-95)
shortcuts/ShortcutView.h (+3/-10)
shortcuts/StandaloneShortcuts.cpp (+52/-33)
tests/CMakeLists.txt (+1/-0)
tests/test_shortcut_controller.cpp (+47/-18)
tests/test_shortcut_model.cpp (+52/-27)
tests/test_shortcut_view.cpp (+198/-0)
tests/test_uscreen_mock.h (+9/-0)
To merge this branch: bzr merge lp:~3v1n0/unity/dynamic-ws-shortcuts
Reviewer Review Type Date Requested Status
Andrea Azzarone (community) Approve
PS Jenkins bot continuous-integration Pending
Review via email: mp+144186@code.launchpad.net

Commit message

shortcut: cleanup the code making it more dynamic and model-dependent

Description of the change

Cleanup the shortcut hints code to make it to be more model-dependent, move the positioning code to the Controller (adding tests for it, and allowing to have a better standalone overlay). Fix some redrawing issues and a potential crash (disconnecting signals).

Directly connect to launcher size changes, removing some wrapping on the launcher controller.

Added new tests that covers both changes to the model, to the view and to the controller.

To post a comment you must log in.
Revision history for this message
Andrea Azzarone (azzar1) wrote :

A lot of unrelated changes but overall looks good.

+#include <stdexcept>

??

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'launcher/LauncherController.cpp'
2--- launcher/LauncherController.cpp 2013-01-18 18:22:03 +0000
3+++ launcher/LauncherController.cpp 2013-01-21 21:26:21 +0000
4@@ -333,10 +333,6 @@
5 launcher_window->InputWindowEnableStruts(parent_->options()->hide_mode == LAUNCHER_HIDE_NEVER);
6 launcher_window->SetEnterFocusInputArea(launcher);
7
8- launcher_window->geometry_changed.connect([this] (nux::Area* /*area*/, nux::Geometry const& geo) {
9- parent_->launcher_width_changed.emit(geo.width);
10- });
11-
12 launcher->add_request.connect(sigc::mem_fun(this, &Impl::OnLauncherAddRequest));
13 launcher->remove_request.connect(sigc::mem_fun(this, &Impl::OnLauncherRemoveRequest));
14
15
16=== modified file 'launcher/LauncherController.h'
17--- launcher/LauncherController.h 2013-01-08 11:47:00 +0000
18+++ launcher/LauncherController.h 2013-01-21 21:26:21 +0000
19@@ -83,8 +83,6 @@
20
21 void UpdateSuperTapDuration(int const super_tap_duration);
22
23- sigc::signal<void, int> launcher_width_changed;
24-
25 protected:
26 // Introspectable methods
27 std::string GetName() const;
28
29=== modified file 'plugins/unityshell/src/unityshell.cpp'
30--- plugins/unityshell/src/unityshell.cpp 2013-01-14 12:06:45 +0000
31+++ plugins/unityshell/src/unityshell.cpp 2013-01-21 21:26:21 +0000
32@@ -1729,13 +1729,9 @@
33
34 if (!shortcut_controller_->Visible() && shortcut_controller_->IsEnabled())
35 {
36- int launcher_width = optionGetIconSize() + 18;
37- int panel_height = panel_style_.panel_height;
38-
39 if (shortcut_controller_->Show())
40 {
41 LOG_DEBUG(logger) << "Showing shortcut hint.";
42- shortcut_controller_->SetAdjustment(launcher_width, panel_height);
43 EnableCancelAction(CancelActionTarget::SHORTCUT_HINT, true, action->key().modifiers());
44 }
45 }
46@@ -3153,12 +3149,14 @@
47
48 AddChild(dash_controller_.get());
49
50- launcher_controller_->launcher_width_changed.connect([this] (int launcher_width) {
51+ launcher_controller_->launcher().size_changed.connect([this] (nux::Area*, int w, int h) {
52 /* The launcher geometry includes 1px used to draw the right margin
53 * that must not be considered when drawing an overlay */
54- hud_controller_->launcher_width = launcher_width - 1;
55- dash_controller_->launcher_width = launcher_width - 1;
56- panel_controller_->launcher_width = launcher_width - 1;
57+ int launcher_width = w - 1;
58+ hud_controller_->launcher_width = launcher_width;
59+ dash_controller_->launcher_width = launcher_width;
60+ panel_controller_->launcher_width = launcher_width;
61+ shortcut_controller_->SetAdjustment(launcher_width, panel_style_.panel_height);
62 });
63
64 ScheduleRelayout(0);
65@@ -3229,37 +3227,37 @@
66
67 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", _(" (Hold)"),
68 _("Opens the Launcher, displays shortcuts."),
69- shortcut::COMPIZ_KEY_OPTION,
70+ shortcut::OptionType::COMPIZ_KEY,
71 COMPIZ_UNITYSHELL_PLUGIN_NAME,
72 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
73
74 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", "",
75 _("Opens Launcher keyboard navigation mode."),
76- shortcut::COMPIZ_KEY_OPTION,
77+ shortcut::OptionType::COMPIZ_KEY,
78 COMPIZ_UNITYSHELL_PLUGIN_NAME,
79 COMPIZ_UNITYSHELL_OPTION_KEYBOARD_FOCUS));
80
81 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", "",
82 _("Switches applications via the Launcher."),
83- shortcut::COMPIZ_KEY_OPTION,
84+ shortcut::OptionType::COMPIZ_KEY,
85 COMPIZ_UNITYSHELL_PLUGIN_NAME,
86 COMPIZ_UNITYSHELL_OPTION_LAUNCHER_SWITCHER_FORWARD));
87
88 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", _(" + 1 to 9"),
89 _("Same as clicking on a Launcher icon."),
90- shortcut::COMPIZ_KEY_OPTION,
91+ shortcut::OptionType::COMPIZ_KEY,
92 COMPIZ_UNITYSHELL_PLUGIN_NAME,
93 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
94
95 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", _(" + Shift + 1 to 9"),
96 _("Opens a new window in the app."),
97- shortcut::COMPIZ_KEY_OPTION,
98+ shortcut::OptionType::COMPIZ_KEY,
99 COMPIZ_UNITYSHELL_PLUGIN_NAME,
100 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
101
102 hints_.push_back(std::make_shared<shortcut::Hint>(launcher, "", " + T",
103 _("Opens the Trash."),
104- shortcut::COMPIZ_KEY_OPTION,
105+ shortcut::OptionType::COMPIZ_KEY,
106 COMPIZ_UNITYSHELL_PLUGIN_NAME,
107 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
108
109@@ -3269,47 +3267,47 @@
110
111 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", _(" (Tap)"),
112 _("Opens the Dash Home."),
113- shortcut::COMPIZ_KEY_OPTION,
114+ shortcut::OptionType::COMPIZ_KEY,
115 COMPIZ_UNITYSHELL_PLUGIN_NAME,
116 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
117
118 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", " + A",
119 _("Opens the Dash App Lens."),
120- shortcut::COMPIZ_KEY_OPTION,
121+ shortcut::OptionType::COMPIZ_KEY,
122 COMPIZ_UNITYSHELL_PLUGIN_NAME,
123 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
124
125 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", " + F",
126 _("Opens the Dash Files Lens."),
127- shortcut::COMPIZ_KEY_OPTION,
128+ shortcut::OptionType::COMPIZ_KEY,
129 COMPIZ_UNITYSHELL_PLUGIN_NAME,
130 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
131
132 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", " + M",
133 _("Opens the Dash Music Lens."),
134- shortcut::COMPIZ_KEY_OPTION,
135+ shortcut::OptionType::COMPIZ_KEY,
136 COMPIZ_UNITYSHELL_PLUGIN_NAME,
137 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
138
139 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", " + V",
140 _("Opens the Dash Video Lens."),
141- shortcut::COMPIZ_KEY_OPTION,
142+ shortcut::OptionType::COMPIZ_KEY,
143 COMPIZ_UNITYSHELL_PLUGIN_NAME,
144 COMPIZ_UNITYSHELL_OPTION_SHOW_LAUNCHER));
145
146 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", "",
147 _("Switches between Lenses."),
148- shortcut::HARDCODED_OPTION,
149+ shortcut::OptionType::HARDCODED,
150 _("Ctrl + Tab")));
151
152 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", "",
153 _("Moves the focus."),
154- shortcut::HARDCODED_OPTION,
155+ shortcut::OptionType::HARDCODED,
156 _("Arrow Keys")));
157
158 hints_.push_back(std::make_shared<shortcut::Hint>(dash, "", "",
159 _("Opens the currently focused item."),
160- shortcut::HARDCODED_OPTION,
161+ shortcut::OptionType::HARDCODED,
162 _("Enter")));
163
164 // Menu Bar
165@@ -3317,24 +3315,24 @@
166
167 hints_.push_back(std::make_shared<shortcut::Hint>(menubar, "", _(" (Tap)"),
168 _("Opens the HUD."),
169- shortcut::COMPIZ_KEY_OPTION,
170+ shortcut::OptionType::COMPIZ_KEY,
171 COMPIZ_UNITYSHELL_PLUGIN_NAME,
172 COMPIZ_UNITYSHELL_OPTION_SHOW_HUD));
173
174 hints_.push_back(std::make_shared<shortcut::Hint>(menubar, "", _(" (Hold)"),
175 _("Reveals the application menu."),
176- shortcut::HARDCODED_OPTION,
177+ shortcut::OptionType::HARDCODED,
178 "Alt"));
179
180 hints_.push_back(std::make_shared<shortcut::Hint>(menubar, "", "",
181 _("Opens the indicator menu."),
182- shortcut::COMPIZ_KEY_OPTION,
183+ shortcut::OptionType::COMPIZ_KEY,
184 COMPIZ_UNITYSHELL_PLUGIN_NAME,
185 COMPIZ_UNITYSHELL_OPTION_PANEL_FIRST_MENU));
186
187 hints_.push_back(std::make_shared<shortcut::Hint>(menubar, "", "",
188 _("Moves focus between indicators."),
189- shortcut::HARDCODED_OPTION,
190+ shortcut::OptionType::HARDCODED,
191 _("Cursor Left or Right")));
192
193 // Switching
194@@ -3342,19 +3340,19 @@
195
196 hints_.push_back(std::make_shared<shortcut::Hint>(switching, "", "",
197 _("Switches between applications."),
198- shortcut::COMPIZ_KEY_OPTION,
199+ shortcut::OptionType::COMPIZ_KEY,
200 COMPIZ_UNITYSHELL_PLUGIN_NAME,
201 COMPIZ_UNITYSHELL_OPTION_ALT_TAB_FORWARD));
202
203 hints_.push_back(std::make_shared<shortcut::Hint>(switching, "", "",
204 _("Switches windows of current applications."),
205- shortcut::COMPIZ_KEY_OPTION,
206+ shortcut::OptionType::COMPIZ_KEY,
207 COMPIZ_UNITYSHELL_PLUGIN_NAME,
208 COMPIZ_UNITYSHELL_OPTION_ALT_TAB_NEXT_WINDOW));
209
210 hints_.push_back(std::make_shared<shortcut::Hint>(switching, "", "",
211 _("Moves the focus."),
212- shortcut::HARDCODED_OPTION,
213+ shortcut::OptionType::HARDCODED,
214 _("Cursor Left or Right")));
215
216 // Workspaces
217@@ -3362,19 +3360,19 @@
218
219 hints_.push_back(std::make_shared<shortcut::Hint>(workspaces, "", "",
220 _("Switches between workspaces."),
221- shortcut::COMPIZ_KEY_OPTION,
222+ shortcut::OptionType::COMPIZ_KEY,
223 COMPIZ_EXPO_PLUGIN_NAME,
224 COMPIZ_EXPO_OPTION_EXPO_KEY));
225
226 hints_.push_back(std::make_shared<shortcut::Hint>(workspaces, "", _(" + Arrow Keys"),
227 _("Switches workspaces."),
228- shortcut::COMPIZ_METAKEY_OPTION,
229+ shortcut::OptionType::COMPIZ_KEY,
230 COMPIZ_WALL_PLUGIN_NAME,
231 COMPIZ_WALL_OPTION_LEFT_KEY));
232
233 hints_.push_back(std::make_shared<shortcut::Hint>(workspaces, "", _(" + Arrow Keys"),
234 _("Moves focused window to another workspace."),
235- shortcut::COMPIZ_METAKEY_OPTION,
236+ shortcut::OptionType::COMPIZ_KEY,
237 COMPIZ_WALL_PLUGIN_NAME,
238 COMPIZ_WALL_OPTION_LEFT_WINDOW_KEY));
239
240@@ -3384,60 +3382,60 @@
241
242 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
243 _("Spreads all windows in the current workspace."),
244- shortcut::COMPIZ_KEY_OPTION,
245+ shortcut::OptionType::COMPIZ_KEY,
246 COMPIZ_SCALE_PLUGIN_NAME,
247 COMPIZ_SCALE_OPTION_INITIATE_ALL_KEY));
248
249 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
250 _("Minimises all windows."),
251- shortcut::COMPIZ_KEY_OPTION,
252+ shortcut::OptionType::COMPIZ_KEY,
253 COMPIZ_CORE_PLUGIN_NAME,
254 COMPIZ_CORE_OPTION_SHOW_DESKTOP_KEY));
255
256 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
257 _("Maximises the current window."),
258- shortcut::COMPIZ_KEY_OPTION,
259+ shortcut::OptionType::COMPIZ_KEY,
260 COMPIZ_CORE_PLUGIN_NAME,
261 COMPIZ_CORE_OPTION_MAXIMIZE_WINDOW_KEY));
262
263 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
264 _("Restores or minimises the current window."),
265- shortcut::COMPIZ_KEY_OPTION,
266+ shortcut::OptionType::COMPIZ_KEY,
267 COMPIZ_CORE_PLUGIN_NAME,
268 COMPIZ_CORE_OPTION_UNMAXIMIZE_WINDOW_KEY));
269
270 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" or Right"),
271 _("Semi-maximise the current window."),
272- shortcut::COMPIZ_KEY_OPTION,
273+ shortcut::OptionType::COMPIZ_KEY,
274 COMPIZ_GRID_PLUGIN_NAME,
275 COMPIZ_GRID_OPTION_PUT_LEFT_KEY));
276
277 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
278 _("Closes the current window."),
279- shortcut::COMPIZ_KEY_OPTION,
280+ shortcut::OptionType::COMPIZ_KEY,
281 COMPIZ_CORE_PLUGIN_NAME,
282 COMPIZ_CORE_OPTION_CLOSE_WINDOW_KEY));
283
284 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
285 _("Opens the window accessibility menu."),
286- shortcut::COMPIZ_KEY_OPTION,
287+ shortcut::OptionType::COMPIZ_KEY,
288 COMPIZ_CORE_PLUGIN_NAME,
289 COMPIZ_CORE_OPTION_WINDOW_MENU_KEY));
290
291 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", "",
292 _("Places the window in corresponding position."),
293- shortcut::HARDCODED_OPTION,
294+ shortcut::OptionType::HARDCODED,
295 _("Ctrl + Alt + Num")));
296
297 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"),
298 _("Moves the window."),
299- shortcut::COMPIZ_MOUSE_OPTION,
300+ shortcut::OptionType::COMPIZ_MOUSE,
301 COMPIZ_MOVE_PLUGIN_NAME,
302 COMPIZ_MOVE_OPTION_INITIATE_BUTTON));
303
304 hints_.push_back(std::make_shared<shortcut::Hint>(windows, "", _(" Drag"),
305 _("Resizes the window."),
306- shortcut::COMPIZ_MOUSE_OPTION,
307+ shortcut::OptionType::COMPIZ_MOUSE,
308 COMPIZ_RESIZE_PLUGIN_NAME,
309 COMPIZ_RESIZE_OPTION_INITIATE_BUTTON));
310 }
311
312=== modified file 'shortcuts/AbstractShortcutHint.h'
313--- shortcuts/AbstractShortcutHint.h 2012-09-11 10:38:31 +0000
314+++ shortcuts/AbstractShortcutHint.h 2013-01-21 21:26:21 +0000
315@@ -31,14 +31,14 @@
316 namespace shortcut
317 {
318
319-enum OptionType
320+enum class OptionType : unsigned
321 {
322- COMPIZ_KEY_OPTION = 0,
323- COMPIZ_METAKEY_OPTION,
324- COMPIZ_MOUSE_OPTION,
325- HARDCODED_OPTION
326- /* GSETTINGS_OPTION,
327- * GCONF_OPTION */
328+ COMPIZ_KEY = 0,
329+ COMPIZ_METAKEY,
330+ COMPIZ_MOUSE,
331+ HARDCODED
332+ /* GSETTINGS,
333+ * GCONF */
334 };
335
336 class AbstractHint
337
338=== modified file 'shortcuts/MockShortcutHint.h'
339--- shortcuts/MockShortcutHint.h 2012-09-11 10:38:31 +0000
340+++ shortcuts/MockShortcutHint.h 2013-01-21 21:26:21 +0000
341@@ -37,34 +37,34 @@
342 std::string const& postfix,
343 std::string const& description,
344 OptionType const type,
345- std::string const& arg1,
346+ std::string const& arg1,
347 std::string const& arg2 = "",
348 std::string const& arg3 = "")
349 : AbstractHint(category, prefix, postfix, description, type, arg1, arg2, arg3)
350 {}
351-
352+
353 // Methods...
354 bool Fill()
355 {
356 switch (type())
357 {
358- case COMPIZ_MOUSE_OPTION:
359- case COMPIZ_KEY_OPTION:
360- case COMPIZ_METAKEY_OPTION:
361+ case OptionType::COMPIZ_MOUSE:
362+ case OptionType::COMPIZ_KEY:
363+ case OptionType::COMPIZ_METAKEY:
364 value = arg1() + "-" + arg2();
365 shortkey = prefix() + value() + postfix();
366 return true;
367-
368- case HARDCODED_OPTION:
369+
370+ case OptionType::HARDCODED:
371 value = arg1();
372 shortkey = prefix() + value() + postfix();
373 return true;
374 }
375-
376+
377 return false;
378 }
379 };
380-
381+
382 }
383 }
384
385
386=== modified file 'shortcuts/ShortcutController.cpp'
387--- shortcuts/ShortcutController.cpp 2012-12-14 17:38:35 +0000
388+++ shortcuts/ShortcutController.cpp 2013-01-21 21:26:21 +0000
389@@ -1,5 +1,5 @@
390 /*
391- * Copyright (C) 2011 Canonical Ltd
392+ * Copyright (C) 2011-2013 Canonical Ltd
393 *
394 * This program is free software: you can redistribute it and/or modify
395 * it under the terms of the GNU General Public License version 3 as
396@@ -14,11 +14,13 @@
397 * along with this program. If not, see <http://www.gnu.org/licenses/>.
398 *
399 * Authored by: Andrea Azzarone <andrea.azzarone@canonical.com>
400+ * Marco Trevisan <marco.trevisan@canonical.com>
401 */
402
403 #include "ShortcutController.h"
404
405 #include "unity-shared/UBusMessages.h"
406+#include "unity-shared/UScreen.h"
407
408 namespace na = nux::animation;
409
410@@ -101,8 +103,10 @@
411
412 base_window_raiser_->Raise(view_window_);
413
414- nux::Geometry geo;
415- if (!view_->GetBaseGeometry(geo))
416+ int monitor = UScreen::GetDefault()->GetMonitorWithMouse();
417+ auto const& geo = GetGeometryPerMonitor(monitor);
418+
419+ if (geo.IsNull())
420 return false;
421
422 view_window_->SetGeometry(geo);
423@@ -125,6 +129,27 @@
424 return false;
425 }
426
427+nux::Geometry Controller::GetGeometryPerMonitor(int monitor)
428+{
429+ if (!view_)
430+ ConstructView();
431+
432+ auto const& view_geo = view_->GetAbsoluteGeometry();
433+ auto const& monitor_geo = UScreen::GetDefault()->GetMonitorGeometry(monitor);
434+
435+ if (adjustment_.x + view_geo.width > monitor_geo.width ||
436+ adjustment_.y + view_geo.height > monitor_geo.height)
437+ {
438+ return nux::Geometry();
439+ }
440+
441+ nux::Geometry geo(monitor_geo.x, monitor_geo.y, view_geo.width, view_geo.height);
442+ geo.x += adjustment_.x + (monitor_geo.width - view_geo.width - adjustment_.x) / 2;
443+ geo.y += adjustment_.y + (monitor_geo.height - view_geo.height - adjustment_.y) / 2;
444+
445+ return geo;
446+}
447+
448 void Controller::ConstructView()
449 {
450 view_ = View::Ptr(new View());
451@@ -158,12 +183,10 @@
452
453 void Controller::SetAdjustment(int x, int y)
454 {
455- EnsureView();
456-
457- view_->SetAdjustment(x, y);
458+ adjustment_.x = x;
459+ adjustment_.y = y;
460 }
461
462-
463 void Controller::Hide()
464 {
465 if (!visible_)
466
467=== modified file 'shortcuts/ShortcutController.h'
468--- shortcuts/ShortcutController.h 2012-12-14 17:38:35 +0000
469+++ shortcuts/ShortcutController.h 2013-01-21 21:26:21 +0000
470@@ -63,6 +63,7 @@
471 // Introspectable
472 std::string GetName() const;
473 void AddProperties(GVariantBuilder* builder);
474+ virtual nux::Geometry GetGeometryPerMonitor(int monitor);
475
476 private:
477 void ConstructView();
478@@ -77,6 +78,7 @@
479 nux::Geometry workarea_;
480 nux::ObjectPtr<nux::BaseWindow> view_window_;
481 nux::HLayout* main_layout_;
482+ nux::Point adjustment_;
483
484 bool visible_;
485 bool enabled_;
486@@ -86,6 +88,8 @@
487
488 glib::Source::UniquePtr show_timer_;
489 UBusManager ubus_manager_;
490+
491+ friend class TestShortcutController;
492 };
493
494 }
495
496=== modified file 'shortcuts/ShortcutHint.cpp'
497--- shortcuts/ShortcutHint.cpp 2012-10-29 09:34:54 +0000
498+++ shortcuts/ShortcutHint.cpp 2013-01-21 21:26:21 +0000
499@@ -58,7 +58,7 @@
500 {
501 switch(type())
502 {
503- case COMPIZ_MOUSE_OPTION:
504+ case OptionType::COMPIZ_MOUSE:
505 {
506 // Arg1 = Plugin name
507 // Arg2 = key Option name
508@@ -88,7 +88,7 @@
509 }
510 break;
511
512- case COMPIZ_KEY_OPTION:
513+ case OptionType::COMPIZ_KEY:
514 {
515 // Arg1 = Plugin name
516 // Arg2 = key Option name
517@@ -116,7 +116,7 @@
518
519 break;
520 }
521- case COMPIZ_METAKEY_OPTION:
522+ case OptionType::COMPIZ_METAKEY:
523 {
524 // Arg1 = Plugin name
525 // Arg2 = key Option name
526@@ -145,7 +145,7 @@
527
528 break;
529 }
530- case HARDCODED_OPTION:
531+ case OptionType::HARDCODED:
532 if (value != arg1())
533 {
534 value = arg1();
535@@ -154,7 +154,7 @@
536 return true;
537
538 default:
539- LOG_WARNING(logger) << "Unable to find the option type" << type();
540+ LOG_WARNING(logger) << "Unable to find the option type" << static_cast<unsigned>(type());
541 }
542
543 return false;
544
545=== modified file 'shortcuts/ShortcutModel.cpp'
546--- shortcuts/ShortcutModel.cpp 2012-09-10 21:03:34 +0000
547+++ shortcuts/ShortcutModel.cpp 2013-01-21 21:26:21 +0000
548@@ -25,8 +25,17 @@
549 {
550
551 Model::Model(std::list<AbstractHint::Ptr> const& hints)
552+ : categories_per_column(3, [] (int& target, int const& new_value) {
553+ int cat_per_col = std::max<int>(1, new_value);
554+ if (cat_per_col != target)
555+ {
556+ target = cat_per_col;
557+ return true;
558+ }
559+ return false;
560+ })
561 {
562- for (auto hint : hints)
563+ for (auto const& hint : hints)
564 AddHint(hint);
565 }
566
567@@ -44,8 +53,8 @@
568
569 void Model::Fill()
570 {
571- for (auto category : categories_)
572- for (auto item : hints_[category])
573+ for (auto const& category : categories_)
574+ for (auto const& item : hints_[category])
575 item->Fill();
576 }
577
578
579=== modified file 'shortcuts/ShortcutModel.h'
580--- shortcuts/ShortcutModel.h 2012-09-10 21:03:34 +0000
581+++ shortcuts/ShortcutModel.h 2013-01-21 21:26:21 +0000
582@@ -41,8 +41,9 @@
583
584 Model(std::list<AbstractHint::Ptr> const& hints);
585
586- std::vector<std::string>& categories() { return categories_; }
587- std::map<std::string, std::list<AbstractHint::Ptr>>& hints() { return hints_; }
588+ nux::Property<int> categories_per_column;
589+ std::vector<std::string> const& categories() const { return categories_; }
590+ std::map<std::string, std::list<AbstractHint::Ptr>> const& hints() const { return hints_; }
591
592 void Fill();
593
594
595=== modified file 'shortcuts/ShortcutView.cpp'
596--- shortcuts/ShortcutView.cpp 2012-08-10 11:47:10 +0000
597+++ shortcuts/ShortcutView.cpp 2013-01-21 21:26:21 +0000
598@@ -1,5 +1,5 @@
599 /*
600- * Copyright (C) 2011 Canonical Ltd
601+ * Copyright (C) 2011-2013 Canonical Ltd
602 *
603 * This program is free software: you can redistribute it and/or modify
604 * it under the terms of the GNU General Public License version 3 as
605@@ -15,17 +15,16 @@
606 *
607 * Authored by: Andrea Azzarone <azzaronea@gmail.com>
608 * Jay Taoko <jay.taoko@canonical.com>
609+ * Marco Trevisan <marco.trevisan@canonical.com>
610 */
611
612 #include "ShortcutView.h"
613
614 #include <glib/gi18n-lib.h>
615-#include <boost/algorithm/string.hpp>
616 #include <UnityCore/GLibWrapper.h>
617
618 #include "unity-shared/LineSeparator.h"
619 #include "unity-shared/StaticCairoText.h"
620-#include "unity-shared/UScreen.h"
621
622 namespace unity
623 {
624@@ -33,12 +32,12 @@
625 {
626 namespace
627 {
628- int SECTION_NAME_FONT_SIZE = 17/1.33;
629- int SHORTKEY_ENTRY_FONT_SIZE = 13/1.33;
630- int INTER_SPACE_SHORTKEY_DESCRIPTION = 10;
631- int SHORTKEY_COLUMN_WIDTH = 150;
632- int DESCRIPTION_COLUMN_WIDTH = 265;
633- int LINE_SPACING = 5;
634+ const unsigned SECTION_NAME_FONT_SIZE = 17/1.33;
635+ const unsigned SHORTKEY_ENTRY_FONT_SIZE = 13/1.33;
636+ const unsigned INTER_SPACE_SHORTKEY_DESCRIPTION = 10;
637+ const unsigned SHORTKEY_COLUMN_WIDTH = 150;
638+ const unsigned DESCRIPTION_COLUMN_WIDTH = 265;
639+ const unsigned LINE_SPACING = 5;
640
641 // We need this class because SetVisible doesn't work for layouts.
642 class SectionView : public nux::View
643@@ -46,13 +45,18 @@
644 public:
645 SectionView(NUX_FILE_LINE_DECL)
646 : nux::View(NUX_FILE_LINE_PARAM)
647+ {}
648+
649+ ~SectionView()
650 {
651+ key_changed_conn.disconnect();
652 }
653
654+ sigc::connection key_changed_conn;
655+
656 protected:
657 void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
658- {
659- }
660+ {}
661
662 void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
663 {
664@@ -67,45 +71,30 @@
665
666 View::View()
667 : ui::UnityWindowView()
668- , x_adjustment_(0)
669- , y_adjustment_(0)
670 {
671- layout_ = new nux::VLayout();
672- layout_->SetPadding(50, 38);
673- layout_->SetSpaceBetweenChildren(20);
674- SetLayout(layout_);
675+ auto main_layout = new nux::VLayout();
676+ main_layout->SetPadding(50, 38);
677+ main_layout->SetSpaceBetweenChildren(20);
678+ SetLayout(main_layout);
679
680- std::string header = "<b>";
681- header += _("Keyboard Shortcuts");
682- header += "</b>";
683+ std::string header = "<b>"+std::string(_("Keyboard Shortcuts"))+"</b>";
684
685 nux::StaticText* header_view = new nux::StaticText(header, NUX_TRACKER_LOCATION);
686 header_view->SetTextPointSize(20/1.33);
687 header_view->SetFontName("Ubuntu");
688- layout_->AddView(header_view, 1 , nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
689+ main_layout->AddView(header_view, 1 , nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
690
691- layout_->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
692+ main_layout->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
693
694 columns_layout_ = new nux::HLayout();
695 columns_layout_->SetSpaceBetweenChildren(30);
696- layout_->AddLayout(columns_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
697-
698- // Column 1...
699- columns_.push_back(new nux::VLayout());
700- columns_layout_->AddLayout(columns_[0], 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
701-
702- // Column 2...
703- columns_.push_back(new nux::VLayout());
704- columns_layout_->AddLayout(columns_[1], 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
705-}
706-
707-View::~View()
708-{
709+ main_layout->AddLayout(columns_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
710 }
711
712 void View::SetModel(Model::Ptr model)
713 {
714 model_ = model;
715+ model_->categories_per_column.changed.connect(sigc::hide(sigc::mem_fun(this, &View::RenderColumns)));
716
717 // Fills the columns...
718 RenderColumns();
719@@ -116,41 +105,11 @@
720 return model_;
721 }
722
723-void View::SetAdjustment(int x, int y)
724-{
725- x_adjustment_ = x;
726- y_adjustment_ = y;
727-}
728-
729-bool View::GetBaseGeometry(nux::Geometry& geo)
730-{
731- UScreen* uscreen = UScreen::GetDefault();
732- int primary_monitor = uscreen->GetMonitorWithMouse();
733- auto monitor_geo = uscreen->GetMonitorGeometry(primary_monitor);
734-
735- int w = GetAbsoluteWidth();
736- int h = GetAbsoluteHeight();
737-
738- if (x_adjustment_ + w > monitor_geo.width ||
739- y_adjustment_ + h > monitor_geo.height)
740- return false;
741-
742- geo.width = w;
743- geo.height = h;
744-
745- geo.x = monitor_geo.x + x_adjustment_ + (monitor_geo.width - geo.width - x_adjustment_) / 2;
746- geo.y = monitor_geo.y + y_adjustment_ + (monitor_geo.height - geo.height - y_adjustment_) / 2;
747- return true;
748-}
749-
750-nux::LinearLayout* View::CreateSectionLayout(const char* section_name)
751+nux::LinearLayout* View::CreateSectionLayout(std::string const& section_name)
752 {
753 nux::VLayout* layout = new nux::VLayout(NUX_TRACKER_LOCATION);
754
755- std::string name("<b>");
756- name += glib::String(g_markup_escape_text(section_name, -1)).Str();
757- name += "</b>";
758-
759+ std::string name("<b>"+glib::String(g_markup_escape_text(section_name.c_str(), -1)).Str()+"</b>");
760 nux::StaticText* section_name_view = new nux::StaticText(name, NUX_TRACKER_LOCATION);
761 section_name_view->SetTextPointSize(SECTION_NAME_FONT_SIZE);
762 section_name_view->SetFontName("Ubuntu");
763@@ -163,7 +122,7 @@
764
765 nux::View* View::CreateShortKeyEntryView(AbstractHint::Ptr const& hint)
766 {
767- nux::View* view = new SectionView(NUX_TRACKER_LOCATION);
768+ auto* view = new SectionView(NUX_TRACKER_LOCATION);
769
770 nux::HLayout* layout = new nux::HLayout("EntryLayout", NUX_TRACKER_LOCATION);
771 view->SetLayout(layout);
772@@ -173,10 +132,7 @@
773
774 glib::String shortkey(g_markup_escape_text(hint->shortkey().c_str(), -1));
775
776- std::string skey = "<b>";
777- skey += shortkey.Str();
778- skey += "</b>";
779-
780+ std::string skey = "<b>"+shortkey.Str()+"</b>";
781 nux::StaticText* shortkey_view = new nux::StaticText(skey, NUX_TRACKER_LOCATION);
782 shortkey_view->SetTextAlignment(nux::StaticText::ALIGN_LEFT);
783 shortkey_view->SetFontName("Ubuntu");
784@@ -208,16 +164,14 @@
785 layout->SetSpaceBetweenChildren(INTER_SPACE_SHORTKEY_DESCRIPTION);
786 description_layout->SetContentDistribution(nux::MAJOR_POSITION_START);
787
788- auto on_shortkey_changed = [view, shortkey_view] (std::string const& new_shortkey) {
789- std::string skey("<b>");
790- skey += new_shortkey;
791- skey += "</b>";
792-
793- shortkey_view->SetText(skey);
794- view->SetVisible(!new_shortkey.empty());
795- };
796-
797- hint->shortkey.changed.connect(on_shortkey_changed);
798+ view->key_changed_conn = hint->shortkey.changed.connect([this, view, shortkey_view] (std::string const& new_key) {
799+ bool enabled = !new_key.empty();
800+ shortkey_view->SetText(enabled ? "<b>"+new_key+"</b>" : "");
801+ view->SetVisible(enabled);
802+ QueueRelayout();
803+ });
804+
805+ view->SetVisible(!shortkey.Str().empty());
806
807 return view;
808 }
809@@ -245,46 +199,62 @@
810
811 void View::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry clip)
812 {
813- layout_->ProcessDraw(GfxContext, force_draw);
814+ view_layout_->ProcessDraw(GfxContext, force_draw);
815 }
816
817 void View::RenderColumns()
818 {
819+ columns_layout_->Clear();
820+
821 int i = 0;
822- int column = 0;
823+ int column_idx = 0;
824+ auto const& columns = columns_layout_->GetChildren();
825
826- for (auto category : model_->categories())
827+ for (auto const& category : model_->categories())
828 {
829- // Three sections in the fist column...
830- if (i > 2)
831- column = 1;
832+ // Computing column index based on current index
833+ column_idx = i/model_->categories_per_column();
834
835- nux::LinearLayout* section_layout = CreateSectionLayout(category.c_str());
836+ nux::LinearLayout* section_layout = CreateSectionLayout(category);
837 nux::LinearLayout* intermediate_layout = CreateIntermediateLayout();
838 intermediate_layout->SetContentDistribution(nux::MAJOR_POSITION_START);
839
840- for (auto hint : model_->hints()[category])
841+ for (auto const& hint : model_->hints().at(category))
842 {
843 nux::View* view = CreateShortKeyEntryView(hint);
844- view->SetVisible(!hint->shortkey().empty());
845 intermediate_layout->AddView(view, 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
846 }
847
848 section_layout->AddLayout(intermediate_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
849
850- if (i == 0 or i==1 or i==3 or i==4)
851+ if ((i + 1) % model_->categories_per_column() != 0 && category != model_->categories().back())
852 {
853- // Add space before the line
854+ // Add a line with some padding after and before each category that is not
855+ // the last of the column.
856 section_layout->AddView(new nux::SpaceLayout(23, 23, 23, 23), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
857 section_layout->AddView(new HSeparator(), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
858- // Add space after the line
859 section_layout->AddView(new nux::SpaceLayout(20, 20, 20, 20), 0, nux::MINOR_POSITION_START, nux::MINOR_SIZE_MATCHCONTENT);
860 }
861
862- columns_[column]->AddView(section_layout, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
863+ nux::VLayout* column = nullptr;
864+ auto column_it = std::next(columns.begin(), column_idx);
865+
866+ if (column_it == columns.end())
867+ {
868+ column = new nux::VLayout();
869+ columns_layout_->AddLayout(column, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
870+ }
871+ else
872+ {
873+ column = static_cast<nux::VLayout*>(*column_it);
874+ }
875+
876+ column->AddView(section_layout, 1, nux::MINOR_POSITION_START, nux::MINOR_SIZE_FULL);
877
878 i++;
879 }
880+
881+ QueueRelayout();
882 }
883
884 //
885
886=== modified file 'shortcuts/ShortcutView.h'
887--- shortcuts/ShortcutView.h 2012-07-09 13:34:41 +0000
888+++ shortcuts/ShortcutView.h 2013-01-21 21:26:21 +0000
889@@ -43,13 +43,10 @@
890 public:
891 typedef nux::ObjectPtr<View> Ptr;
892
893- // Ctor and dtor
894+ // Ctor
895 View();
896- ~View();
897
898 // Public methods
899- bool GetBaseGeometry(nux::Geometry&);
900- void SetAdjustment(int x, int y);
901 void SetModel(Model::Ptr model);
902 Model::Ptr GetModel();
903
904@@ -63,7 +60,7 @@
905
906 private:
907 // Private methods
908- nux::LinearLayout* CreateSectionLayout(const char* section_name);
909+ nux::LinearLayout* CreateSectionLayout(std::string const& section_name);
910 nux::View* CreateShortKeyEntryView(AbstractHint::Ptr const& hint);
911 nux::LinearLayout* CreateIntermediateLayout();
912
913@@ -71,13 +68,9 @@
914
915 // Private members
916 Model::Ptr model_;
917-
918- nux::VLayout* layout_;
919 nux::HLayout* columns_layout_;
920- std::vector<nux::VLayout*> columns_;
921
922- int x_adjustment_;
923- int y_adjustment_;
924+ friend class TestShortcutView;
925 };
926
927 } // namespace shortcut
928
929=== modified file 'shortcuts/StandaloneShortcuts.cpp'
930--- shortcuts/StandaloneShortcuts.cpp 2012-12-11 20:39:16 +0000
931+++ shortcuts/StandaloneShortcuts.cpp 2013-01-21 21:26:21 +0000
932@@ -33,6 +33,25 @@
933
934 using namespace unity;
935
936+namespace unity
937+{
938+namespace shortcut
939+{
940+struct StandaloneController : Controller
941+{
942+ StandaloneController(std::list<AbstractHint::Ptr> const& hints,
943+ BaseWindowRaiser::Ptr const& raiser)
944+ : Controller(hints, raiser)
945+ {}
946+
947+ nux::Geometry GetGeometryPerMonitor(int monitor) override
948+ {
949+ return nux::Geometry(0, 0, 1024, 700);
950+ }
951+};
952+}
953+}
954+
955 struct ShortcutsWindow
956 {
957 ShortcutsWindow()
958@@ -68,133 +87,133 @@
959 // Launcher...
960 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", _(" (Hold)"),
961 _("Opens the Launcher, displays shortcuts."),
962- shortcut::COMPIZ_KEY_OPTION,
963+ shortcut::OptionType::COMPIZ_KEY,
964 "unityshell",
965 "show_launcher" )));
966
967 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", "",
968 _("Opens Launcher keyboard navigation mode."),
969- shortcut::COMPIZ_KEY_OPTION,
970+ shortcut::OptionType::COMPIZ_KEY,
971 "unityshell",
972 "keyboard_focus")));
973
974 // FIXME: Implemstd::shared_ptr<shortcut::AbstractHint>(ent it...
975 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", "",
976 _("Switches applications via the Launcher."),
977- shortcut::HARDCODED_OPTION,
978+ shortcut::OptionType::HARDCODED,
979 "Super + Tab")));
980
981 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", _(" + 1 to 9"),
982 _("Same as clicking on a Launcher icon."),
983- shortcut::COMPIZ_KEY_OPTION,
984+ shortcut::OptionType::COMPIZ_KEY,
985 "unityshell",
986 "show_launcher")));
987
988 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", _(" + Shift + 1 to 9"),
989 _("Opens a new window in the app."),
990- shortcut::COMPIZ_KEY_OPTION,
991+ shortcut::OptionType::COMPIZ_KEY,
992 "unityshell",
993 "show_launcher")));
994
995 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Launcher"), "", " + T",
996 _("Opens the Trash."),
997- shortcut::COMPIZ_KEY_OPTION,
998+ shortcut::OptionType::COMPIZ_KEY,
999 "unityshell",
1000 "show_launcher")));
1001
1002 // Dash...
1003 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", _(" (Tap)"),
1004 _("Opens the Dash Home."),
1005- shortcut::COMPIZ_KEY_OPTION,
1006+ shortcut::OptionType::COMPIZ_KEY,
1007 "unityshell",
1008 "show_launcher")));
1009
1010 // These are notstd::shared_ptr<shortcut::AbstractHint>( really hardcoded...
1011 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", " + A",
1012 _("Opens the Dash App Lens."),
1013- shortcut::COMPIZ_KEY_OPTION,
1014+ shortcut::OptionType::COMPIZ_KEY,
1015 "unityshell",
1016 "show_launcher")));
1017
1018 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", " + F",
1019 _("Opens the Dash Files Lens."),
1020- shortcut::COMPIZ_KEY_OPTION,
1021+ shortcut::OptionType::COMPIZ_KEY,
1022 "unityshell",
1023 "show_launcher")));
1024
1025 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", " + M",
1026 _("Opens the Dash Music Lens."),
1027- shortcut::COMPIZ_KEY_OPTION,
1028+ shortcut::OptionType::COMPIZ_KEY,
1029 "unityshell",
1030 "show_launcher")));
1031
1032 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", "",
1033 _("Switches between Lenses."),
1034- shortcut::HARDCODED_OPTION,
1035+ shortcut::OptionType::HARDCODED,
1036 "Ctrl + Tab")));
1037
1038 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", "",
1039 _("Moves the focus."),
1040- shortcut::HARDCODED_OPTION,
1041+ shortcut::OptionType::HARDCODED,
1042 _("Arrow Keys"))));
1043
1044 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Dash"), "", "",
1045 _("Opens the currently focused item."),
1046- shortcut::HARDCODED_OPTION,
1047+ shortcut::OptionType::HARDCODED,
1048 _("Enter"))));
1049
1050 // Hud Menu Bar
1051 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("HUD & Menu Bar"), "", _(" (Tap)"),
1052 _("Opens the HUD."),
1053- shortcut::COMPIZ_KEY_OPTION,
1054+ shortcut::OptionType::COMPIZ_KEY,
1055 "unityshell",
1056 "show_hud")));
1057
1058 // Is it really std::shared_ptr<shortcut::AbstractHint>(hard coded?
1059 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("HUD & Menu Bar"), "", _(" (Hold)"),
1060 _("Reveals the application menu."),
1061- shortcut::HARDCODED_OPTION,
1062+ shortcut::OptionType::HARDCODED,
1063 "Alt")));
1064
1065 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("HUD & Menu Bar"), "", "",
1066 _("Opens the indicator menu."),
1067- shortcut::COMPIZ_KEY_OPTION,
1068+ shortcut::OptionType::COMPIZ_KEY,
1069 "unityshell",
1070 "panel_first_menu")));
1071
1072 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("HUD & Menu Bar"), "", "",
1073 _("Moves focus between indicators."),
1074- shortcut::HARDCODED_OPTION,
1075+ shortcut::OptionType::HARDCODED,
1076 _("Cursor Left or Right"))));
1077
1078 // Switching
1079 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Switching"), "", "",
1080 _("Switches between applications."),
1081- shortcut::COMPIZ_KEY_OPTION,
1082+ shortcut::OptionType::COMPIZ_KEY,
1083 "unityshell",
1084 "alt_tab_forward")));
1085
1086 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Switching"), "", "",
1087 _("Switches windows of current applications."),
1088- shortcut::COMPIZ_KEY_OPTION,
1089+ shortcut::OptionType::COMPIZ_KEY,
1090 "unityshell",
1091 "alt_tab_next_window")));
1092
1093 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Switching"), "", "",
1094 _("Moves the focus."),
1095- shortcut::HARDCODED_OPTION,
1096+ shortcut::OptionType::HARDCODED,
1097 _("Cursor Left or Right"))));
1098
1099 // Workspaces
1100 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Workspaces"), "", "",
1101 _("Switches between workspaces."),
1102- shortcut::COMPIZ_KEY_OPTION,
1103+ shortcut::OptionType::COMPIZ_KEY,
1104 "expo",
1105 "expo_key")));
1106
1107 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Workspaces"), "", "",
1108 _("Switches workspaces."),
1109- shortcut::HARDCODED_OPTION,
1110+ shortcut::OptionType::HARDCODED,
1111 _("Arrow Keys"))));
1112
1113 //hints.push_bacstd::shared_ptr<shortcut::AbstractHint>(k(new shortcut::MockHint(_("Workspaces"), "", "", _("Move focused window to other workspace."), ...)
1114@@ -202,65 +221,65 @@
1115 // Windows
1116 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1117 _("Spreads all windows in the current workspace."),
1118- shortcut::COMPIZ_KEY_OPTION,
1119+ shortcut::OptionType::COMPIZ_KEY,
1120 "scale",
1121 "initiate_output_key")));
1122
1123 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1124 _("Minimises all windows."),
1125- shortcut::COMPIZ_KEY_OPTION,
1126+ shortcut::OptionType::COMPIZ_KEY,
1127 "core",
1128 "show_desktop_key")));
1129
1130 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1131 _("Maximises the current window."),
1132- shortcut::COMPIZ_KEY_OPTION,
1133+ shortcut::OptionType::COMPIZ_KEY,
1134 "core",
1135 "maximize_window_key")));
1136
1137 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1138 _("Restores or minimises the current window."),
1139- shortcut::COMPIZ_KEY_OPTION,
1140+ shortcut::OptionType::COMPIZ_KEY,
1141 "core",
1142 "unmaximize_window_key")));
1143
1144 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", _(" or Right"),
1145 _("Semi-maximises the current window."),
1146- shortcut::COMPIZ_KEY_OPTION,
1147+ shortcut::OptionType::COMPIZ_KEY,
1148 "grid",
1149 "put_left_key")));
1150
1151 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1152 _("Closes the current window."),
1153- shortcut::COMPIZ_KEY_OPTION,
1154+ shortcut::OptionType::COMPIZ_KEY,
1155 "core",
1156 "close_window_key")));
1157
1158 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1159 _("Opens the window accessibility menu."),
1160- shortcut::COMPIZ_KEY_OPTION,
1161+ shortcut::OptionType::COMPIZ_KEY,
1162 "core",
1163 "window_menu_key")));
1164
1165 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1166 _("Places the window in corresponding position."),
1167- shortcut::HARDCODED_OPTION,
1168+ shortcut::OptionType::HARDCODED,
1169 "Ctrl + Alt + Num")));
1170
1171 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1172 _("Moves the window."),
1173- shortcut::COMPIZ_KEY_OPTION,
1174+ shortcut::OptionType::COMPIZ_KEY,
1175 "move",
1176 "initiate_key")));
1177
1178 hints.push_back(std::shared_ptr<shortcut::AbstractHint>(new shortcut::MockHint(_("Windows"), "", "",
1179 _("Resizes the current window."),
1180- shortcut::COMPIZ_KEY_OPTION,
1181+ shortcut::OptionType::COMPIZ_KEY,
1182 "resize",
1183 "initiate_key")));
1184
1185 auto base_window_raiser_ = std::make_shared<shortcut::BaseWindowRaiserImp>();
1186- controller = std::make_shared<shortcut::Controller>(hints, base_window_raiser_);
1187+ controller = std::make_shared<shortcut::StandaloneController>(hints, base_window_raiser_);
1188 controller->Show();
1189 }
1190
1191
1192=== modified file 'tests/CMakeLists.txt'
1193--- tests/CMakeLists.txt 2013-01-19 02:52:02 +0000
1194+++ tests/CMakeLists.txt 2013-01-21 21:26:21 +0000
1195@@ -229,6 +229,7 @@
1196 test_resultviewgrid.cpp
1197 test_searchbar.cpp
1198 test_shortcut_controller.cpp
1199+ test_shortcut_view.cpp
1200 test_single_monitor_launcher_icon.cpp
1201 test_expo_launcher_icon.cpp
1202 test_showdesktop_handler.cpp
1203
1204=== modified file 'tests/test_shortcut_controller.cpp'
1205--- tests/test_shortcut_controller.cpp 2012-12-14 18:20:13 +0000
1206+++ tests/test_shortcut_controller.cpp 2013-01-21 21:26:21 +0000
1207@@ -26,6 +26,7 @@
1208 using namespace unity;
1209
1210 #include "test_utils.h"
1211+#include "test_uscreen_mock.h"
1212
1213 #include <NuxCore/AnimationController.h>
1214
1215@@ -38,24 +39,32 @@
1216
1217 MOCK_METHOD1 (Raise, void(nux::ObjectPtr<nux::BaseWindow> window));
1218 };
1219-
1220-struct MockShortcutController : public shortcut::Controller
1221-{
1222- MockShortcutController(std::list<shortcut::AbstractHint::Ptr> const& hints,
1223- shortcut::BaseWindowRaiser::Ptr const& base_window_raiser)
1224- : Controller(hints, base_window_raiser)
1225- {}
1226-
1227- MOCK_METHOD1(SetOpacity, void(double));
1228-
1229- void RealSetOpacity(double value)
1230- {
1231- Controller::SetOpacity(value);
1232- }
1233-};
1234-
1235+}
1236+
1237+namespace unity
1238+{
1239+namespace shortcut
1240+{
1241 class TestShortcutController : public Test
1242 {
1243+ struct MockShortcutController : public Controller
1244+ {
1245+ MockShortcutController(std::list<AbstractHint::Ptr> const& hints,
1246+ BaseWindowRaiser::Ptr const& base_window_raiser)
1247+ : Controller(hints, base_window_raiser)
1248+ {}
1249+
1250+ MOCK_METHOD1(SetOpacity, void(double));
1251+ using Controller::GetGeometryPerMonitor;
1252+ using Controller::ConstructView;
1253+ using Controller::view_;
1254+
1255+ void RealSetOpacity(double value)
1256+ {
1257+ Controller::SetOpacity(value);
1258+ }
1259+ };
1260+
1261 public:
1262 TestShortcutController()
1263 : base_window_raiser_(std::make_shared<MockBaseWindowRaiser>())
1264@@ -66,10 +75,11 @@
1265 .WillByDefault(Invoke(&controller_, &MockShortcutController::RealSetOpacity));
1266 }
1267
1268+ MockUScreen uscreen;
1269 Settings unity_settings;
1270 std::list<shortcut::AbstractHint::Ptr> hints_;
1271 MockBaseWindowRaiser::Ptr base_window_raiser_;
1272- MockShortcutController controller_;
1273+ NiceMock<MockShortcutController> controller_;
1274
1275 nux::animation::TickSource tick_source_;
1276 nux::animation::AnimationController animation_controller_;
1277@@ -101,5 +111,24 @@
1278 tick_source_.tick(1000);
1279 }
1280
1281-
1282+TEST_F (TestShortcutController, GetGeometryPerMonitor)
1283+{
1284+ nux::Geometry good_monitor(0, 0, 1366, 768);
1285+ nux::Geometry invalid_monitor(good_monitor.x + good_monitor.width, 0, 1, 1);
1286+ uscreen.SetMonitors({good_monitor, invalid_monitor});
1287+
1288+ nux::Point offset(g_random_int_range(0, 100), g_random_int_range(0, 100));
1289+ controller_.SetAdjustment(offset.x, offset.y);
1290+ controller_.ConstructView();
1291+
1292+ nux::Geometry expected = controller_.view_->GetAbsoluteGeometry();
1293+ expected.x = good_monitor.x + offset.x + (good_monitor.width - expected.width - offset.x) / 2;
1294+ expected.y = good_monitor.y + offset.y + (good_monitor.height - expected.height - offset.y) / 2;
1295+ EXPECT_EQ(controller_.GetGeometryPerMonitor(0), expected);
1296+
1297+ EXPECT_TRUE(controller_.GetGeometryPerMonitor(1).IsNull());
1298+}
1299+
1300+
1301+}
1302 }
1303
1304=== modified file 'tests/test_shortcut_model.cpp'
1305--- tests/test_shortcut_model.cpp 2012-03-29 05:14:03 +0000
1306+++ tests/test_shortcut_model.cpp 2013-01-21 21:26:21 +0000
1307@@ -18,6 +18,7 @@
1308 */
1309
1310 #include <memory>
1311+#include <stdexcept>
1312 #include <gtest/gtest.h>
1313
1314 #include "MockShortcutHint.h"
1315@@ -31,55 +32,79 @@
1316 {
1317 std::list<AbstractHint::Ptr> hints;
1318
1319- hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1"));
1320- hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2"));
1321- hints.push_back(std::make_shared<MockHint>("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3"));
1322- hints.push_back(std::make_shared<MockHint>("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value4"));
1323+ hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 1", OptionType::COMPIZ_KEY, "Plugin 1", "key_option_1"));
1324+ hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 2", OptionType::HARDCODED, "Value 2"));
1325+ hints.push_back(std::make_shared<MockHint>("Dash", "Prefix", "Postfix", "Description 3", OptionType::COMPIZ_KEY, "Plugin 3", "key_option_3"));
1326+ hints.push_back(std::make_shared<MockHint>("Menu Bar", "Prefix", "Postfix", "Description 4", OptionType::HARDCODED, "Value4"));
1327
1328 Model model(hints);
1329
1330+ EXPECT_EQ(model.categories_per_column(), 3);
1331 EXPECT_EQ(model.categories().size(), 3);
1332- EXPECT_EQ(model.hints()["Launcher"].size(), 2);
1333- EXPECT_EQ(model.hints()["Dash"].size(), 1);
1334- EXPECT_EQ(model.hints()["Menu Bar"].size(), 1);
1335- EXPECT_EQ(model.hints()["Unity"].size(), 0);
1336+ EXPECT_EQ(model.hints().at("Launcher").size(), 2);
1337+ EXPECT_EQ(model.hints().at("Dash").size(), 1);
1338+ EXPECT_EQ(model.hints().at("Menu Bar").size(), 1);
1339+ EXPECT_EQ(model.hints().find("Unity"), model.hints().end());
1340 }
1341
1342 TEST(TestShortcutModel, TestFill)
1343 {
1344 std::list<AbstractHint::Ptr> hints;
1345
1346- hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 1", COMPIZ_KEY_OPTION, "Plugin 1", "key_option_1"));
1347- hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 2", HARDCODED_OPTION, "Value 2"));
1348- hints.push_back(std::make_shared<MockHint>("Dash", "Prefix", "Postfix", "Description 3", COMPIZ_KEY_OPTION, "Plugin 3", "key_option_3"));
1349- hints.push_back(std::make_shared<MockHint>("Menu Bar", "Prefix", "Postfix", "Description 4", HARDCODED_OPTION, "Value 4"));
1350+ hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 1", OptionType::COMPIZ_KEY, "Plugin 1", "key_option_1"));
1351+ hints.push_back(std::make_shared<MockHint>("Launcher", "", "", "Description 2", OptionType::HARDCODED, "Value 2"));
1352+ hints.push_back(std::make_shared<MockHint>("Dash", "Prefix", "Postfix", "Description 3", OptionType::COMPIZ_KEY, "Plugin 3", "key_option_3"));
1353+ hints.push_back(std::make_shared<MockHint>("Menu Bar", "Prefix", "Postfix", "Description 4", OptionType::HARDCODED, "Value 4"));
1354
1355 Model model(hints);
1356
1357 model.Fill();
1358
1359 // We cannot test CompOption here... :/
1360- EXPECT_EQ(model.hints()["Launcher"].front()->value(), "Plugin 1-key_option_1");
1361- EXPECT_EQ(model.hints()["Launcher"].back()->value(), "Value 2");
1362- EXPECT_EQ(model.hints()["Dash"].front()->value(),"Plugin 3-key_option_3");
1363- EXPECT_EQ(model.hints()["Menu Bar"].front()->value(), "Value 4");
1364+ EXPECT_EQ(model.hints().at("Launcher").front()->value(), "Plugin 1-key_option_1");
1365+ EXPECT_EQ(model.hints().at("Launcher").back()->value(), "Value 2");
1366+ EXPECT_EQ(model.hints().at("Dash").front()->value(),"Plugin 3-key_option_3");
1367+ EXPECT_EQ(model.hints().at("Menu Bar").front()->value(), "Value 4");
1368 }
1369
1370 TEST(TestShortcutModel, TestProperty)
1371 {
1372 std::list<AbstractHint::Ptr> hints;
1373
1374- hints.push_back(std::make_shared<MockHint>("Launcher", "Prefix1", "Postfix1", "Description1", COMPIZ_KEY_OPTION, "Plugin1", "key_option1"));
1375-
1376- Model model(hints);
1377-
1378- EXPECT_EQ(model.hints()["Launcher"].front()->category(), "Launcher");
1379- EXPECT_EQ(model.hints()["Launcher"].front()->prefix(), "Prefix1");
1380- EXPECT_EQ(model.hints()["Launcher"].front()->postfix(), "Postfix1");
1381- EXPECT_EQ(model.hints()["Launcher"].front()->description(), "Description1");
1382- EXPECT_EQ(model.hints()["Launcher"].front()->type(), COMPIZ_KEY_OPTION);
1383- EXPECT_EQ(model.hints()["Launcher"].front()->arg1(), "Plugin1");
1384- EXPECT_EQ(model.hints()["Launcher"].front()->arg2(), "key_option1");
1385+ hints.push_back(std::make_shared<MockHint>("Launcher", "Prefix1", "Postfix1", "Description1", OptionType::COMPIZ_KEY, "Plugin1", "key_option1"));
1386+
1387+ Model model(hints);
1388+
1389+ EXPECT_EQ(model.hints().at("Launcher").front()->category(), "Launcher");
1390+ EXPECT_EQ(model.hints().at("Launcher").front()->prefix(), "Prefix1");
1391+ EXPECT_EQ(model.hints().at("Launcher").front()->postfix(), "Postfix1");
1392+ EXPECT_EQ(model.hints().at("Launcher").front()->description(), "Description1");
1393+ EXPECT_EQ(model.hints().at("Launcher").front()->type(), OptionType::COMPIZ_KEY);
1394+ EXPECT_EQ(model.hints().at("Launcher").front()->arg1(), "Plugin1");
1395+ EXPECT_EQ(model.hints().at("Launcher").front()->arg2(), "key_option1");
1396+}
1397+
1398+TEST(TestShortcutModel, CategoriesPerColumnSetter)
1399+{
1400+ std::list<AbstractHint::Ptr> hints;
1401+ Model model(hints);
1402+
1403+ bool changed = false;
1404+ model.categories_per_column.changed.connect([&changed] (int) {changed = true;});
1405+
1406+ model.categories_per_column = 3456789;
1407+ EXPECT_TRUE(changed);
1408+ EXPECT_EQ(model.categories_per_column(), 3456789);
1409+
1410+ changed = false;
1411+ model.categories_per_column = 0;
1412+ EXPECT_TRUE(changed);
1413+ EXPECT_EQ(model.categories_per_column(), 1);
1414+
1415+ changed = false;
1416+ model.categories_per_column = -1;
1417+ EXPECT_FALSE(changed);
1418+ EXPECT_EQ(model.categories_per_column(), 1);
1419 }
1420
1421 } // anonymouse namespace
1422
1423=== added file 'tests/test_shortcut_view.cpp'
1424--- tests/test_shortcut_view.cpp 1970-01-01 00:00:00 +0000
1425+++ tests/test_shortcut_view.cpp 2013-01-21 21:26:21 +0000
1426@@ -0,0 +1,198 @@
1427+/*
1428+ * Copyright 2013 Canonical Ltd.
1429+ *
1430+ * This program is free software: you can redistribute it and/or modify it
1431+ * under the terms of the GNU General Public License version 3, as published
1432+ * by the Free Software Foundation.
1433+ *
1434+ * This program is distributed in the hope that it will be useful, but
1435+ * WITHOUT ANY WARRANTY; without even the implied warranties of
1436+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
1437+ * PURPOSE. See the GNU General Public License for more details.
1438+ *
1439+ * You should have received a copy of the GNU General Public License
1440+ * version 3 along with this program. If not, see
1441+ * <http://www.gnu.org/licenses/>
1442+ *
1443+ * Authored by: Marco Trevisan <marco.trevisan@canonical.com>
1444+ */
1445+
1446+#include <gmock/gmock.h>
1447+using namespace testing;
1448+
1449+#include "ShortcutView.h"
1450+#include "ShortcutModel.h"
1451+#include "MockShortcutHint.h"
1452+#include "UnitySettings.h"
1453+#include "LineSeparator.h"
1454+
1455+namespace unity
1456+{
1457+namespace shortcut
1458+{
1459+struct TestShortcutView : Test
1460+{
1461+ struct MockShortcutView : View
1462+ {
1463+ using View::columns_layout_;
1464+ };
1465+
1466+ Model::Ptr GetMockModel(std::vector<std::string> const& categories, unsigned number)
1467+ {
1468+ std::list<AbstractHint::Ptr> hints;
1469+
1470+ for (auto const& category : categories)
1471+ {
1472+ for (unsigned i = 0; i < number; ++i)
1473+ {
1474+ auto str_id = category + std::to_string(i);
1475+ auto hint = std::make_shared<MockHint>(category, "", "", "Description "+str_id, OptionType::HARDCODED, "Value "+str_id);
1476+ hints.push_back(hint);
1477+ }
1478+ }
1479+
1480+ return std::make_shared<Model>(hints);
1481+ }
1482+
1483+ Settings settings;
1484+ MockShortcutView view;
1485+};
1486+
1487+TEST_F(TestShortcutView, Construction)
1488+{
1489+ EXPECT_NE(view.GetLayout(), nullptr);
1490+ auto const& children = view.GetLayout()->GetChildren();
1491+ EXPECT_NE(std::find(children.begin(), children.end(), view.columns_layout_), children.end());
1492+}
1493+
1494+TEST_F(TestShortcutView, SetModel)
1495+{
1496+ auto model = GetMockModel({}, 0);
1497+ view.SetModel(model);
1498+ EXPECT_EQ(view.GetModel(), model);
1499+ EXPECT_FALSE(model->categories_per_column.changed.empty());
1500+}
1501+
1502+TEST_F(TestShortcutView, SettingModelAddsColumns)
1503+{
1504+ auto model = GetMockModel({"Cat1", "Cat2"}, 1);
1505+ model->categories_per_column = 1;
1506+ view.SetModel(model);
1507+
1508+ EXPECT_EQ(view.columns_layout_->GetChildren().size(), 2);
1509+}
1510+
1511+TEST_F(TestShortcutView, SettingModelRebuildsColumns)
1512+{
1513+ auto model1 = GetMockModel({"Cat1", "Cat2"}, 1);
1514+ model1->categories_per_column = 1;
1515+ view.SetModel(model1);
1516+ ASSERT_EQ(view.columns_layout_->GetChildren().size(), 2);
1517+
1518+ auto model2 = GetMockModel({"Cat1"}, 1);
1519+ model2->categories_per_column = 1;
1520+ view.SetModel(model2);
1521+ EXPECT_EQ(view.columns_layout_->GetChildren().size(), 1);
1522+}
1523+
1524+TEST_F(TestShortcutView, ChangingModelParametersRebuildsColumns)
1525+{
1526+ auto model = GetMockModel({"Cat1", "Cat2", "Cat3", "Cat4", "Cat5"}, 1);
1527+ model->categories_per_column = std::numeric_limits<int>::max();
1528+ view.SetModel(model);
1529+
1530+ for (unsigned i = 1; i <= model->categories().size() * 10; ++i)
1531+ {
1532+ model->categories_per_column = i;
1533+ int expected_columns = std::ceil(model->categories().size() / static_cast<double>(model->categories_per_column));
1534+ ASSERT_EQ(view.columns_layout_->GetChildren().size(), expected_columns);
1535+
1536+ int added_cats = 0;
1537+ for (auto col : view.columns_layout_->GetChildren())
1538+ {
1539+ int expected_cats = model->categories_per_column();
1540+
1541+ if (expected_cats > int(model->categories().size()) ||
1542+ added_cats == (expected_columns - 1) * model->categories_per_column)
1543+ {
1544+ expected_cats = model->categories().size() - added_cats;
1545+ }
1546+
1547+ ASSERT_EQ(dynamic_cast<nux::Layout*>(col)->GetChildren().size(), expected_cats);
1548+ added_cats += expected_cats;
1549+ }
1550+ }
1551+}
1552+
1553+TEST_F(TestShortcutView, CategoryHasSeparator)
1554+{
1555+ auto model = GetMockModel({"Cat1", "Cat2", "Cat3", "Cat4", "Cat5"}, 1);
1556+ model->categories_per_column = std::numeric_limits<int>::max();
1557+ view.SetModel(model);
1558+
1559+ for (unsigned i = 1; i <= model->categories().size(); ++i)
1560+ {
1561+ model->categories_per_column = i;
1562+
1563+ for (auto col : view.columns_layout_->GetChildren())
1564+ {
1565+ auto column = dynamic_cast<nux::Layout*>(col);
1566+
1567+ for (auto section : column->GetChildren())
1568+ {
1569+ unsigned found_separators = 0;
1570+ for (auto item : dynamic_cast<nux::Layout*>(section)->GetChildren())
1571+ if (dynamic_cast<HSeparator*>(item))
1572+ ++found_separators;
1573+
1574+ ASSERT_EQ(found_separators, section != column->GetChildren().back() ? 1 : 0);
1575+ }
1576+ }
1577+
1578+ }
1579+}
1580+
1581+TEST_F(TestShortcutView, QueueRelayoutOnHintChange)
1582+{
1583+ auto model = GetMockModel({"Cat"}, 1);
1584+ view.SetModel(model);
1585+
1586+ // Removing any queued relayout from WT, so that we can check if we queue a new one
1587+ nux::GetWindowThread()->RemoveObjectFromLayoutQueue(&view);
1588+ ASSERT_FALSE(nux::GetWindowThread()->RemoveObjectFromLayoutQueue(&view));
1589+
1590+ // Changing a shortkey should queue a relayout
1591+ model->hints().at("Cat").front()->shortkey.changed.emit("New Key!");
1592+ EXPECT_TRUE(nux::GetWindowThread()->RemoveObjectFromLayoutQueue(&view));
1593+}
1594+
1595+TEST_F(TestShortcutView, HintSignalsDisconnectedOnCleanup)
1596+{
1597+ AbstractHint::Ptr hint;
1598+ {
1599+ MockShortcutView mock_view;
1600+ mock_view.SetModel(GetMockModel({"Cat"}, 1));
1601+ hint = mock_view.GetModel()->hints().at("Cat").front();
1602+ ASSERT_FALSE(hint->shortkey.changed.empty());
1603+ }
1604+
1605+ ASSERT_TRUE(hint->shortkey.changed.empty());
1606+ hint->shortkey.changed.emit("New Key!");
1607+}
1608+
1609+TEST_F(TestShortcutView, HintSignalsDisconnectedOnModelReplace)
1610+{
1611+ AbstractHint::Ptr hint;
1612+ view.SetModel(GetMockModel({"Cat"}, 1));
1613+ hint = view.GetModel()->hints().at("Cat").front();
1614+ ASSERT_FALSE(hint->shortkey.changed.empty());
1615+
1616+ // Replacing the model with a new one
1617+ view.SetModel(GetMockModel({"Cat"}, 1));
1618+
1619+ ASSERT_TRUE(hint->shortkey.changed.empty());
1620+ hint->shortkey.changed.emit("New Key!");
1621+}
1622+
1623+}
1624+}
1625
1626=== modified file 'tests/test_uscreen_mock.h'
1627--- tests/test_uscreen_mock.h 2012-11-23 02:11:55 +0000
1628+++ tests/test_uscreen_mock.h 2013-01-21 21:26:21 +0000
1629@@ -79,6 +79,15 @@
1630 changed.emit(primary_, monitors_);
1631 }
1632 }
1633+
1634+ void SetMonitors(std::vector<nux::Geometry> const& monitors)
1635+ {
1636+ if (!std::equal(monitors_.begin(), monitors_.end(), monitors.begin()))
1637+ {
1638+ monitors_ = monitors;
1639+ changed.emit(primary_, monitors_);
1640+ }
1641+ }
1642 };
1643
1644 }