summaryrefslogtreecommitdiff
path: root/launcher
diff options
authorMarco Trevisan (TreviƱo) <mail@3v1n0.net>2013-11-21 16:06:58 +0000
committerTarmac <>2013-11-21 16:06:58 +0000
commit8e0868523fee70ac29bf7a9a3f25a7c75bf5317f (patch)
tree1e67a8392c75602b20dca0bd801a26dde9fd6a7b /launcher
parent4a7655cf6a14d050a1e6c4ef64e001a2c1cfcced (diff)
parent9096dfeddc269fba8adaf6ca9ccd3265c727245c (diff)
SwitcherView: define a custom GeometryGetterFunc and notify helper on changes
Thanks to this the switcher won't make BackgroundEffectHelper to create a blurred area as big as the current monitor (with just a small padding), but an area big enough to draw its background. This get updated automagically when the switcher view changes its geometry... Also, use nux::AnimateValue for switcher animations, making compiz to orchestrate it and only redraw the view if an icon changed since the last progress iteration. We don't want the switcher to be drawn unless its geometry or an icon changes. Also we don't want to redraw the switcher multiple times if only a not-animated parameter of an icon (such as a pip or the selection glow) has changed. As bonus, reduce lots of list copies. Approved by Christopher Townsend, PS Jenkins bot. (bzr r3601)
Diffstat (limited to 'launcher')
-rw-r--r--launcher/SwitcherController.cpp14
-rw-r--r--launcher/SwitcherView.cpp134
-rw-r--r--launcher/SwitcherView.h22
3 files changed, 86 insertions, 84 deletions
diff --git a/launcher/SwitcherController.cpp b/launcher/SwitcherController.cpp
index 4808b7634..0ff72b203 100644
--- a/launcher/SwitcherController.cpp
+++ b/launcher/SwitcherController.cpp
@@ -615,20 +615,10 @@ void Controller::Impl::InitiateDetail(bool animate)
if (!model_->detail_selection)
{
- view_->animate = animate;
-
SetDetail(true);
- if (!view_->animate())
- {
- // As soon as the detail selection is changed we re-enable the animations
- auto conn = std::make_shared<sigc::connection>();
- *conn = model_->detail_selection.changed.connect([this, conn] (bool) {
- if (view_)
- view_->animate = true;
- conn->disconnect();
- });
- }
+ if (!animate)
+ view_->SkipAnimation();
}
}
diff --git a/launcher/SwitcherView.cpp b/launcher/SwitcherView.cpp
index eb75a37d9..08376ac74 100644
--- a/launcher/SwitcherView.cpp
+++ b/launcher/SwitcherView.cpp
@@ -19,6 +19,8 @@
#include "config.h"
#include "MultiMonitor.h"
#include "SwitcherView.h"
+
+#include "unity-shared/AnimationUtils.h"
#include "unity-shared/IconRenderer.h"
#include "unity-shared/TimeUtil.h"
#include "unity-shared/UScreen.h"
@@ -45,7 +47,6 @@ NUX_IMPLEMENT_OBJECT_TYPE(SwitcherView);
SwitcherView::SwitcherView()
: render_boxes(false)
- , animate(true)
, border_size(50)
, flat_spacing(20)
, icon_size(128)
@@ -58,6 +59,7 @@ SwitcherView::SwitcherView()
, spread_size(3.5f)
, icon_renderer_(std::make_shared<IconRenderer>())
, text_view_(new StaticCairoText(""))
+ , animation_(animation_length)
, last_icon_selected_(-1)
, last_detail_icon_selected_(-1)
, check_mouse_first_time_(true)
@@ -81,20 +83,16 @@ SwitcherView::SwitcherView()
CaptureMouseDownAnyWhereElse(true);
SetAcceptMouseWheelEvent(true);
- ResetTimer();
- animate.changed.connect([this] (bool enabled) {
- if (enabled)
- {
- SaveTime();
- QueueRelayout();
- QueueDraw();
- }
- else
- {
- ResetTimer();
- }
+ SetBackgroundHelperGeometryGetter([this] {
+ // XXX: remove me when switcher will have a proper BaseWindow
+ auto geo = GetAbsoluteGeometry();
+ geo.OffsetPosition(blur_geometry_.x, blur_geometry_.y);
+ geo.SetSize(blur_geometry_.width, blur_geometry_.height);
+ return geo;
});
+
+ animation_.updated.connect(sigc::hide(sigc::mem_fun(this, &SwitcherView::PreLayoutManagement)));
}
std::string SwitcherView::GetName() const
@@ -177,15 +175,14 @@ void SwitcherView::OnTileSizeChanged (int size)
vertical_size = tile_size + VERTICAL_PADDING * 2;
}
-void SwitcherView::SaveTime()
+void SwitcherView::StartAnimation()
{
- clock_gettime(CLOCK_MONOTONIC, &save_time_);
+ animation::Start(animation_, animation::Direction::FORWARD);
}
-void SwitcherView::ResetTimer()
+void SwitcherView::SkipAnimation()
{
- save_time_.tv_sec = 0;
- save_time_.tv_nsec = 0;
+ animation::Skip(animation_);
}
void SwitcherView::SaveLast()
@@ -193,14 +190,12 @@ void SwitcherView::SaveLast()
saved_args_ = last_args_;
saved_background_ = last_background_;
- if (animate())
- SaveTime();
+ StartAnimation();
}
void SwitcherView::OnDetailSelectionIndexChanged(unsigned int index)
{
QueueRelayout();
- QueueDraw();
}
void SwitcherView::OnDetailSelectionChanged(bool detail)
@@ -217,8 +212,6 @@ void SwitcherView::OnDetailSelectionChanged(bool detail)
}
SaveLast();
- QueueRelayout();
- QueueDraw();
}
void SwitcherView::OnSelectionChanged(AbstractLauncherIcon::Ptr const& selection)
@@ -229,8 +222,6 @@ void SwitcherView::OnSelectionChanged(AbstractLauncherIcon::Ptr const& selection
delta_tracker_.ResetState();
SaveLast();
- QueueRelayout();
- QueueDraw();
}
nux::Point CalculateMouseMonitorOffset(int x, int y)
@@ -698,13 +689,12 @@ void GetFlatIconPositions (int n_flat_icons,
}
}
-std::list<RenderArg> SwitcherView::RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress)
+bool SwitcherView::RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress)
{
- std::list<RenderArg> results;
+ bool any_changed = true;
+ last_args_.clear();
nux::Geometry const& base = GetGeometry();
- bool detail_selection = model_->detail_selection;
-
background_geo.y = base.y + base.height / 2 - (vertical_size / 2);
background_geo.height = vertical_size;
@@ -713,6 +703,7 @@ std::list<RenderArg> SwitcherView::RenderArgsFlat(nux::Geometry& background_geo,
if (model_)
{
+ bool detail_selection = model_->detail_selection;
int size = model_->Size();
int padded_tile_size = tile_size + flat_spacing * 2;
int max_width = base.width - border_size * 2;
@@ -764,6 +755,8 @@ std::list<RenderArg> SwitcherView::RenderArgsFlat(nux::Geometry& background_geo,
int i = 0;
int y = base.y + base.height / 2;
x += border_size;
+ auto& results = last_args_;
+
for (auto const& icon : *model_)
{
RenderArg arg = CreateBaseArgForIcon(icon);
@@ -823,40 +816,71 @@ std::list<RenderArg> SwitcherView::RenderArgsFlat(nux::Geometry& background_geo,
++i;
}
- if (saved_args_.size () == results.size () && progress < 1.0f)
+ if (background_geo != blur_geometry_)
+ {
+ /* Update the blurred area geometry only if the final background is
+ * bigger than the previous blur geometry or if we've finished the
+ * animation; in this way we update the blurred area before growing
+ * and after that we've resized the view to the smaller size */
+ if ((background_geo.width >= blur_geometry_.width &&
+ background_geo.height >= blur_geometry_.height) || progress >= 1.0f)
+ {
+ blur_geometry_ = background_geo;
+
+ // Notify BackgroundEffectHelper
+ geometry_changed.emit(this, blur_geometry_);
+ }
+ }
+
+ bool result_size_changed = (saved_args_.size() != results.size());
+ any_changed = result_size_changed;
+
+ if (!result_size_changed && progress < 1.0f)
{
- std::list<RenderArg> end = results;
- results.clear();
+ auto& end = results;
- std::list<RenderArg>::iterator start_it, end_it;
- for (start_it = saved_args_.begin(), end_it = end.begin(); start_it != saved_args_.end(); ++start_it, ++end_it)
+ for (auto start_it = saved_args_.begin(), end_it = end.begin(); start_it != saved_args_.end(); ++start_it, ++end_it)
{
- results.push_back(InterpolateRenderArgs(*start_it, *end_it, progress));
+ if (*start_it != *end_it)
+ {
+ any_changed = true;
+
+ if (start_it->render_center == end_it->render_center &&
+ start_it->rotation == end_it->rotation)
+ {
+ /* If a value that we don't animate has changed, we only care about
+ * redrawing the icons once, so we return true here, but we also
+ * update the saved RenderArg so that next time this function
+ * will be called, we don't consider it changed (unless reprocessed). */
+ *start_it = *end_it;
+ continue;
+ }
+
+ *end_it = InterpolateRenderArgs(*start_it, *end_it, progress);
+ }
}
background_geo = InterpolateBackground(saved_background_, background_geo, progress);
}
}
- return results;
-}
-
-double SwitcherView::GetCurrentProgress()
-{
- clock_gettime(CLOCK_MONOTONIC, &current_);
- DeltaTime ms_since_change = TimeUtil::TimeDelta(&current_, &save_time_);
- return std::min<double>(1.0f, ms_since_change / static_cast<double>(animation_length()));
+ return any_changed;
}
void SwitcherView::PreLayoutManagement()
{
UnityWindowView::PreLayoutManagement();
- double progress = GetCurrentProgress();
+ double progress = animation_.GetCurrentValue();
nux::Geometry background_geo;
- last_args_ = RenderArgsFlat(background_geo, model_->SelectionIndex(), progress);
- last_background_ = background_geo;
+ bool any_changed = RenderArgsFlat(background_geo, model_ ? model_->SelectionIndex() : 0, progress);
+
+ if (background_geo != last_background_ || any_changed)
+ {
+ last_background_ = background_geo;
+ QueueDraw();
+ }
}
void SwitcherView::PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw)
@@ -869,6 +893,11 @@ nux::Geometry SwitcherView::GetBackgroundGeometry()
return last_background_;
}
+nux::Geometry SwitcherView::GetBlurredBackgroundGeometry()
+{
+ return blur_geometry_;
+}
+
void SwitcherView::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip)
{
nux::Geometry const& base = GetGeometry();
@@ -876,7 +905,6 @@ void SwitcherView::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw,
GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
-
for (auto const& arg : last_args_)
{
if (text_view_->IsVisible() && model_->Selection() == arg.icon)
@@ -929,18 +957,6 @@ void SwitcherView::DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw,
text_view_->Draw(GfxContext, force_draw);
nux::GetPainter().PopPaintLayerStack();
}
-
- DeltaTime ms_since_change = TimeUtil::TimeDelta(&current_, &save_time_);
-
- if (ms_since_change < animation_length && !redraw_idle_)
- {
- redraw_idle_.reset(new glib::Idle([this] () {
- QueueRelayout();
- QueueDraw();
- redraw_idle_.reset();
- return false;
- }, glib::Source::Priority::DEFAULT));
- }
}
int SwitcherView::IconIndexAt(int x, int y) const
diff --git a/launcher/SwitcherView.h b/launcher/SwitcherView.h
index 0c90b9436..2d09e01c3 100644
--- a/launcher/SwitcherView.h
+++ b/launcher/SwitcherView.h
@@ -30,10 +30,9 @@
#include "unity-shared/UnityWindowView.h"
#include <Nux/View.h>
+#include <NuxCore/Animation.h>
#include <NuxCore/Property.h>
-#include <UnityCore/GLibSource.h>
-
namespace unity
{
@@ -58,7 +57,6 @@ public:
SwitcherModel::Ptr GetModel();
nux::Property<bool> render_boxes;
- nux::Property<bool> animate;
nux::Property<int> border_size;
nux::Property<int> flat_spacing;
nux::Property<int> icon_size;
@@ -70,6 +68,8 @@ public:
nux::Property<int> monitor;
nux::Property<double> spread_size;
+ void SkipAnimation();
+
// Returns the index of the icon at the given position, in window coordinates.
// If there's no icon there, -1 is returned.
int IconIndexAt(int x, int y) const;
@@ -99,12 +99,14 @@ protected:
void PreDraw(nux::GraphicsEngine& GfxContext, bool force_draw);
void DrawOverlay(nux::GraphicsEngine& GfxContext, bool force_draw, nux::Geometry const& clip);
+
nux::Geometry GetBackgroundGeometry();
+ nux::Geometry GetBlurredBackgroundGeometry();
ui::RenderArg InterpolateRenderArgs(ui::RenderArg const& start, ui::RenderArg const& end, float progress);
nux::Geometry InterpolateBackground(nux::Geometry const& start, nux::Geometry const& end, float progress);
- std::list<ui::RenderArg> RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress);
+ bool RenderArgsFlat(nux::Geometry& background_geo, int selection, float progress);
ui::RenderArg CreateBaseArgForIcon(launcher::AbstractLauncherIcon::Ptr const& icon);
@@ -142,10 +144,7 @@ private:
nux::Size SpreadSize();
- double GetCurrentProgress();
-
- void SaveTime();
- void ResetTimer();
+ void StartAnimation();
void SaveLast();
bool CheckMouseInsideBackground(int x, int y) const;
@@ -155,6 +154,7 @@ private:
ui::LayoutSystem layout_system_;
ui::AbstractIconRenderer::Ptr icon_renderer_;
nux::ObjectPtr<StaticCairoText> text_view_;
+ nux::animation::AnimateValue<double> animation_;
int last_icon_selected_;
int last_detail_icon_selected_;
@@ -167,14 +167,10 @@ private:
nux::Geometry last_background_;
nux::Geometry saved_background_;
+ nux::Geometry blur_geometry_;
ui::LayoutWindow::Vector render_targets_;
- timespec current_;
- timespec save_time_;
-
- glib::Source::UniquePtr redraw_idle_;
-
friend class TestSwitcherView;
};