summaryrefslogtreecommitdiff
diff options
-rw-r--r--launcher/SwitcherController.cpp104
-rw-r--r--launcher/SwitcherControllerImpl.h9
-rw-r--r--launcher/SwitcherView.cpp118
-rw-r--r--launcher/SwitcherView.h16
-rw-r--r--tests/autopilot/unity/emulators/switcher.py14
-rw-r--r--tests/autopilot/unity/tests/test_switcher.py67
-rw-r--r--unity-shared/AbstractIconRenderer.h16
-rw-r--r--unity-shared/LayoutSystem.cpp10
-rw-r--r--unity-shared/LayoutSystem.h9
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