diff options
| author | Brandon Schaefer <brandon.schaefer@canonical.com> | 2013-07-17 14:54:34 -0700 |
|---|---|---|
| committer | Brandon Schaefer <brandon.schaefer@canonical.com> | 2013-07-17 14:54:34 -0700 |
| commit | ada86a00d73f60511f1b6035a62e495d00caba5c (patch) | |
| tree | 69f4be8c6e1f082d0dacec4d9727c77d825ffa1f | |
| parent | 9f9e10aa844376ca10a30eadbe3bbe24b4dab7eb (diff) | |
* Move logic from SwitcherController -> SwitcherView
* Mouse will only change the selected icon when it hits a different icon then it hit last. - This means if you hightlight icon 0, then use the keyboard to move the selection over, the mouse will not steal selection until it hits a new icon. * Added AP tests for normal icon mouse movement (bzr r3426.1.3)
| -rw-r--r-- | launcher/SwitcherController.cpp | 104 | ||||
| -rw-r--r-- | launcher/SwitcherControllerImpl.h | 9 | ||||
| -rw-r--r-- | launcher/SwitcherView.cpp | 118 | ||||
| -rw-r--r-- | launcher/SwitcherView.h | 16 | ||||
| -rw-r--r-- | tests/autopilot/unity/emulators/switcher.py | 14 | ||||
| -rw-r--r-- | tests/autopilot/unity/tests/test_switcher.py | 67 | ||||
| -rw-r--r-- | unity-shared/AbstractIconRenderer.h | 16 | ||||
| -rw-r--r-- | unity-shared/LayoutSystem.cpp | 10 | ||||
| -rw-r--r-- | unity-shared/LayoutSystem.h | 9 |
9 files changed, 252 insertions, 111 deletions
diff --git a/launcher/SwitcherController.cpp b/launcher/SwitcherController.cpp index a6755c0e6..7fd423766 100644 --- a/launcher/SwitcherController.cpp +++ b/launcher/SwitcherController.cpp @@ -430,7 +430,6 @@ void Controller::Impl::ConstructWindow() main_layout_->SetHorizontalExternalMargin(0); view_window_ = create_window_(); - view_window_->SetOpacity(0.0f); view_window_->SetLayout(main_layout_); view_window_->SetBackgroundColor(nux::color::Transparent); @@ -451,8 +450,9 @@ void Controller::Impl::ConstructView() view_->background_color = bg_color_; view_->monitor = obj_->monitor_; - view_->mouse_move.connect(sigc::mem_fun(this, &Controller::Impl::RecvMouseMove)); - view_->mouse_up.connect(sigc::mem_fun(this, &Controller::Impl::RecvMouseUp)); + view_->hide_request.connect ([this] (bool activate) { Hide(activate); }); + view_->right_clicked_icon.connect ([this] (int /*icon_index*/) { InitiateDetail(true); }); + view_->mouse_moving_over_icon.connect([this] (int /*icon_index*/) { ResetDetailTimer(); }); ConstructWindow(); main_layout_->AddView(view_.GetPointer(), 1); @@ -460,102 +460,6 @@ void Controller::Impl::ConstructView() view_window_->SetGeometry(workarea_); view_built.emit(); - -} - -void Controller::Impl::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) -{ - if (model_->detail_selection) - { - HandleDetailMouseMove(x, y); - } - else - { - HandleMouseMove(x, y); - } -} - -void Controller::Impl::HandleDetailMouseMove(int x, int y) -{ - int detail_icon_index = view_->DetailIconIdexAt(x, y); - int icon_index = view_->IconIndexAt(x, y); - - // We are over a different application icon - if (icon_index != model_->SelectionIndex() && icon_index >= 0) - { - model_->detail_selection = false; - } - else if (detail_icon_index >= 0) - { - model_->detail_selection_index = detail_icon_index; - } -} - -void Controller::Impl::HandleMouseMove(int x, int y) -{ - int icon_index = view_->IconIndexAt(x, y); - - if (icon_index >= 0) - { - if (icon_index != model_->SelectionIndex()) - { - model_->Select(icon_index); - } - else - { - ResetDetailTimer(); - } - } -} - -void Controller::Impl::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) -{ - int button = nux::GetEventButton(button_flags); - - if (model_->detail_selection) - { - HandleDetailMouseUp(x, y, button); - } - else - { - HandleMouseUp(x, y, button); - } -} - -void Controller::Impl::HandleDetailMouseUp(int x, int y, int button) -{ - int detail_icon_index = view_->DetailIconIdexAt(x, y); - - if (button == 1) - { - if (detail_icon_index >= 0) - { - model_->detail_selection_index = detail_icon_index; - Hide(true); - } - } - else if (button == 3) - { - model_->detail_selection = false; - } -} - -void Controller::Impl::HandleMouseUp(int x, int y, int button) -{ - int icon_index = view_->IconIndexAt(x,y); - - if (button == 1) - { - if (icon_index >= 0) - { - model_->Select(icon_index); - Hide(true); - } - } - else if (button == 3) - { - InitiateDetail(true); - } } void Controller::Impl::Hide(bool accept_state) @@ -678,7 +582,7 @@ void Controller::Impl::SetDetail(bool value, unsigned int min_windows) obj_->detail_mode_ = DetailMode::TAB_NEXT_WINDOW; } else - { + { model_->detail_selection = false; } } diff --git a/launcher/SwitcherControllerImpl.h b/launcher/SwitcherControllerImpl.h index 509e63745..e46279048 100644 --- a/launcher/SwitcherControllerImpl.h +++ b/launcher/SwitcherControllerImpl.h @@ -87,15 +87,6 @@ struct Controller::Impl void OnModelSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& icon); void OnBackgroundUpdate(GVariant* data); - - void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); - void HandleDetailMouseMove(int x, int y); - void HandleMouseMove(int x, int y); - - void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); - void HandleDetailMouseUp(int x, int y, int button); - void HandleMouseUp(int x, int y, int button); - unsigned int construct_timeout_; Controller* obj_; diff --git a/launcher/SwitcherView.cpp b/launcher/SwitcherView.cpp index 5862c7256..f925ce5eb 100644 --- a/launcher/SwitcherView.cpp +++ b/launcher/SwitcherView.cpp @@ -69,6 +69,9 @@ SwitcherView::SwitcherView() icon_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnIconSizeChanged)); tile_size.changed.connect (sigc::mem_fun (this, &SwitcherView::OnTileSizeChanged)); + mouse_move.connect(sigc::mem_fun(this, &SwitcherView::RecvMouseMove)); + mouse_up.connect (sigc::mem_fun(this, &SwitcherView::RecvMouseUp)); + CaptureMouseDownAnyWhereElse(true); ResetTimer(); @@ -104,9 +107,33 @@ void SwitcherView::AddProperties(GVariantBuilder* builder) .add("animation-length", animation_length) .add("spread-size", (float)spread_size) .add("label", text_view_->GetText()) + .add("spread_offset", SPREAD_OFFSET) .add("label_visible", text_view_->IsVisible()); } +debug::Introspectable::IntrospectableList SwitcherView::GetIntrospectableChildren() +{ + introspection_results_.clear(); + + if (model_->detail_selection) + { + for (auto target : render_targets_) + { + // FIXME When a LayoutWindow is introspectable, it no longer renders :( + //introspection_results_.push_back(target.get()); + } + } + else if (!last_args_.empty()) + { + for (auto& args : last_args_) + { + introspection_results_.push_back(&args); + } + } + + return introspection_results_; +} + LayoutWindow::Vector SwitcherView::ExternalTargets () { return render_targets_; @@ -187,6 +214,97 @@ void SwitcherView::OnSelectionChanged(AbstractLauncherIcon::Ptr const& selection QueueDraw(); } +void SwitcherView::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) +{ + if (model_->detail_selection) + { + HandleDetailMouseMove(x, y); + } + else + { + HandleMouseMove(x, y); + } +} + +void SwitcherView::HandleDetailMouseMove(int x, int y) +{ + static int last_selected_icon = -1; + int detail_icon_index = DetailIconIdexAt(x, y); + + if (detail_icon_index >= 0 && detail_icon_index != last_selected_icon) + { + model_->detail_selection_index = detail_icon_index; + last_selected_icon = detail_icon_index; + } +} + +void SwitcherView::HandleMouseMove(int x, int y) +{ + static int last_selected_icon = -1; + int icon_index = IconIndexAt(x, y); + + if (icon_index >= 0 && icon_index != last_selected_icon) + { + if (icon_index != model_->SelectionIndex()) + { + model_->Select(icon_index); + } + + mouse_moving_over_icon.emit(icon_index); + last_selected_icon = icon_index; + } +} + +void SwitcherView::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + int button = nux::GetEventButton(button_flags); + + if (model_->detail_selection) + { + HandleDetailMouseUp(x, y, button); + } + else + { + HandleMouseUp(x, y, button); + } +} + +void SwitcherView::HandleDetailMouseUp(int x, int y, int button) +{ + int detail_icon_index = DetailIconIdexAt(x, y); + + if (button == 1) + { + if (detail_icon_index >= 0) + { + model_->detail_selection_index = detail_icon_index; + hide_request.emit(true); + } + } + else if (button == 3) + { + model_->detail_selection = false; + } +} + +void SwitcherView::HandleMouseUp(int x, int y, int button) +{ + int icon_index = IconIndexAt(x,y); + + if (button == 1) + { + if (icon_index >= 0) + { + model_->Select(icon_index); + hide_request.emit(true); + } + } + else if (button == 3) + { + right_clicked_icon.emit(icon_index); + } +} + SwitcherModel::Ptr SwitcherView::GetModel() { return model_; diff --git a/launcher/SwitcherView.h b/launcher/SwitcherView.h index 26ba80d44..e63a9e667 100644 --- a/launcher/SwitcherView.h +++ b/launcher/SwitcherView.h @@ -25,6 +25,7 @@ #include "unity-shared/StaticCairoText.h" #include "unity-shared/LayoutSystem.h" #include "unity-shared/BackgroundEffectHelper.h" +#include "unity-shared/Introspectable.h" #include "unity-shared/UnityWindowView.h" #include <Nux/View.h> @@ -73,10 +74,15 @@ public: int IconIndexAt(int x, int y) const; int DetailIconIdexAt(int x, int y) const; + sigc::signal<void, int> right_clicked_icon; + sigc::signal<void, int> mouse_moving_over_icon; + sigc::signal<void, bool> hide_request; + protected: // Introspectable methods std::string GetName() const; void AddProperties(GVariantBuilder* builder); + IntrospectableList GetIntrospectableChildren(); void PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw); void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip); @@ -88,7 +94,15 @@ protected: std::list<ui::RenderArg> RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress); ui::RenderArg CreateBaseArgForIcon(launcher::AbstractLauncherIcon::Ptr const& icon); + private: + void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + void HandleDetailMouseMove(int x, int y); + void HandleMouseMove(int x, int y); + + void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); + void HandleDetailMouseUp(int x, int y, int button); + void HandleMouseUp(int x, int y, int button); void OnSelectionChanged(launcher::AbstractLauncherIcon::Ptr const& selection); void OnDetailSelectionChanged (bool detail); @@ -112,6 +126,8 @@ private: void ResetTimer(); void SaveLast(); + std::list<unity::debug::Introspectable*> introspection_results_; + SwitcherModel::Ptr model_; ui::LayoutSystem layout_system_; ui::AbstractIconRenderer::Ptr icon_renderer_; diff --git a/tests/autopilot/unity/emulators/switcher.py b/tests/autopilot/unity/emulators/switcher.py index 3dcbd1b8e..38f74cdb7 100644 --- a/tests/autopilot/unity/emulators/switcher.py +++ b/tests/autopilot/unity/emulators/switcher.py @@ -234,6 +234,20 @@ class SwitcherController(UnityIntrospectionObject, KeybindingsHelper): class SwitcherView(UnityIntrospectionObject): """An emulator class for interacting with with SwitcherView.""" + @property + def icon_args(self): + return self.get_children_by_type(RenderArgs); + + @property + def detail_icons(self): + return self.get_children_by_type(LayoutWindow); + + +class RenderArgs(UnityIntrospectionObject): + """An emulator class for interacting with the RenderArgs class.""" + +class LayoutWindow(UnityIntrospectionObject): + """An emulator class for interacting with the LayoutWindows class.""" class SwitcherModel(UnityIntrospectionObject): """An emulator class for interacting with the SwitcherModel.""" diff --git a/tests/autopilot/unity/tests/test_switcher.py b/tests/autopilot/unity/tests/test_switcher.py index 3f77e0e81..29e86a159 100644 --- a/tests/autopilot/unity/tests/test_switcher.py +++ b/tests/autopilot/unity/tests/test_switcher.py @@ -512,3 +512,70 @@ class SwitcherWorkspaceTests(SwitcherTestCase): self.addCleanup(self.unity.switcher.terminate) self.assertThat(self.unity.switcher.visible, Eventually(Equals(False))) + +class SwitcherDetailsMouseTests(SwitcherTestCase): + """ Test the interactions with the mouse and the switcher. """ + + def setUp(self): + super(SwitcherDetailsMouseTests, self).setUp() + self.set_timeout_setting(False) + + def test_mouse_highlights_switcher_icons(self): + """ Tests that the mouse can hightlight all the switcher icons. """ + + self.process_manager.start_app("Character Map") + + self.unity.switcher.initiate() + self.addCleanup(self.unity.switcher.terminate) + + icon_args = self.unity.switcher.view.icon_args + offset = self.unity.switcher.view.spread_offset + icon_cords = [] + + # Must collect the cords before moving mouse + for args in icon_args: + x = args.logical_center_x + offset + y = args.logical_center_y + offset + icon_cords.append((x,y)) + + index = 0; + for cords in icon_cords: + self.mouse.move(cords[0], cords[1]) + self.assertThat(index, Equals(self.unity.switcher.selection_index)) + index += 1 + + def test_mouse_clicks_activate_icon(self): + """ + Opens 2 different applications, CharMap being opened before TextEditor. + Then we get the index of the CharMap, and click on it, asserting CharMap is focused. + """ + + char_win1, char_win2 = self.start_applications("Character Map", "Text Editor") + self.assertVisibleWindowStack([char_win2, char_win1]) + self.assertProperty(char_win1, is_focused=False) + + self.unity.switcher.initiate() + self.addCleanup(self.unity.switcher.terminate) + + index = self.unity.switcher.selection_index + offset = self.unity.switcher.view.spread_offset + + icon_arg = self.unity.switcher.view.icon_args[index] + x = icon_arg.logical_center_x + offset + y = icon_arg.logical_center_y + offset + self.mouse.move(x, y) + self.mouse.click() + + self.assertProperty(char_win1, is_focused=True) + + def test_mouse_highlights_switcher_deatil_icons_motion(self): + """ """ + + self.start_applications("Character Map", "Character Map", "Character Map") + + self.unity.switcher.initiate(SwitcherMode.DETAIL) + self.addCleanup(self.unity.switcher.terminate) + print self.unity.switcher.view.detail_icons + + + diff --git a/unity-shared/AbstractIconRenderer.h b/unity-shared/AbstractIconRenderer.h index abb9def0b..6bb7065c8 100644 --- a/unity-shared/AbstractIconRenderer.h +++ b/unity-shared/AbstractIconRenderer.h @@ -22,8 +22,11 @@ #include <Nux/Nux.h> +#include "Introspectable.h" #include "IconTextureSource.h" +#include <UnityCore/Variant.h> + namespace unity { namespace ui @@ -35,7 +38,7 @@ enum PipRenderStyle OVER_TILE, }; -class RenderArg +class RenderArg : public debug::Introspectable { public: RenderArg() @@ -91,6 +94,17 @@ public: bool colorify_background; int window_indicators; char shortcut_label; + +protected: + // Introspectable methods + std::string GetName() const { return "RenderArgs"; } + void AddProperties(GVariantBuilder* builder) + { + unity::variant::BuilderWrapper(builder) + .add("logical_center_x", logical_center.x) + .add("logical_center_y", logical_center.y) + .add("logical_center_z", logical_center.z); + } }; class AbstractIconRenderer diff --git a/unity-shared/LayoutSystem.cpp b/unity-shared/LayoutSystem.cpp index 611759250..7a15984bb 100644 --- a/unity-shared/LayoutSystem.cpp +++ b/unity-shared/LayoutSystem.cpp @@ -290,5 +290,15 @@ LayoutWindow::LayoutWindow(Window xid) } } +// Introspectable methods +std::string LayoutWindow::GetName() const +{ + return "LayoutSystem"; +} + +void LayoutWindow::AddProperties(GVariantBuilder* builder) +{ +} + } } diff --git a/unity-shared/LayoutSystem.h b/unity-shared/LayoutSystem.h index 68598b3d2..c10ba77d9 100644 --- a/unity-shared/LayoutSystem.h +++ b/unity-shared/LayoutSystem.h @@ -24,13 +24,15 @@ #include <sigc++/sigc++.h> #include <Nux/Nux.h> +#include "unity-shared/Introspectable.h" #include "unity-shared/WindowManager.h" namespace unity { namespace ui { -struct LayoutWindow +class LayoutWindow //: public debug::Introspectable//: public ui::UnityWindowView { +public: typedef std::shared_ptr<LayoutWindow> Ptr; typedef std::vector<LayoutWindow::Ptr> Vector; @@ -45,6 +47,11 @@ struct LayoutWindow bool selected; float aspect_ratio; float alpha; + +protected: + // Introspectable methods + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); }; class LayoutSystem |
