summaryrefslogtreecommitdiff
path: root/dash
diff options
authorManuel de la Pena <manuel@canonical.com>2013-05-06 13:57:14 +0200
committerManuel de la Pena <manuel@canonical.com>2013-05-06 13:57:14 +0200
commitae6ff369d9a9bbc475c3e755c58869ee75937748 (patch)
tree98d5263885b0590ace837979bd95a9385207cfad /dash
parent25c90fdef54fa888275bbe3d604dbf72bcceb7e2 (diff)
parentb0477dbe8dfe65756eec88b8e68824923d0d213f (diff)
Merged with libunity breackage.
(bzr r3263.2.24)
Diffstat (limited to 'dash')
-rw-r--r--dash/CMakeLists.txt6
-rwxr-xr-xdash/CoverflowResultView.cpp38
-rwxr-xr-xdash/CoverflowResultView.h2
-rw-r--r--dash/DashController.cpp9
-rw-r--r--dash/DashView.cpp490
-rw-r--r--dash/DashView.h52
-rw-r--r--dash/DashViewPrivate.cpp4
-rw-r--r--dash/DashViewPrivate.h4
-rw-r--r--dash/FilterAllButton.cpp1
-rw-r--r--dash/FilterBar.cpp17
-rw-r--r--dash/FilterBar.h1
-rw-r--r--dash/FilterExpanderLabel.cpp25
-rw-r--r--dash/FilterGenreWidget.cpp21
-rw-r--r--dash/FilterMultiRangeWidget.cpp16
-rw-r--r--dash/FilterRatingsButton.cpp2
-rw-r--r--dash/FilterRatingsWidget.cpp17
-rwxr-xr-xdash/LensView.cpp946
-rwxr-xr-xdash/PlacesGroup.cpp31
-rw-r--r--dash/PlacesGroup.h15
-rw-r--r--dash/PreviewStateMachine.cpp2
-rw-r--r--dash/PreviewStateMachine.h2
-rw-r--r--dash/ResultRenderer.cpp4
-rw-r--r--dash/ResultRenderer.h4
-rw-r--r--dash/ResultRendererHorizontalTile.cpp2
-rw-r--r--dash/ResultRendererHorizontalTile.h2
-rw-r--r--dash/ResultRendererTile.cpp21
-rw-r--r--dash/ResultRendererTile.h10
-rw-r--r--dash/ResultView.cpp84
-rw-r--r--dash/ResultView.h24
-rw-r--r--dash/ResultViewGrid.cpp180
-rw-r--r--dash/ResultViewGrid.h22
-rw-r--r--dash/ScopeBar.cpp (renamed from dash/LensBar.cpp)128
-rw-r--r--dash/ScopeBar.h (renamed from dash/LensBar.h)32
-rw-r--r--dash/ScopeBarIcon.cpp (renamed from dash/LensBarIcon.cpp)20
-rw-r--r--dash/ScopeBarIcon.h (renamed from dash/LensBarIcon.h)14
-rwxr-xr-xdash/ScopeView.cpp1106
-rw-r--r--dash/ScopeView.h (renamed from dash/LensView.h)108
-rw-r--r--dash/StandaloneDash.cpp4
-rw-r--r--dash/previews/ApplicationPreview.cpp18
-rw-r--r--dash/previews/DBusTestRunner.h1
-rw-r--r--dash/previews/LensDBusTestRunner.h19
-rw-r--r--dash/previews/MusicPaymentPreview.cpp4
-rw-r--r--dash/previews/MusicPaymentPreview.h1
-rw-r--r--dash/previews/MusicPreview.cpp37
-rw-r--r--dash/previews/MusicPreview.h4
-rw-r--r--dash/previews/PaymentPreview.cpp.moved368
-rw-r--r--dash/previews/PaymentPreview.h1
-rw-r--r--dash/previews/Preview.cpp9
-rw-r--r--dash/previews/StandaloneMusicPreview.cpp4
-rw-r--r--dash/previews/Track.cpp65
-rw-r--r--dash/previews/Track.h9
-rw-r--r--dash/previews/Tracks.cpp11
-rw-r--r--dash/previews/Tracks.h10
53 files changed, 2242 insertions, 1785 deletions
diff --git a/dash/CMakeLists.txt b/dash/CMakeLists.txt
index 31472f51c..af230a327 100644
--- a/dash/CMakeLists.txt
+++ b/dash/CMakeLists.txt
@@ -35,9 +35,9 @@ set (DASH_SOURCES
FilterMultiRangeWidget.cpp
FilterRatingsButton.cpp
FilterRatingsWidget.cpp
- LensBar.cpp
- LensBarIcon.cpp
- LensView.cpp
+ ScopeBar.cpp
+ ScopeBarIcon.cpp
+ ScopeView.cpp
PlacesGroup.cpp
PreviewStateMachine.cpp
ResultRenderer.cpp
diff --git a/dash/CoverflowResultView.cpp b/dash/CoverflowResultView.cpp
index fc696419e..3c9180ef5 100755
--- a/dash/CoverflowResultView.cpp
+++ b/dash/CoverflowResultView.cpp
@@ -66,8 +66,6 @@ public:
~Impl();
void ComputeFlatIcons();
- int GetIndexForUri(std::string uri);
- std::string GetUriForIndex(int index);
CoverflowResultView *parent_;
nux::Coverflow *coverflow_;
@@ -133,10 +131,10 @@ void CoverflowResultItem::Activate(int button)
//Left and right click take you to previews.
if (button == 1 || button == 3)
- parent_->Activate(result_.uri, index, ResultView::ActivateType::PREVIEW);
+ parent_->Activate(LocalResult(result_), index, ResultView::ActivateType::PREVIEW);
//Scroll click opens up music player.
else if (button == 2)
- parent_->Activate(result_.uri, index, ResultView::ActivateType::DIRECT);
+ parent_->Activate(LocalResult(result_), index, ResultView::ActivateType::DIRECT);
}
@@ -165,16 +163,18 @@ CoverflowResultView::Impl::Impl(CoverflowResultView *parent)
ubus_.RegisterInterest(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, [&] (GVariant* data) {
int nav_mode = 0;
- glib::String uri;
+ GVariant* local_result_variant = nullptr;
glib::String proposed_unique_id;
- g_variant_get(data, "(iss)", &nav_mode, &uri, &proposed_unique_id);
+ g_variant_get(data, "(ivs)", &nav_mode, &local_result_variant, &proposed_unique_id);
+ LocalResult local_result(LocalResult::FromVariant(local_result_variant));
+ g_variant_unref(local_result_variant);
if (proposed_unique_id.Str() != parent_->unique_id())
return;
unsigned num_results = coverflow_->model()->Items().size();
- int current_index = GetIndexForUri(uri);
+ int current_index = parent->GetIndexForLocalResult(local_result);
if (nav_mode == -1) // left
{
current_index--;
@@ -191,8 +191,7 @@ CoverflowResultView::Impl::Impl(CoverflowResultView *parent)
if (nav_mode)
{
- std::string uri = GetUriForIndex(current_index);
- parent_->Activate(uri, current_index, ActivateType::PREVIEW);
+ parent_->Activate(parent_->GetLocalResultForIndex(current_index), current_index, ActivateType::PREVIEW);
}
});
}
@@ -202,23 +201,6 @@ CoverflowResultView::Impl::~Impl()
}
-int CoverflowResultView::Impl::GetIndexForUri(std::string uri)
-{
- int i = 0;
- for (auto item : coverflow_->model()->Items())
- {
- if (uri == static_cast<CoverflowResultItem*>(item.GetPointer())->Uri())
- return i;
- i++;
- }
- return -1;
-}
-
-std::string CoverflowResultView::Impl::GetUriForIndex(int index)
-{
- return static_cast<CoverflowResultItem*>(coverflow_->model()->Items()[index].GetPointer())->Uri();
-}
-
CoverflowResultView::CoverflowResultView(NUX_FILE_LINE_DECL)
: ResultView(NUX_FILE_LINE_PARAM)
, pimpl(new CoverflowResultView::Impl(this))
@@ -296,7 +278,7 @@ long CoverflowResultView::ComputeContentSize()
}
-void CoverflowResultView::Activate(std::string const& uri, int index, ResultView::ActivateType type)
+void CoverflowResultView::Activate(LocalResult const& local_result, int index, ResultView::ActivateType type)
{
unsigned num_results = pimpl->coverflow_->model()->Items().size();
@@ -308,7 +290,7 @@ void CoverflowResultView::Activate(std::string const& uri, int index, ResultView
int column_width = GetWidth();
glib::Variant data(g_variant_new("(iiii)", column_x, row_y, column_width, row_height, left_results, right_results));
- UriActivated.emit(uri, type, data);
+ ResultActivated.emit(local_result, type, data);
}
diff --git a/dash/CoverflowResultView.h b/dash/CoverflowResultView.h
index d841d211c..c87017a37 100755
--- a/dash/CoverflowResultView.h
+++ b/dash/CoverflowResultView.h
@@ -40,7 +40,7 @@ public:
virtual void AddResult(Result& result);
virtual void RemoveResult(Result& result);
- virtual void Activate(std::string const& uri, int index, ActivateType type);
+ virtual void Activate(LocalResult const& local_result, int index, ActivateType type);
protected:
virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
diff --git a/dash/DashController.cpp b/dash/DashController.cpp
index cbd08d8e8..7c0635114 100644
--- a/dash/DashController.cpp
+++ b/dash/DashController.cpp
@@ -22,6 +22,7 @@
#include <NuxCore/Logger.h>
#include <Nux/HLayout.h>
#include <UnityCore/GLibWrapper.h>
+#include "UnityCore/GSettingsScopes.h"
#include "ApplicationStarterImp.h"
#include "unity-shared/DashStyle.h"
@@ -140,7 +141,7 @@ void Controller::SetupWindow()
void Controller::SetupDashView()
{
- view_ = new DashView(std::make_shared<FilesystemLenses>(), std::make_shared<ApplicationStarterImp>());
+ view_ = new DashView(std::make_shared<GSettingsScopes>(), std::make_shared<ApplicationStarterImp>());
AddChild(view_);
nux::HLayout* layout = new nux::HLayout(NUX_TRACKER_LOCATION);
@@ -411,14 +412,14 @@ void Controller::OnActivateRequest(GVariant* variant)
gboolean Controller::CheckShortcutActivation(const char* key_string)
{
EnsureDash();
- std::string lens_id = view_->GetIdForShortcutActivation(std::string(key_string));
- if (lens_id != "")
+ std::string scope_id = view_->GetIdForShortcutActivation(std::string(key_string));
+ if (scope_id != "")
{
WindowManager& wm = WindowManager::Default();
if (wm.IsScaleActive())
wm.TerminateScale();
- GVariant* args = g_variant_new("(sus)", lens_id.c_str(), dash::GOTO_DASH_URI, "");
+ GVariant* args = g_variant_new("(sus)", scope_id.c_str(), dash::GOTO_DASH_URI, "");
OnActivateRequest(args);
g_variant_unref(args);
return true;
diff --git a/dash/DashView.cpp b/dash/DashView.cpp
index 2db9f54ae..5f9d6488d 100644
--- a/dash/DashView.cpp
+++ b/dash/DashView.cpp
@@ -94,11 +94,9 @@ public:
{
SetRedirectRenderingToTexture(true);
}
- ~DashContentView() {}
void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
- {
- }
+ {}
void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
@@ -110,15 +108,13 @@ public:
NUX_IMPLEMENT_OBJECT_TYPE(DashView);
-DashView::DashView(Lenses::Ptr const& lenses, ApplicationStarter::Ptr const& application_starter)
+DashView::DashView(Scopes::Ptr const& scopes, ApplicationStarter::Ptr const& application_starter)
: nux::View(NUX_TRACKER_LOCATION)
- , lenses_(lenses)
- , home_lens_(new HomeLens(_("Home"), _("Home screen"), _("Search your computer and online sources")))
+ , scopes_(scopes)
, application_starter_(application_starter)
, preview_container_(nullptr)
, preview_displaying_(false)
, preview_navigation_mode_(previews::Navigation::NONE)
- , last_activated_uri_("")
, last_activated_timestamp_(0)
, search_in_progress_(false)
, activate_on_finish_(false)
@@ -142,35 +138,28 @@ DashView::DashView(Lenses::Ptr const& lenses, ApplicationStarter::Ptr const& app
AddChild(overlay_window_buttons_.GetPointer());
- lenses_->lens_added.connect(sigc::mem_fun(this, &DashView::OnLensAdded));
mouse_down.connect(sigc::mem_fun(this, &DashView::OnMouseButtonDown));
preview_state_machine_.PreviewActivated.connect(sigc::mem_fun(this, &DashView::BuildPreview));
Relayout();
- for (auto lens : lenses_->GetLenses())
- lenses_->lens_added.emit(lens);
-
- home_lens_->AddLenses(lenses_);
- lens_bar_->Activate("home.lens");
-
- // we will special case when applications lens finishes global search
- // because we want to be able to launch applications immediately
- // without waiting for the search finished signal which will
- // be delayed by all the lenses we're searching
- home_lens_->lens_search_finished.connect(sigc::mem_fun(this, &DashView::OnAppsGlobalSearchFinished));
-
// We are interested in the color of the desktop background.
ubus_manager_.RegisterInterest(UBUS_BACKGROUND_COLOR_CHANGED, sigc::mem_fun(this, &DashView::OnBGColorChanged));
// request the latest colour from bghash
ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
+ if (scopes_)
+ {
+ scopes_->scope_added.connect(sigc::mem_fun(this, &DashView::OnScopeAdded));
+ scopes_->LoadScopes();
+ }
}
DashView::~DashView()
{
+ scope_can_refine_connection_.disconnect();
// Do this explicitely, otherwise dee will complain about invalid access
- // to the lens models
+ // to the scope models
RemoveLayout();
}
@@ -191,12 +180,13 @@ void DashView::SetMonitorOffset(int x, int y)
bool DashView::IsCommandLensOpen() const
{
- return (lens_bar_->GetActiveLensId() == "commands.lens");
+ return (scope_bar_->GetActiveScopeId() == "commands.scope");
}
-void DashView::OnUriActivated(ResultView::ActivateType type, std::string const& uri, GVariant* data, std::string const& unique_id)
+
+void DashView::OnResultActivated(ResultView::ActivateType type, LocalResult const& local_result, GVariant* data, std::string const& unique_id)
{
- last_activated_uri_ = uri;
+ last_activated_result_ = local_result;
stored_activated_unique_id_ = unique_id;
if (data)
@@ -234,12 +224,12 @@ void DashView::BuildPreview(Preview::Ptr model)
StartPreviewAnimation();
content_view_->SetPresentRedirectedView(false);
- preview_lens_view_ = active_lens_view_;
- if (preview_lens_view_)
+ preview_scope_view_ = active_scope_view_;
+ if (preview_scope_view_)
{
- preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, true);
- preview_lens_view_->EnableResultTextures(true);
- preview_lens_view_->PushFilterExpansion(false);
+ preview_scope_view_->ForceCategoryExpansion(stored_activated_unique_id_, true);
+ preview_scope_view_->EnableResultTextures(true);
+ preview_scope_view_->PushFilterExpansion(false);
}
if (!preview_container_)
@@ -251,7 +241,7 @@ void DashView::BuildPreview(Preview::Ptr model)
}
preview_container_->Preview(model, previews::Navigation::NONE); // no swipe left or right
- preview_container_->SetGeometry(lenses_layout_->GetGeometry());
+ preview_container_->SetGeometry(scopes_layout_->GetGeometry());
preview_displaying_ = true;
// connect to nav left/right signals to request nav left/right movement.
@@ -260,7 +250,7 @@ void DashView::BuildPreview(Preview::Ptr model)
// sends a message to all result views, sending the the uri of the current preview result
// and the unique id of the result view that should be handling the results
- ubus_manager_.SendMessage(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, g_variant_new("(iss)", -1, last_activated_uri_.c_str(), stored_activated_unique_id_.c_str()));
+ ubus_manager_.SendMessage(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, g_variant_new("(ivs)", -1, g_variant_ref(last_activated_result_.Variant()), stored_activated_unique_id_.c_str()));
});
preview_container_->navigate_right.connect([&] () {
@@ -268,7 +258,7 @@ void DashView::BuildPreview(Preview::Ptr model)
// sends a message to all result views, sending the the uri of the current preview result
// and the unique id of the result view that should be handling the results
- ubus_manager_.SendMessage(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, g_variant_new("(iss)", 1, last_activated_uri_.c_str(), stored_activated_unique_id_.c_str()));
+ ubus_manager_.SendMessage(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, g_variant_new("(ivs)", 1, g_variant_ref(last_activated_result_.Variant()), stored_activated_unique_id_.c_str()));
});
preview_container_->request_close.connect([&] () { ClosePreview(); });
@@ -368,8 +358,8 @@ void DashView::StartPreviewAnimation()
preview_container_animation_->Start();
}
- if (preview_lens_view_)
- preview_lens_view_->SetResultsPreviewAnimationValue(animate_split_value_);
+ if (preview_scope_view_)
+ preview_scope_view_->SetResultsPreviewAnimationValue(animate_split_value_);
});
split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));
@@ -429,8 +419,8 @@ void DashView::EndPreviewAnimation()
split_animation_->finished.connect(sigc::mem_fun(this, &DashView::OnPreviewAnimationFinished));
split_animation_->Start();
- // if (preview_lens_view_)
- // preview_lens_view_->PopFilterExpansion();
+ // if (preview_scope_view_)
+ // preview_scope_view_->PopFilterExpansion();
}
});
@@ -459,14 +449,14 @@ void DashView::OnPreviewAnimationFinished()
}
// reset the saturation.
- if (preview_lens_view_.IsValid())
+ if (preview_scope_view_.IsValid())
{
- preview_lens_view_->SetResultsPreviewAnimationValue(0.0);
- preview_lens_view_->ForceCategoryExpansion(stored_activated_unique_id_, false);
- preview_lens_view_->EnableResultTextures(false);
- preview_lens_view_->PopFilterExpansion();
+ preview_scope_view_->SetResultsPreviewAnimationValue(0.0);
+ preview_scope_view_->ForceCategoryExpansion(stored_activated_unique_id_, false);
+ preview_scope_view_->EnableResultTextures(false);
+ preview_scope_view_->PopFilterExpansion();
}
- preview_lens_view_.Release();
+ preview_scope_view_.Release();
content_view_->SetPresentRedirectedView(true);
}
@@ -476,42 +466,25 @@ void DashView::AboutToShow()
visible_ = true;
search_bar_->text_entry()->SelectAll();
- /* Give the lenses a chance to prep data before we map them */
- lens_bar_->Activate(active_lens_view_->lens()->id());
- if (active_lens_view_)
- {
- active_lens_view_->SetVisible(true);
+ /* Give the scopes a chance to prep data before we map them */
+ if (active_scope_view_)
+ {
+ scope_bar_->Activate(active_scope_view_->scope()->id());
- if (active_lens_view_->lens()->id() == "home.lens")
- {
- for (auto lens : lenses_->GetLenses())
- {
- lens->view_type = ViewType::HOME_VIEW;
- LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HOME_VIEW
- << " on '" << lens->id() << "'";
- }
-
- home_lens_->view_type = ViewType::LENS_VIEW;
- LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW
- << " on '" << home_lens_->id() << "'";
- }
- else
- {
- // careful here, the lens_view's view_type doesn't get reset when the dash
- // hides, but lens' view_type does, so we need to update the lens directly
- active_lens_view_->lens()->view_type = ViewType::LENS_VIEW;
- }
+ active_scope_view_->SetVisible(true);
+ active_scope_view_->scope()->view_type = ScopeViewType::SCOPE_VIEW;
+
+ // this will make sure the spinner animates if the search takes a while
+ search_bar_->ForceLiveSearch();
}
- // this will make sure the spinner animates if the search takes a while
- search_bar_->ForceSearchChanged();
-
// if a preview is open, close it
if (preview_displaying_)
{
ClosePreview();
}
+
overlay_window_buttons_->Show();
renderer_.AboutToShow();
@@ -522,19 +495,18 @@ void DashView::AboutToHide()
visible_ = false;
renderer_.AboutToHide();
- for (auto lens : lenses_->GetLenses())
+ if (scopes_)
{
- lens->view_type = ViewType::HIDDEN;
- LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN
- << " on '" << lens->id() << "'";
+ for (auto scope : scopes_->GetScopes())
+ {
+ scope->view_type = ScopeViewType::HIDDEN;
+ LOG_DEBUG(logger) << "Setting ViewType " << ScopeViewType::HIDDEN
+ << " on '" << scope->id() << "'";
+ }
}
- home_lens_->view_type = ViewType::HIDDEN;
- LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN
- << " on '" << home_lens_->id() << "'";
-
- if (active_lens_view_.IsValid())
- active_lens_view_->SetVisible(false);
+ if (active_scope_view_.IsValid())
+ active_scope_view_->SetVisible(false);
// if a preview is open, close it
if (preview_displaying_)
@@ -576,30 +548,22 @@ void DashView::SetupViews()
search_bar_->live_search_reached.connect(sigc::mem_fun(this, &DashView::OnLiveSearchReached));
search_bar_->showing_filters.changed.connect([&] (bool showing)
{
- if (active_lens_view_)
+ if (active_scope_view_)
{
- active_lens_view_->filters_expanded = showing;
+ active_scope_view_->filters_expanded = showing;
QueueDraw();
}
});
search_bar_layout_->AddView(search_bar_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
content_layout_->SetSpecialArea(search_bar_->show_filters());
- lenses_layout_ = new nux::VLayout();
- content_layout_->AddLayout(lenses_layout_, 1, nux::MINOR_POSITION_START);
-
- home_view_ = new LensView(home_lens_, nullptr);
- home_view_->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));
+ scopes_layout_ = new nux::VLayout();
+ content_layout_->AddLayout(scopes_layout_, 1, nux::MINOR_POSITION_START);
- AddChild(home_view_.GetPointer());
- active_lens_view_ = home_view_;
- lens_views_[home_lens_->id] = home_view_;
- lenses_layout_->AddView(home_view_.GetPointer());
-
- lens_bar_ = new LensBar();
- AddChild(lens_bar_);
- lens_bar_->lens_activated.connect(sigc::mem_fun(this, &DashView::OnLensBarActivated));
- content_layout_->AddView(lens_bar_, 0, nux::MINOR_POSITION_CENTER);
+ scope_bar_ = new ScopeBar();
+ AddChild(scope_bar_);
+ scope_bar_->scope_activated.connect(sigc::mem_fun(this, &DashView::OnScopeBarActivated));
+ content_layout_->AddView(scope_bar_, 0, nux::MINOR_POSITION_CENTER);
}
void DashView::SetupUBusConnections()
@@ -623,8 +587,8 @@ void DashView::Relayout()
// kinda hacky, but it makes sure the content isn't so big that it throws
// the bottom of the dash off the screen
// not hugely happy with this, so FIXME
- lenses_layout_->SetMaximumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
- lenses_layout_->SetMinimumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - lens_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
+ scopes_layout_->SetMaximumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - scope_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
+ scopes_layout_->SetMinimumHeight (std::max(0, content_geo_.height - search_bar_->GetGeometry().height - scope_bar_->GetGeometry().height - style.GetDashViewTopPadding()));
layout_->SetMinMaxSize(content_geo_.width, content_geo_.y + content_geo_.height);
@@ -667,7 +631,7 @@ nux::Geometry DashView::GetBestFitGeometry(nux::Geometry const& for_geo)
height += style.GetDashViewTopPadding();
height += search_bar_->GetGeometry().height;
height += category_height * DASH_DEFAULT_CATEGORY_COUNT; // adding three categories
- height += lens_bar_->GetGeometry().height;
+ height += scope_bar_->GetGeometry().height;
// width/height shouldn't be bigger than the geo available.
width = std::min(width, for_geo.width); // launcher width is taken into account in for_geo.
@@ -733,7 +697,7 @@ void DashView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw
graphics_engine.PushClippingRectangle(geo_split_clip);
- if (preview_lens_view_.IsValid())
+ if (preview_scope_view_.IsValid())
{
DrawPreviewResultTextures(graphics_engine, force_draw);
}
@@ -755,8 +719,6 @@ void DashView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw
nux::GetPainter().PopBackgroundStack();
}
- overlay_window_buttons_->QueueDraw();
-
graphics_engine.PopClippingRectangle();
renderer_.DrawInnerCleanup(graphics_engine, content_geo_, renderer_geo_abs, renderer_geo);
@@ -780,29 +742,29 @@ void DashView::DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry
texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
texxform.FlipVCoord(true);
- // Lens Bar
- texxform.uoffset = (lens_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();
- texxform.voffset = (lens_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();
+ // Scope Bar
+ texxform.uoffset = (scope_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();
+ texxform.voffset = (scope_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();
- int start_y = lens_bar_->GetY();
+ int start_y = scope_bar_->GetY();
int final_y = geo_layout.y + geo_layout.height + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;
- int lens_y = (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y);
+ int scope_y = (1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y);
graphics_engine.QRP_1Tex
(
- lens_bar_->GetX(),
- lens_y,
- lens_bar_->GetWidth(),
- lens_bar_->GetHeight(),
+ scope_bar_->GetX(),
+ scope_y,
+ scope_bar_->GetWidth(),
+ scope_bar_->GetHeight(),
content_view_->BackupTexture(),
texxform,
nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))
);
- split_clip.height = std::min(lens_y, geo_layout.height);
+ split_clip.height = std::min(scope_y, geo_layout.height);
- if (active_lens_view_ && active_lens_view_->GetPushedFilterExpansion())
+ if (active_scope_view_ && active_scope_view_->GetPushedFilterExpansion())
{
// Search Bar
texxform.uoffset = (search_bar_->GetX() - content_view_->GetX())/(float)content_view_->GetWidth();
@@ -815,7 +777,7 @@ void DashView::DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry
(
search_bar_->GetX(),
(1.0f - animate_split_value_) * start_y + (animate_split_value_ * final_y),
- search_bar_->GetWidth() - active_lens_view_->filter_bar()->GetWidth(),
+ search_bar_->GetWidth() - active_scope_view_->filter_bar()->GetWidth(),
search_bar_->GetHeight(),
content_view_->BackupTexture(),
texxform,
@@ -823,10 +785,10 @@ void DashView::DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry
);
// Filter Bar
- texxform.uoffset = (active_lens_view_->filter_bar()->GetX() -content_view_->GetX())/(float)content_view_->GetWidth();
+ texxform.uoffset = (active_scope_view_->filter_bar()->GetX() -content_view_->GetX())/(float)content_view_->GetWidth();
texxform.voffset = (search_bar_->GetY() - content_view_->GetY())/(float)content_view_->GetHeight();
- int start_x = active_lens_view_->filter_bar()->GetX();
+ int start_x = active_scope_view_->filter_bar()->GetX();
int final_x = content_view_->GetX() + content_view_->GetWidth() + PREVIEW_ICON_SPLIT_OFFSCREEN_OFFSET;
int filter_x = (1.0f - animate_split_value_) * start_x + (animate_split_value_ * final_x);
@@ -835,8 +797,8 @@ void DashView::DrawDashSplit(nux::GraphicsEngine& graphics_engine, nux::Geometry
(
filter_x,
search_bar_->GetY(),
- active_lens_view_->filter_bar()->GetWidth(),
- active_lens_view_->filter_bar()->GetY() + active_lens_view_->filter_bar()->GetHeight(),
+ active_scope_view_->filter_bar()->GetWidth(),
+ active_scope_view_->filter_bar()->GetY() + active_scope_view_->filter_bar()->GetHeight(),
content_view_->BackupTexture(),
texxform,
nux::Color((1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_), (1.0-animate_split_value_))
@@ -953,7 +915,7 @@ void DashView::DrawPreviewResultTextures(nux::GraphicsEngine& graphics_engine, b
texxform.voffset = 0.0f;
texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
- std::vector<ResultViewTexture::Ptr> result_textures = preview_lens_view_->GetResultTextureContainers();
+ std::vector<ResultViewTexture::Ptr> result_textures = preview_scope_view_->GetResultTextureContainers();
std::vector<ResultViewTexture::Ptr> top_textures;
int height_concat_below = 0;
@@ -991,7 +953,7 @@ void DashView::DrawPreviewResultTextures(nux::GraphicsEngine& graphics_engine, b
// off the bottom
if (geo_tex_top.y <= geo_layout.y + geo_layout.height)
{
- preview_lens_view_->RenderResultTexture(result_texture);
+ preview_scope_view_->RenderResultTexture(result_texture);
// If we haven't got it now, we're not going to get it
if (!result_texture->texture.IsValid())
continue;
@@ -1032,7 +994,7 @@ void DashView::DrawPreviewResultTextures(nux::GraphicsEngine& graphics_engine, b
// off the top
if (geo_tex_top.y + geo_tex_top.height >= geo_layout.y)
{
- preview_lens_view_->RenderResultTexture(result_texture);
+ preview_scope_view_->RenderResultTexture(result_texture);
// If we haven't got it now, we're not going to get it
if (!result_texture->texture.IsValid())
continue;
@@ -1124,11 +1086,13 @@ void DashView::OnActivateRequest(GVariant* args)
{
glib::String uri;
glib::String search_string;
- dash::HandledType handled_type;
+ ScopeHandledType handled_type;
g_variant_get(args, "(sus)", &uri, &handled_type, &search_string);
- std::string id(AnalyseLensURI(uri.Str()));
+ std::string id(AnalyseScopeURI(uri.Str()));
+
+ LOG_DEBUG(logger) << "External activation request: " << id << " (uri: "<< uri.Str() << ")";
// we got an activation request, we should probably close the preview
if (preview_displaying_)
@@ -1136,45 +1100,48 @@ void DashView::OnActivateRequest(GVariant* args)
ClosePreview();
}
- if (!visible_)
- {
- lens_bar_->Activate(id);
- ubus_manager_.SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);
- }
- else if (/* visible_ && */ handled_type == NOT_HANDLED)
+ if (visible_ && handled_type == ScopeHandledType::NOT_HANDLED)
{
ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST, NULL,
- glib::Source::Priority::HIGH);
+ glib::Source::Priority::HIGH);
}
- else if (/* visible_ && */ handled_type == GOTO_DASH_URI)
- {
- lens_bar_->Activate(id);
+ else if (!visible_ || handled_type == ScopeHandledType::GOTO_DASH_URI)
+ {
+ if (!scopes_->GetScope(id))
+ {
+ // should trigger the addition of the scope.
+ scopes_->AppendScope(id);
+ }
+ scope_bar_->Activate(id);
+
+ if (!visible_)
+ ubus_manager_.SendMessage(UBUS_DASH_EXTERNAL_ACTIVATION);
}
}
-std::string DashView::AnalyseLensURI(std::string const& uri)
+std::string DashView::AnalyseScopeURI(std::string const& uri)
{
- impl::LensFilter filter = impl::parse_lens_uri(uri);
+ impl::ScopeFilter filter = impl::parse_scope_uri(uri);
if (!filter.filters.empty())
{
- lens_views_[filter.id]->filters_expanded = true;
- // update the lens for each filter
+ scope_views_[filter.id]->filters_expanded = true;
+ // update the scope for each filter
for (auto p : filter.filters) {
- UpdateLensFilter(filter.id, p.first, p.second);
+ UpdateScopeFilter(filter.id, p.first, p.second);
}
}
return filter.id;
}
-void DashView::UpdateLensFilter(std::string lens_id, std::string filter_name, std::string value)
+void DashView::UpdateScopeFilter(std::string scope_id, std::string filter_name, std::string value)
{
- if (lenses_->GetLens(lens_id))
+ if (scopes_ && scopes_->GetScope(scope_id))
{
- Lens::Ptr lens = lenses_->GetLens(lens_id);
+ Scope::Ptr scope = scopes_->GetScope(scope_id);
- Filters::Ptr filters = lens->filters;
+ Filters::Ptr filters = scope->filters;
for (unsigned int i = 0; i < filters->count(); ++i)
{
@@ -1182,13 +1149,13 @@ void DashView::UpdateLensFilter(std::string lens_id, std::string filter_name, st
if (filter->id() == filter_name)
{
- UpdateLensFilterValue(filter, value);
+ UpdateScopeFilterValue(filter, value);
}
}
}
}
-void DashView::UpdateLensFilterValue(Filter::Ptr filter, std::string value)
+void DashView::UpdateScopeFilterValue(Filter::Ptr filter, std::string value)
{
if (filter->renderer_name == "filter-radiooption")
{
@@ -1203,65 +1170,66 @@ void DashView::UpdateLensFilterValue(Filter::Ptr filter, std::string value)
void DashView::OnSearchChanged(std::string const& search_string)
{
- LOG_DEBUG(logger) << "Search changed: " << search_string;
- if (active_lens_view_)
- {
- search_in_progress_ = true;
- // it isn't guaranteed that we get a SearchFinished signal, so we need
- // FIXME: it is now actually!!
- // to make sure this isn't set even though we aren't doing any search
- // 250ms for the Search method call, rest for the actual search
- searching_timeout_.reset(new glib::Timeout(500, [&] () {
- search_in_progress_ = false;
- activate_on_finish_ = false;
- return false;
- }));
-
- // 150ms to hide the no reults message if its take a while to return results
- hide_message_delay_.reset(new glib::Timeout(150, [&] () {
- active_lens_view_->HideResultsMessage();
- return false;
- }));
- }
+ search_in_progress_ = true;
}
void DashView::OnLiveSearchReached(std::string const& search_string)
{
+ // reset and set it again once we're sure a search is happening
+ search_in_progress_ = false;
+
LOG_DEBUG(logger) << "Live search reached: " << search_string;
- if (active_lens_view_)
+ if (active_scope_view_)
{
- active_lens_view_->PerformSearch(search_string,
- sigc::mem_fun(this, &DashView::OnSearchFinished));
+ if (active_scope_view_->PerformSearch(search_string, sigc::mem_fun(this, &DashView::OnScopeSearchFinished)))
+ {
+ search_in_progress_ = true;
+ }
}
}
-void DashView::OnLensAdded(Lens::Ptr& lens)
+void DashView::OnScopeSearchFinished(std::string const& scope_id, std::string const& search_string, glib::Error const& err)
{
- lens_bar_->AddLens(lens);
+ // match active scope?
+ auto scope_pos = scope_views_.find(scope_id);
+ if (scope_pos == scope_views_.end() || scope_pos->second != active_scope_view_)
+ return;
+
+ if (search_string == search_bar_->search_string)
+ {
+ if (err)
+ LOG_WARNING(logger) << "Search failed '"<< search_string <<"'=> " << err;
+ else
+ LOG_DEBUG(logger) << "Search completed: " << search_string;
- nux::ObjectPtr<LensView> view(new LensView(lens, search_bar_->show_filters()));
+ search_bar_->SetSearchFinished();
+ search_in_progress_ = false;
+
+ if (activate_on_finish_ && !err)
+ OnEntryActivated();
+ activate_on_finish_= false;
+ }
+}
+
+void DashView::OnScopeAdded(Scope::Ptr const& scope, int position)
+{
+ LOG_DEBUG(logger) << "Scope Added: " << scope->id();
+
+ scope_bar_->AddScope(scope);
+
+ nux::ObjectPtr<ScopeView> view(new ScopeView(scope, search_bar_->show_filters()));
AddChild(view.GetPointer());
view->SetVisible(false);
- view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));
+ view->result_activated.connect(sigc::mem_fun(this, &DashView::OnResultActivated));
- lenses_layout_->AddView(view.GetPointer(), 1);
- lens_views_[lens->id] = view;
+ scopes_layout_->AddView(view.GetPointer(), 1);
+ scope_views_[scope->id] = view;
- lens->activated.connect(sigc::mem_fun(this, &DashView::OnUriActivatedReply));
- lens->connected.changed.connect([&] (bool value)
- {
- std::string const& search_string = search_bar_->search_string;
- if (value && lens->search_in_global && active_lens_view_ == home_view_
- && !search_string.empty())
- {
- // force a (global!) search with the correct string
- lens->GlobalSearch(search_bar_->search_string,
- sigc::mem_fun(this, &DashView::OnSearchFinished));
- }
- });
+ scope->activated.connect(sigc::mem_fun(this, &DashView::OnResultActivatedReply));
+ scope->connected.changed.connect([&] (bool value) { });
// Hook up to the new preview infrastructure
- lens->preview_ready.connect([&] (std::string const& uri, Preview::Ptr model)
+ scope->preview_ready.connect([&] (LocalResult const& result, Preview::Ptr model)
{
// HACK: Atm we don't support well the fact that a preview can be sent from
// an ActionResponse and therefore transition does not work, this hack allows
@@ -1274,28 +1242,32 @@ void DashView::OnLensAdded(Lens::Ptr& lens)
}
preview_state_machine_.ActivatePreview(model); // this does not immediately display a preview - we now wait.
});
+
+ if (!active_scope_view_)
+ scope_bar_->Activate(scope->id);
}
-void DashView::OnLensBarActivated(std::string const& id)
+void DashView::OnScopeBarActivated(std::string const& id)
{
- if (lens_views_.find(id) == lens_views_.end())
+ if (scope_views_.find(id) == scope_views_.end())
{
- LOG_WARN(logger) << "Unable to find Lens " << id;
+ LOG_WARN(logger) << "Unable to find Scope " << id;
return;
}
- if (active_lens_view_.IsValid())
- active_lens_view_->SetVisible(false);
+ if (active_scope_view_.IsValid())
+ active_scope_view_->SetVisible(false);
+ scope_can_refine_connection_.disconnect();
- nux::ObjectPtr<LensView> view = active_lens_view_ = lens_views_[id];
+ nux::ObjectPtr<ScopeView> view = active_scope_view_ = scope_views_[id];
view->SetVisible(true);
view->AboutToShow();
- for (auto it: lens_views_)
+ for (auto it: scope_views_)
{
bool id_matches = it.first == id;
- ViewType view_type = id_matches ? LENS_VIEW : (view == home_view_ ? HOME_VIEW : HIDDEN);
+ ScopeViewType view_type = id_matches ? ScopeViewType::SCOPE_VIEW : ScopeViewType::HIDDEN;
it.second->SetVisible(id_matches);
it.second->view_type = view_type;
@@ -1306,72 +1278,32 @@ void DashView::OnLensBarActivated(std::string const& id)
search_bar_->SetVisible(true);
QueueRelayout();
search_bar_->search_string = view->search_string;
- search_bar_->search_hint = view->lens()->search_hint;
- // lenses typically return immediately from Search() if the search query
- // doesn't change, so SearchFinished will be called in a few ms
- // FIXME: if we're forcing a search here, why don't we get rid of view types?
- search_bar_->ForceSearchChanged();
-
- bool expanded = view->filters_expanded;
- search_bar_->showing_filters = expanded;
-
- nux::GetWindowCompositor().SetKeyFocusArea(default_focus());
+ search_bar_->search_hint = view->scope()->search_hint;
+ search_bar_->showing_filters = view->filters_expanded();
+ search_bar_->ForceLiveSearch();
search_bar_->text_entry()->SelectAll();
search_bar_->can_refine_search = view->can_refine_search();
- hide_message_delay_.reset();
+ scope_can_refine_connection_ = view->can_refine_search.changed.connect([this] (bool can_refine_search) {
+ search_bar_->can_refine_search = can_refine_search;
+ });
+
+ // Fix for a nux quirk. Unparented objects cannot have focus because there will be a break in the
+ // parent tree and the compositor will not be able to walk the focus tree. This still needs to be here
+ // for when scopes switch via the scope bar and the focus nees to move away from the scope bar to the search bar..
+ if (GetParentObject())
+ nux::GetWindowCompositor().SetKeyFocusArea(default_focus());
view->QueueDraw();
QueueDraw();
}
-void DashView::OnSearchFinished(Lens::Hints const& hints, glib::Error const& err)
-{
- hide_message_delay_.reset();
-
- if (!active_lens_view_.IsValid()) return;
-
- // FIXME: bind the lens_view in PerformSearch
- active_lens_view_->CheckNoResults(hints);
- std::string const& search_string = search_bar_->search_string;
-
- if (active_lens_view_->search_string == search_string)
- {
- search_bar_->SearchFinished();
- search_in_progress_ = false;
- if (activate_on_finish_)
- this->OnEntryActivated();
- }
-}
-
-void DashView::OnGlobalSearchFinished(Lens::Hints const& hints, glib::Error const& error)
-{
- if (active_lens_view_ == home_view_)
- OnSearchFinished(hints, error);
-}
-
-void DashView::OnAppsGlobalSearchFinished(Lens::Ptr const& lens)
-{
- if (active_lens_view_ == home_view_ && lens->id() == "applications.lens")
- {
- /* HACKITY HACK! We're resetting the state of search_in_progress when
- * doing searches in the home lens and we get results from apps lens.
- * This way typing a search query and pressing enter immediately will
- * wait for the apps lens results and will run correct application.
- * See lp:966417 and lp:856206 for more info about why we do this.
- */
- search_in_progress_ = false;
- if (activate_on_finish_)
- this->OnEntryActivated();
- }
-}
-
-void DashView::OnUriActivatedReply(std::string const& uri, HandledType type, Lens::Hints const&)
+void DashView::OnResultActivatedReply(LocalResult const& local_result, ScopeHandledType type, glib::HintsMap const&)
{
// We don't want to close the dash if there was another activation pending
if (type == NOT_HANDLED)
{
- if (!DoFallbackActivation(uri))
+ if (!DoFallbackActivation(local_result.uri))
return;
}
else if (type == SHOW_DASH)
@@ -1382,13 +1314,8 @@ void DashView::OnUriActivatedReply(std::string const& uri, HandledType type, Len
ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
}
-bool DashView::DoFallbackActivation(std::string const& fake_uri)
+bool DashView::DoFallbackActivation(std::string const& uri)
{
- size_t pos = fake_uri.find(":");
- std::string uri = fake_uri.substr(++pos);
-
- LOG_DEBUG(logger) << "Fallback activating " << uri;
-
if (g_str_has_prefix(uri.c_str(), "application://"))
{
std::string const& appname = uri.substr(14);
@@ -1411,9 +1338,9 @@ void DashView::DisableBlur()
}
void DashView::OnEntryActivated()
{
- if (active_lens_view_.IsValid() && !search_in_progress_)
+ if (active_scope_view_.IsValid() && !search_in_progress_)
{
- active_lens_view_->ActivateFirst();
+ active_scope_view_->ActivateFirst();
}
// delay the activation until we get the SearchFinished signal
activate_on_finish_ = search_in_progress_;
@@ -1427,9 +1354,9 @@ bool DashView::AcceptKeyNavFocus()
std::string const DashView::GetIdForShortcutActivation(std::string const& shortcut) const
{
- Lens::Ptr lens = lenses_->GetLensForShortcut(shortcut);
- if (lens)
- return lens->id;
+ Scope::Ptr scope = scopes_ ? scopes_->GetScopeForShortcut(shortcut) : Scope::Ptr();
+ if (scope)
+ return scope->id;
return "";
}
@@ -1437,11 +1364,14 @@ std::vector<char> DashView::GetAllShortcuts()
{
std::vector<char> result;
- for (Lens::Ptr lens: lenses_->GetLenses())
+ if (scopes_)
{
- std::string shortcut = lens->shortcut;
- if(shortcut.size() > 0)
- result.push_back(shortcut.at(0));
+ for (Scope::Ptr scope: scopes_->GetScopes())
+ {
+ std::string shortcut = scope->shortcut;
+ if(shortcut.size() > 0)
+ result.push_back(shortcut.at(0));
+ }
}
return result;
}
@@ -1480,8 +1410,8 @@ void DashView::AddProperties(GVariantBuilder* builder)
dash::Style& style = dash::Style::Instance();
int num_rows = 1; // The search bar
- if (active_lens_view_.IsValid())
- num_rows += active_lens_view_->GetNumRows();
+ if (active_scope_view_.IsValid())
+ num_rows += active_scope_view_->GetNumRows();
std::string form_factor("unknown");
@@ -1510,17 +1440,17 @@ nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction)
{
return preview_container_->KeyNavIteration(direction);
}
- else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_lens_view_.IsValid())
+ else if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_scope_view_.IsValid())
{
auto show_filters = search_bar_->show_filters();
- auto fscroll_view = active_lens_view_->fscroll_view();
+ auto fscroll_view = active_scope_view_->fscroll_view();
if (show_filters && show_filters->HasKeyFocus())
{
if (fscroll_view->IsVisible() && fscroll_view)
return fscroll_view->KeyNavIteration(direction);
else
- return active_lens_view_->KeyNavIteration(direction);
+ return active_scope_view_->KeyNavIteration(direction);
}
}
return this;
@@ -1528,7 +1458,11 @@ nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction)
void DashView::ProcessDndEnter()
{
- ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
+ auto const& event = nux::GetGraphicsDisplay()->GetCurrentEvent();
+
+ // Don't close the dash if the mouse is over the vertical line between the dash and the launcher.
+ if (event.x != GetAbsoluteX())
+ ubus_manager_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
}
nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
@@ -1598,12 +1532,12 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
if (direction != KEY_NAV_NONE && key_symbol == nux::NUX_KEYDOWN && !search_bar_->im_preedit)
{
std::list<nux::Area*> tabs;
- if (active_lens_view_.IsValid())
+ if (active_scope_view_.IsValid())
{
- for (auto category : active_lens_view_->categories())
+ for (auto category : active_scope_view_->GetOrderedCategoryViews())
{
if (category->IsVisible())
- tabs.push_back(category);
+ tabs.push_back(category.GetPointer());
}
}
@@ -1613,11 +1547,11 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
tabs.push_back(search_bar_->show_filters());
}
- if (active_lens_view_.IsValid() &&
- active_lens_view_->filter_bar() && active_lens_view_->fscroll_view() &&
- active_lens_view_->fscroll_view()->IsVisible())
+ if (active_scope_view_.IsValid() &&
+ active_scope_view_->filter_bar() && active_scope_view_->fscroll_view() &&
+ active_scope_view_->fscroll_view()->IsVisible())
{
- for (auto child : active_lens_view_->filter_bar()->GetLayout()->GetChildren())
+ for (auto child : active_scope_view_->filter_bar()->GetLayout()->GetChildren())
{
FilterExpanderLabel* filter = dynamic_cast<FilterExpanderLabel*>(child);
if (filter)
@@ -1629,7 +1563,7 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
{
if (ctrl)
{
- lens_bar_->ActivatePrevious();
+ scope_bar_->ActivatePrevious();
}
else
{
@@ -1656,7 +1590,7 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
{
if (ctrl)
{
- lens_bar_->ActivateNext();
+ scope_bar_->ActivateNext();
}
else
{
@@ -1687,7 +1621,7 @@ nux::Area* DashView::FindKeyFocusArea(unsigned int key_symbol,
}
}
- if (search_key || search_bar_->im_preedit)
+ if (!preview_displaying_ && (search_key || search_bar_->im_preedit))
{
// then send the event to the search entry
return search_bar_->text_entry();
diff --git a/dash/DashView.h b/dash/DashView.h
index cf1974263..28105e2fe 100644
--- a/dash/DashView.h
+++ b/dash/DashView.h
@@ -24,13 +24,12 @@
#include <Nux/View.h>
#include <Nux/VLayout.h>
-#include <UnityCore/FilesystemLenses.h>
-#include <UnityCore/HomeLens.h>
+#include <UnityCore/Scopes.h>
#include <UnityCore/GLibSource.h>
+#include "ScopeBar.h"
+#include "ScopeView.h"
#include "ApplicationStarter.h"
-#include "LensBar.h"
-#include "LensView.h"
#include "previews/PreviewContainer.h"
#include "PreviewStateMachine.h"
#include "UnityCore/Preview.h"
@@ -56,10 +55,10 @@ class DashLayout;
class DashView : public nux::View, public unity::debug::Introspectable
{
NUX_DECLARE_OBJECT_TYPE(DashView, nux::View);
- typedef std::map<std::string, nux::ObjectPtr<LensView>> LensViews;
+ typedef std::map<std::string, nux::ObjectPtr<ScopeView>> ScopeViews;
public:
- DashView(Lenses::Ptr const& lenses, ApplicationStarter::Ptr const& application_starter);
+ DashView(Scopes::Ptr const& scopes, ApplicationStarter::Ptr const& application_starter);
~DashView();
void AboutToShow();
@@ -111,20 +110,17 @@ private:
void OnBackgroundColorChanged(GVariant* args);
void OnSearchChanged(std::string const& search_string);
void OnLiveSearchReached(std::string const& search_string);
- void OnLensAdded(Lens::Ptr& lens);
- void OnLensBarActivated(std::string const& id);
- void OnSearchFinished(Lens::Hints const& hints, glib::Error const& error);
- void OnGlobalSearchFinished(Lens::Hints const& hints, glib::Error const& error);
- void OnAppsGlobalSearchFinished(Lens::Ptr const& lens);
- void OnUriActivated(ResultView::ActivateType type, std::string const& uri, GVariant* data, std::string const& unique_id);
- void OnUriActivatedReply(std::string const& uri, HandledType type, Lens::Hints const&);
+ void OnScopeAdded(Scope::Ptr const& scope, int position);
+ void OnScopeBarActivated(std::string const& id);
+ void OnScopeSearchFinished(std::string const& scope_id, std::string const& search_string, glib::Error const& err);
+ void OnResultActivated(ResultView::ActivateType type, LocalResult const& local_result, GVariant* data, std::string const& unique_id);
+ void OnResultActivatedReply(LocalResult const& local_result, ScopeHandledType type, glib::HintsMap const& hints);
bool DoFallbackActivation(std::string const& uri);
bool LaunchApp(std::string const& appname);
void OnEntryActivated();
- std::string AnalyseLensURI(std::string const& uri);
- void UpdateLensFilter(std::string lens, std::string filter, std::string value);
- void UpdateLensFilterValue(Filter::Ptr filter, std::string value);
- void EnsureLensesInitialized();
+ std::string AnalyseScopeURI(std::string const& uri);
+ void UpdateScopeFilter(std::string scope_id, std::string filter, std::string value);
+ void UpdateScopeFilterValue(Filter::Ptr filter, std::string value);
bool AcceptKeyNavFocus();
bool InspectKeyEvent(unsigned int eventType, unsigned int key_sym, const char* character);
@@ -134,9 +130,8 @@ private:
nux::Area* KeyNavIteration(nux::KeyNavDirection direction);
UBusManager ubus_manager_;
- Lenses::Ptr lenses_;
- HomeLens::Ptr home_lens_;
- LensViews lens_views_;
+ Scopes::Ptr scopes_;
+ ScopeViews scope_views_;
ApplicationStarter::Ptr application_starter_;
@@ -152,27 +147,24 @@ private:
nux::View* content_view_;
nux::HLayout* search_bar_layout_;
SearchBar* search_bar_;
- nux::VLayout* lenses_layout_;
- LensBar* lens_bar_;
+ nux::VLayout* scopes_layout_;
+ ScopeBar* scope_bar_;
- nux::ObjectPtr<LensView> home_view_;
- nux::ObjectPtr<LensView> active_lens_view_;
- nux::ObjectPtr<LensView> preview_lens_view_;
+ nux::ObjectPtr<ScopeView> active_scope_view_;
+ nux::ObjectPtr<ScopeView> preview_scope_view_;
+ sigc::connection scope_can_refine_connection_;
// Drawing related
nux::Geometry content_geo_;
OverlayRenderer renderer_;
- std::string last_activated_uri_;
+ LocalResult last_activated_result_;
guint64 last_activated_timestamp_;
bool search_in_progress_;
bool activate_on_finish_;
bool visible_;
- glib::Source::UniquePtr searching_timeout_;
- glib::Source::UniquePtr hide_message_delay_;
-
nux::ObjectPtr<nux::IOpenGLBaseTexture> dash_view_copy_;
nux::ObjectPtr<nux::IOpenGLBaseTexture> search_view_copy_;
nux::ObjectPtr<nux::IOpenGLBaseTexture> filter_view_copy_;
@@ -195,6 +187,8 @@ private:
float animate_preview_value_;
nux::ObjectPtr<OverlayWindowButtons> overlay_window_buttons_;
+
+ friend class TestDashView;
};
diff --git a/dash/DashViewPrivate.cpp b/dash/DashViewPrivate.cpp
index 796619730..6dca9572e 100644
--- a/dash/DashViewPrivate.cpp
+++ b/dash/DashViewPrivate.cpp
@@ -28,9 +28,9 @@ namespace dash
namespace impl
{
-LensFilter parse_lens_uri(std::string const& uri)
+ScopeFilter parse_scope_uri(std::string const& uri)
{
- LensFilter filter;
+ ScopeFilter filter;
filter.id = uri;
std::size_t pos = uri.find("?");
diff --git a/dash/DashViewPrivate.h b/dash/DashViewPrivate.h
index cb03cb562..9e3855634 100644
--- a/dash/DashViewPrivate.h
+++ b/dash/DashViewPrivate.h
@@ -29,13 +29,13 @@ namespace dash
namespace impl
{
-struct LensFilter
+struct ScopeFilter
{
std::string id;
std::map<std::string, std::string> filters;
};
-LensFilter parse_lens_uri(std::string const& uri);
+ScopeFilter parse_scope_uri(std::string const& uri);
} // namespace impl
} // namespace dash
diff --git a/dash/FilterAllButton.cpp b/dash/FilterAllButton.cpp
index 474e40134..bef183d04 100644
--- a/dash/FilterAllButton.cpp
+++ b/dash/FilterAllButton.cpp
@@ -45,6 +45,7 @@ FilterAllButton::FilterAllButton(NUX_FILE_LINE_DECL)
FilterAllButton::~FilterAllButton()
{
+ filtering_connection_.disconnect();
}
void FilterAllButton::SetFilter(Filter::Ptr const& filter)
diff --git a/dash/FilterBar.cpp b/dash/FilterBar.cpp
index 60135a0c1..b5cca7a68 100644
--- a/dash/FilterBar.cpp
+++ b/dash/FilterBar.cpp
@@ -33,17 +33,13 @@ namespace unity
{
namespace dash
{
-DECLARE_LOGGER(logger, "unity.dash.filter.bar");
+DECLARE_LOGGER(logger, "unity.dash.filterbar");
NUX_IMPLEMENT_OBJECT_TYPE(FilterBar);
FilterBar::FilterBar(NUX_FILE_LINE_DECL)
: View(NUX_FILE_LINE_PARAM)
{
- // TODO - does the filterbar associate itself with a model of some sort?
- // does libunity provide a Lens.Filters model or something that we can update on?
- // don't want to associate a Filterbar with just a lens model, its a filter bar not a
- // lens parser
Init();
}
@@ -95,6 +91,17 @@ void FilterBar::RemoveFilter(Filter::Ptr const& filter)
}
}
+void FilterBar::ClearFilters()
+{
+ for (auto iter: filter_map_)
+ {
+ FilterExpanderLabel* filter_view = iter.second;
+ RemoveChild(filter_view);
+ GetLayout()->RemoveChildObject(filter_view);
+ }
+ filter_map_.clear();
+}
+
void FilterBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
diff --git a/dash/FilterBar.h b/dash/FilterBar.h
index 56e0bb459..668065275 100644
--- a/dash/FilterBar.h
+++ b/dash/FilterBar.h
@@ -48,6 +48,7 @@ public:
void AddFilter(Filter::Ptr const& filter);
void RemoveFilter(Filter::Ptr const& filter);
+ void ClearFilters();
protected:
virtual bool AcceptKeyNavFocus();
diff --git a/dash/FilterExpanderLabel.cpp b/dash/FilterExpanderLabel.cpp
index 5b08540c3..b2fda6b34 100644
--- a/dash/FilterExpanderLabel.cpp
+++ b/dash/FilterExpanderLabel.cpp
@@ -62,12 +62,10 @@ protected:
nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
{
- bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
-
- if (mouse_inside == false)
+ if (event_type != nux::EVENT_MOUSE_WHEEL && TestMousePointerInclusion(mouse_position, event_type))
+ return this;
+ else
return nullptr;
-
- return this;
}
};
@@ -106,11 +104,18 @@ void FilterExpanderLabel::SetLabel(std::string const& label)
void FilterExpanderLabel::SetRightHandView(nux::View* view)
{
dash::Style& style = dash::Style::Instance();
-
- right_hand_contents_ = view;
- right_hand_contents_->SetMinimumHeight(style.GetAllButtonHeight());
- right_hand_contents_->SetMaximumHeight(style.GetAllButtonHeight());
- top_bar_layout_->AddView(right_hand_contents_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
+ if (right_hand_contents_)
+ {
+ top_bar_layout_->RemoveChildObject(right_hand_contents_);
+ right_hand_contents_ = nullptr;
+ }
+ if (view)
+ {
+ right_hand_contents_ = view;
+ right_hand_contents_->SetMinimumHeight(style.GetAllButtonHeight());
+ right_hand_contents_->SetMaximumHeight(style.GetAllButtonHeight());
+ top_bar_layout_->AddView(right_hand_contents_, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
+ }
}
void FilterExpanderLabel::SetContents(nux::Layout* contents)
diff --git a/dash/FilterGenreWidget.cpp b/dash/FilterGenreWidget.cpp
index ea638e95e..cb2475e9b 100644
--- a/dash/FilterGenreWidget.cpp
+++ b/dash/FilterGenreWidget.cpp
@@ -39,13 +39,13 @@ namespace dash
NUX_IMPLEMENT_OBJECT_TYPE(FilterGenre);
FilterGenre::FilterGenre(int columns, NUX_FILE_LINE_DECL)
- : FilterExpanderLabel(_("Categories"), NUX_FILE_LINE_PARAM)
+: FilterExpanderLabel(_("Categories"), NUX_FILE_LINE_PARAM)
+, all_button_(nullptr)
{
dash::Style& style = dash::Style::Instance();
InitTheme();
- all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION);
genre_layout_ = new nux::GridHLayout(NUX_TRACKER_LOCATION);
genre_layout_->ForceChildrenSize(true);
@@ -64,7 +64,6 @@ FilterGenre::FilterGenre(int columns, NUX_FILE_LINE_DECL)
genre_layout_->SetSpaceBetweenChildren (10, 12);
}
- SetRightHandView(all_button_);
SetContents(genre_layout_);
}
@@ -76,7 +75,17 @@ void FilterGenre::SetFilter(Filter::Ptr const& filter)
{
filter_ = std::static_pointer_cast<CheckOptionFilter>(filter);
- all_button_->SetFilter(filter_);
+ // all button
+ auto show_button_func = [this] (bool show_all_button)
+ {
+ all_button_ = show_all_button ? new FilterAllButton(NUX_TRACKER_LOCATION) : nullptr;
+ SetRightHandView(all_button_);
+ if (all_button_)
+ all_button_->SetFilter(filter_);
+ };
+ show_button_func(filter_->show_all_button);
+ filter_->show_all_button.changed.connect(show_button_func);
+
expanded = !filter_->collapsed();
filter_->option_added.connect(sigc::mem_fun(this, &FilterGenre::OnOptionAdded));
@@ -100,6 +109,8 @@ void FilterGenre::OnOptionAdded(FilterOption::Ptr const& new_filter)
button->SetFilter(new_filter);
genre_layout_->AddView(button, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
buttons_.push_back(button);
+
+ QueueRelayout();
}
void FilterGenre::OnOptionRemoved(FilterOption::Ptr const& removed_filter)
@@ -110,6 +121,8 @@ void FilterGenre::OnOptionRemoved(FilterOption::Ptr const& removed_filter)
{
genre_layout_->RemoveChildObject(*it);
buttons_.erase(it);
+
+ QueueRelayout();
break;
}
}
diff --git a/dash/FilterMultiRangeWidget.cpp b/dash/FilterMultiRangeWidget.cpp
index d42268342..8a95217f5 100644
--- a/dash/FilterMultiRangeWidget.cpp
+++ b/dash/FilterMultiRangeWidget.cpp
@@ -41,6 +41,7 @@ NUX_IMPLEMENT_OBJECT_TYPE(FilterMultiRangeWidget);
FilterMultiRangeWidget::FilterMultiRangeWidget(NUX_FILE_LINE_DECL)
: FilterExpanderLabel(_("Multi-range"), NUX_FILE_LINE_PARAM)
+ , all_button_(nullptr)
, dragging_(false)
{
InitTheme();
@@ -51,13 +52,10 @@ FilterMultiRangeWidget::FilterMultiRangeWidget(NUX_FILE_LINE_DECL)
const int top_padding = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding() - 2;
const int bottom_padding = style.GetFilterHighlightPadding() - 1;
- all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION);
-
layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
layout_->SetLeftAndRightPadding(left_padding, right_padding);
layout_->SetTopAndBottomPadding(top_padding, bottom_padding);
- SetRightHandView(all_button_);
SetContents(layout_);
OnActiveChanged(false);
@@ -79,7 +77,17 @@ void FilterMultiRangeWidget::SetFilter(Filter::Ptr const& filter)
filter_ = std::static_pointer_cast<MultiRangeFilter>(filter);
- all_button_->SetFilter(filter_);
+ // all button
+ auto show_button_func = [this] (bool show_all_button)
+ {
+ all_button_ = show_all_button ? new FilterAllButton(NUX_TRACKER_LOCATION) : nullptr;
+ SetRightHandView(all_button_);
+ if (all_button_)
+ all_button_->SetFilter(filter_);
+ };
+ show_button_func(filter_->show_all_button);
+ filter_->show_all_button.changed.connect(show_button_func);
+
expanded = !filter_->collapsed();
filter_->option_added.connect(sigc::mem_fun(this, &FilterMultiRangeWidget::OnOptionAdded));
diff --git a/dash/FilterRatingsButton.cpp b/dash/FilterRatingsButton.cpp
index 2f2374b26..c73df3a11 100644
--- a/dash/FilterRatingsButton.cpp
+++ b/dash/FilterRatingsButton.cpp
@@ -90,7 +90,7 @@ void FilterRatingsButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
// FIXME: 9/26/2011
// We should probably support an API for saying whether the ratings
// should or shouldn't support half stars...but our only consumer at
- // the moment is the applications lens which according to design
+ // the moment is the applications scope which according to design
// (Bug #839759) shouldn't. So for now just force rounding.
// int total_half_stars = rating % 2;
// int total_full_stars = rating / 2;
diff --git a/dash/FilterRatingsWidget.cpp b/dash/FilterRatingsWidget.cpp
index ae89d965d..1fd083315 100644
--- a/dash/FilterRatingsWidget.cpp
+++ b/dash/FilterRatingsWidget.cpp
@@ -46,10 +46,9 @@ namespace dash
NUX_IMPLEMENT_OBJECT_TYPE(FilterRatingsWidget);
FilterRatingsWidget::FilterRatingsWidget(NUX_FILE_LINE_DECL)
- : FilterExpanderLabel(_("Rating"), NUX_FILE_LINE_PARAM)
+: FilterExpanderLabel(_("Rating"), NUX_FILE_LINE_PARAM)
+, all_button_(nullptr)
{
- all_button_ = new FilterAllButton(NUX_TRACKER_LOCATION);
-
dash::Style& style = dash::Style::Instance();
const int top_padding = style.GetSpaceBetweenFilterWidgets() - style.GetFilterHighlightPadding() - 1; // -1 (PNGs have an 1px top padding)
const int bottom_padding = style.GetFilterHighlightPadding();
@@ -61,7 +60,6 @@ FilterRatingsWidget::FilterRatingsWidget(NUX_FILE_LINE_DECL)
layout->AddView(ratings_);
- SetRightHandView(all_button_);
SetContents(layout);
}
@@ -73,6 +71,17 @@ void FilterRatingsWidget::SetFilter(Filter::Ptr const& filter)
{
filter_ = std::static_pointer_cast<RatingsFilter>(filter);
+ // all button
+ auto show_button_func = [this] (bool show_all_button)
+ {
+ all_button_ = show_all_button ? new FilterAllButton(NUX_TRACKER_LOCATION) : nullptr;
+ SetRightHandView(all_button_);
+ if (all_button_)
+ all_button_->SetFilter(filter_);
+ };
+ show_button_func(filter_->show_all_button);
+ filter_->show_all_button.changed.connect(show_button_func);
+
all_button_->SetFilter(filter_);
expanded = !filter_->collapsed();
ratings_->SetFilter(filter_);
diff --git a/dash/LensView.cpp b/dash/LensView.cpp
deleted file mode 100755
index e972e3f94..000000000
--- a/dash/LensView.cpp
+++ /dev/null
@@ -1,946 +0,0 @@
-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
-/*
- * Copyright (C) 2010, 2011 Canonical Ltd
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
- */
-
-#include "LensView.h"
-
-#include <boost/lexical_cast.hpp>
-
-#include <NuxCore/Logger.h>
-#include <Nux/HScrollBar.h>
-#include <Nux/VScrollBar.h>
-
-#include "unity-shared/DashStyle.h"
-#include "CoverflowResultView.h"
-
-#include "ResultRendererTile.h"
-#include "ResultRendererHorizontalTile.h"
-#include "unity-shared/UBusMessages.h"
-#include "unity-shared/UBusWrapper.h"
-#include "unity-shared/PlacesVScrollBar.h"
-#include "unity-shared/PlacesOverlayVScrollBar.h"
-#include "unity-shared/GraphicsUtils.h"
-
-#include "config.h"
-#include <glib/gi18n-lib.h>
-
-namespace unity
-{
-namespace dash
-{
-DECLARE_LOGGER(logger, "unity.dash.lensview");
-namespace
-{
-const int CARD_VIEW_GAP_VERT = 24; // pixels
-const int CARD_VIEW_GAP_HORIZ = 25; // pixels
-}
-
-// This is so we can access some protected members in scrollview.
-class LensScrollView: public nux::ScrollView
-{
-public:
- LensScrollView(nux::VScrollBar* scroll_bar, NUX_FILE_LINE_DECL)
- : nux::ScrollView(NUX_FILE_LINE_PARAM)
- , right_area_(nullptr)
- , up_area_(nullptr)
- {
- SetVScrollBar(scroll_bar);
-
- OnVisibleChanged.connect([&] (nux::Area* /*area*/, bool visible) {
- if (m_horizontal_scrollbar_enable)
- _hscrollbar->SetVisible(visible);
- if (m_vertical_scrollbar_enable)
- _vscrollbar->SetVisible(visible);
- });
- }
-
- void ScrollToPosition(nux::Geometry const& position)
- {
- // much of this code is copied from Nux/ScrollView.cpp
- nux::Geometry const& geo = GetGeometry();
-
- int child_y = position.y - geo.y;
- int child_y_diff = child_y - abs (_delta_y);
-
- if (child_y_diff + position.height < geo.height && child_y_diff >= 0)
- {
- return;
- }
-
- if (child_y_diff < 0)
- {
- ScrollUp (1, abs (child_y_diff));
- }
- else
- {
- int size = child_y_diff - geo.height;
-
- // always keeps the top of a view on the screen
- size += position.height;
-
- ScrollDown (1, size);
- }
- }
-
- void SetRightArea(nux::Area* area)
- {
- right_area_ = area;
- }
-
- void SetUpArea(nux::Area* area)
- {
- up_area_ = area;
- }
-
- void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
- {
- if (RedirectedAncestor())
- {
- if (m_horizontal_scrollbar_enable && _hscrollbar->IsRedrawNeeded())
- graphics::ClearGeometry(_hscrollbar->GetGeometry());
- if (m_vertical_scrollbar_enable && _vscrollbar->IsRedrawNeeded())
- graphics::ClearGeometry(_vscrollbar->GetGeometry());
- }
-
- ScrollView::DrawContent(graphics_engine, force_draw);
- }
-
- void EnableScrolling(bool enable_scrolling)
- {
- _vscrollbar->SetInputEventSensitivity(enable_scrolling);
- }
-
-protected:
-
- // This is so we can break the natural key navigation path.
- nux::Area* KeyNavIteration(nux::KeyNavDirection direction)
- {
- nux::Area* focus_area = nux::GetWindowCompositor().GetKeyFocusArea();
-
- if (direction == nux::KEY_NAV_RIGHT && focus_area && focus_area->IsChildOf(this))
- return right_area_;
- else if (direction == nux::KEY_NAV_UP && focus_area && focus_area->IsChildOf(this))
- return up_area_;
- else
- return nux::ScrollView::KeyNavIteration(direction);
- }
-
-private:
- nux::Area* right_area_;
- nux::Area* up_area_;
-};
-
-
-NUX_IMPLEMENT_OBJECT_TYPE(LensView);
-
-LensView::LensView(Lens::Ptr lens, nux::Area* show_filters)
- : nux::View(NUX_TRACKER_LOCATION)
- , filters_expanded(false)
- , can_refine_search(false)
- , lens_(lens)
- , initial_activation_(true)
- , no_results_active_(false)
- , last_expanded_group_(nullptr)
- , last_good_filter_model_(-1)
- , filter_expansion_pushed_(false)
-{
- SetupViews(show_filters);
- SetupCategories();
- SetupResults();
- SetupFilters();
-
- dash::Style::Instance().columns_changed.connect(sigc::mem_fun(this, &LensView::OnColumnsChanged));
-
- search_string.SetGetterFunction(sigc::mem_fun(this, &LensView::get_search_string));
- filters_expanded.changed.connect(sigc::mem_fun(this, &LensView::OnLensFilterExpanded));
- view_type.changed.connect(sigc::mem_fun(this, &LensView::OnViewTypeChanged));
- if (lens_)
- {
- lens_->connected.changed.connect([&](bool is_connected)
- {
- if (is_connected)
- initial_activation_ = true;
- });
- lens_->categories_reordered.connect(sigc::mem_fun(this, &LensView::OnCategoryOrderChanged));
- }
-
- ubus_manager_.RegisterInterest(UBUS_RESULT_VIEW_KEYNAV_CHANGED, [&] (GVariant* data) {
- // we get this signal when a result view keynav changes,
- // its a bad way of doing this but nux ABI needs to be broken
- // to do it properly
- nux::Geometry focused_pos;
- g_variant_get (data, "(iiii)", &focused_pos.x, &focused_pos.y, &focused_pos.width, &focused_pos.height);
-
- for (auto category : categories_)
- {
- if (category->GetLayout() != nullptr)
- {
- auto expand_label = category->GetHeaderFocusableView();
- auto child = category->GetChildView();
-
- if ((child && child->HasKeyFocus()) ||
- (expand_label && expand_label->HasKeyFocus()))
- {
- focused_pos.x += child->GetGeometry().x;
- focused_pos.y += child->GetGeometry().y - 30;
- focused_pos.height += 30;
- scroll_view_->ScrollToPosition(focused_pos);
- break;
- }
- }
- }
- });
-
- OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {
- scroll_view_->SetVisible(visible);
- });
-
-}
-
-void LensView::SetupViews(nux::Area* show_filters)
-{
- dash::Style& style = dash::Style::Instance();
-
- layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
- layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenLensAndFilters());
-
- scroll_view_ = new LensScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION),
- NUX_TRACKER_LOCATION);
- scroll_view_->EnableVerticalScrollBar(true);
- scroll_view_->EnableHorizontalScrollBar(false);
- layout_->AddView(scroll_view_);
-
- scroll_layout_ = new nux::VLayout(NUX_TRACKER_LOCATION);
- scroll_view_->SetLayout(scroll_layout_);
- scroll_view_->SetRightArea(show_filters);
-
- no_results_ = new StaticCairoText("", NUX_TRACKER_LOCATION);
- no_results_->SetTextColor(nux::color::White);
- no_results_->SetVisible(false);
- scroll_layout_->AddView(no_results_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
-
- fscroll_view_ = new LensScrollView(new PlacesVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION);
- fscroll_view_->EnableVerticalScrollBar(true);
- fscroll_view_->EnableHorizontalScrollBar(false);
- fscroll_view_->SetVisible(false);
- fscroll_view_->SetUpArea(show_filters);
- layout_->AddView(fscroll_view_, 1);
-
- fscroll_layout_ = new nux::VLayout();
- fscroll_view_->SetLayout(fscroll_layout_);
-
- filter_bar_ = new FilterBar();
- int width = style.GetFilterBarWidth() +
- style.GetFilterBarLeftPadding() +
- style.GetFilterBarRightPadding();
-
- fscroll_view_->SetMinimumWidth(width + style.GetFilterViewRightPadding());
- fscroll_view_->SetMaximumWidth(width + style.GetFilterViewRightPadding());
- filter_bar_->SetMinimumWidth(width);
- filter_bar_->SetMaximumWidth(width);
- AddChild(filter_bar_);
- fscroll_layout_->AddView(filter_bar_, 0);
-
- SetLayout(layout_);
-}
-
-void LensView::SetupCategories()
-{
- if (!lens_)
- return;
-
- Categories::Ptr categories = lens_->categories;
- categories->category_added.connect(sigc::mem_fun(this, &LensView::OnCategoryAdded));
-
- for (unsigned int i = 0; i < categories->count(); ++i)
- OnCategoryAdded(categories->RowAtIndex(i));
-}
-
-void LensView::SetupResults()
-{
- if (!lens_)
- return;
-
- Results::Ptr results = lens_->results;
- results->result_added.connect(sigc::mem_fun(this, &LensView::OnResultAdded));
- results->result_removed.connect(sigc::mem_fun(this, &LensView::OnResultRemoved));
-
- results->model.changed.connect([this] (glib::Object<DeeModel> model)
- {
- for (unsigned int i = 0; i < categories_.size(); ++i)
- {
- ResultViewGrid* grid = GetGridForCategory(i);
- glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(i));
- Results::Ptr results_model = lens_->results;
- grid->SetModel(filter_model, results_model->GetTag());
- }
- });
-
- for (unsigned int i = 0; i < results->count(); ++i)
- OnResultAdded(results->RowAtIndex(i));
-}
-
-void LensView::SetupFilters()
-{
- if (!lens_)
- return;
-
- Filters::Ptr filters = lens_->filters;
- filters->filter_added.connect(sigc::mem_fun(this, &LensView::OnFilterAdded));
- filters->filter_removed.connect(sigc::mem_fun(this, &LensView::OnFilterRemoved));
-
- for (unsigned int i = 0; i < filters->count(); ++i)
- OnFilterAdded(filters->FilterAtIndex(i));
-}
-
-void LensView::OnCategoryAdded(Category const& category)
-{
- std::string name = category.name;
- std::string icon_hint = category.icon_hint;
- std::string renderer_name = category.renderer_name;
- unsigned index = (category.index == unsigned(-1)) ? categories_.size() : category.index;
- bool reset_filter_models = false;
-
- LOG_DEBUG(logger) << "Category added: " << name
- << "(" << icon_hint
- << ", " << renderer_name
- << ", " << boost::lexical_cast<int>(index) << ")";
-
- if (index < categories_.size())
- {
- // the lens might have restarted and we don't want to create
- // new PlacesGroup if we can reuse the old one
- PlacesGroup* existing_group = categories_.at(index);
- if (existing_group->GetCategoryIndex() == index) return;
- }
-
- PlacesGroup* group = CreatePlacesGroup();
- AddChild(group);
- group->SetName(name);
- group->SetIcon(icon_hint);
- group->SetCategoryIndex(index);
- group->SetExpanded(false);
- group->SetVisible(false);
- group->expanded.connect(sigc::mem_fun(this, &LensView::OnGroupExpanded));
-
- reset_filter_models = index < categories_.size();
- /* Add the group at the correct offset into the categories vector */
- categories_.insert(categories_.begin() + index, group);
-
- /* Reset result count */
- counts_[group] = 0;
-
- ResultView* grid;
-
- if (renderer_name == "tile-horizontal")
- {
- grid = new ResultViewGrid(NUX_TRACKER_LOCATION);
- grid->SetModelRenderer(new ResultRendererHorizontalTile(NUX_TRACKER_LOCATION));
- static_cast<ResultViewGrid*> (grid)->horizontal_spacing = CARD_VIEW_GAP_HORIZ;
- static_cast<ResultViewGrid*> (grid)->vertical_spacing = CARD_VIEW_GAP_VERT;
- }
- /*
- * The flow renderer is disabled for now, expecting return later
- else if (renderer_name == "flow" && nux::GetWindowThread()->GetGraphicsEngine().UsingGLSLCodePath())
- {
- grid = new CoverflowResultView(NUX_TRACKER_LOCATION);
- grid->SetModelRenderer(new ResultRendererTile(NUX_TRACKER_LOCATION));
- group->SetHeaderCountVisible(false);
- }
- */
- else
- {
- grid = new ResultViewGrid(NUX_TRACKER_LOCATION);
- grid->SetModelRenderer(new ResultRendererTile(NUX_TRACKER_LOCATION));
- }
- group->SetChildView(grid);
-
- if (lens_)
- {
- std::string unique_id = name + lens_->name();
- grid->unique_id = unique_id;
- grid->expanded = false;
-
- group->SetRendererName(renderer_name.c_str());
- grid->UriActivated.connect([this, unique_id] (std::string const& uri, ResultView::ActivateType type, GVariant* data)
- {
- uri_activated.emit(type, uri, data, unique_id);
- switch (type)
- {
- case ResultView::ActivateType::DIRECT:
- {
- lens_->Activate(uri);
- } break;
- case ResultView::ActivateType::PREVIEW:
- {
- lens_->Preview(uri);
- } break;
- default: break;
- };
- });
-
-
- /* Set up filter model for this category */
- Results::Ptr results_model = lens_->results;
- if (results_model->model())
- {
- glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(index));
- grid->SetModel(filter_model, results_model->GetTag());
- }
-
- if (reset_filter_models)
- {
- /* HomeLens is reodering the categories, and since their index is based
- * on the row position in the model, we need to re-initialize the filter
- * models if we got insert and not an append */
- for (auto it = categories_.begin() + (index + 1); it != categories_.end(); ++it)
- {
- grid = static_cast<ResultViewGrid*>((*it)->GetChildView());
- grid->SetModel(glib::Object<DeeModel>(), NULL);
- }
-
- if (static_cast<int>(index) < last_good_filter_model_ || last_good_filter_model_ < 0)
- {
- last_good_filter_model_ = index;
- }
- if (!fix_filter_models_idle_)
- {
- fix_filter_models_idle_.reset(new glib::Idle(sigc::mem_fun(this, &LensView::ReinitializeFilterModels), glib::Source::Priority::HIGH));
- }
- }
- }
-
- /* We need the full range of method args so we can specify the offset
- * of the group into the layout */
- scroll_layout_->AddView(group, 0, nux::MinorDimensionPosition::MINOR_POSITION_START,
- nux::MinorDimensionSize::MINOR_SIZE_FULL, 100.0f,
- (nux::LayoutPosition)index);
-}
-
-void LensView::OnCategoryOrderChanged()
-{
- LOG_DEBUG(logger) << "Reordering categories for " << lens_->name();
-
- // need references so that the Layout doesn't destroy the views
- std::vector<nux::ObjectPtr<PlacesGroup> > child_views;
- for (unsigned i = 0; i < categories_.size(); i++)
- {
- child_views.push_back(nux::ObjectPtr<PlacesGroup>(categories_.at(i)));
- scroll_layout_->RemoveChildObject(categories_.at(i));
- }
-
- if (lens_)
- {
- // there should be ~10 categories, so this shouldn't be too big of a deal
- std::vector<unsigned> order(lens_->GetCategoriesOrder());
- for (unsigned i = 0; i < order.size(); i++)
- {
- unsigned desired_category_index = order[i];
- for (unsigned j = 0; j < child_views.size(); j++)
- {
- if (child_views[j]->GetCategoryIndex() == desired_category_index)
- {
- scroll_layout_->AddView(child_views[j].GetPointer(), 0);
- break;
- }
- }
- }
- }
-}
-
-bool LensView::ReinitializeFilterModels()
-{
- if (!lens_)
- return false;
-
- Results::Ptr results_model = lens_->results;
- for (unsigned i = last_good_filter_model_ + 1; i < categories_.size(); ++i)
- {
- ResultViewGrid* grid = GetGridForCategory(i);
- glib::Object<DeeModel> filter_model(lens_->GetFilterModelForCategory(i));
- grid->SetModel(filter_model, results_model->GetTag());
- }
-
- last_good_filter_model_ = -1;
- fix_filter_models_idle_.reset();
- return false;
-}
-
-ResultViewGrid* LensView::GetGridForCategory(unsigned category_index)
-{
- if (category_index >= categories_.size()) return nullptr;
- PlacesGroup* group = categories_.at(category_index);
- return static_cast<ResultViewGrid*>(group->GetChildView());
-}
-
-ResultView* LensView::GetResultViewForCategory(unsigned category_index)
-{
- if (category_index >= categories_.size()) return nullptr;
- PlacesGroup* group = categories_.at(category_index);
- return static_cast<ResultView*>(group->GetChildView());
-}
-
-void LensView::OnResultAdded(Result const& result)
-{
- try {
- // Anything done in this method needs to be super fast, if in doubt, add
- // it to the model_updated_timeout_ callback!
- PlacesGroup* group = categories_.at(result.category_index);
-
- std::string uri = result.uri;
- LOG_TRACE(logger) << "Result added: " << uri;
-
- UpdateCounts(group, ++counts_[group]);
- // make sure we don't display the no-results-hint if we do have results
- if (G_UNLIKELY (no_results_active_))
- {
- CheckNoResults(Lens::Hints());
- }
-
- if (!model_updated_timeout_)
- {
- model_updated_timeout_.reset(new glib::Idle([&] () {
- // Check if all results so far are from one category
- // If so, then expand that category.
- CheckCategoryExpansion();
- model_updated_timeout_.reset();
- return false;
- }, glib::Source::Priority::HIGH));
- }
- } catch (std::out_of_range& oor) {
- LOG_WARN(logger) << "Result does not have a valid category index: "
- << boost::lexical_cast<unsigned int>(result.category_index)
- << ". Is out of range.";
- }
-}
-
-void LensView::OnResultRemoved(Result const& result)
-{
- try {
- PlacesGroup* group = categories_.at(result.category_index);
-
- std::string uri = result.uri;
- LOG_TRACE(logger) << "Result removed: " << uri;
-
- UpdateCounts(group, --counts_[group]);
- } catch (std::out_of_range& oor) {
- LOG_WARN(logger) << "Result does not have a valid category index: "
- << boost::lexical_cast<unsigned int>(result.category_index)
- << ". Is out of range.";
- }
-}
-
-void LensView::UpdateCounts(PlacesGroup* group, unsigned int new_counts)
-{
- unsigned int columns = dash::Style::Instance().GetDefaultNColumns();
- columns -= filters_expanded ? 2 : 0;
-
- group->SetCounts(columns, new_counts);
- group->SetVisible(new_counts);
-}
-
-void LensView::CheckNoResults(Lens::Hints const& hints)
-{
- gint count = lens_->results()->count();
-
- if (count == 0 && !no_results_active_ && !search_string_.empty())
- {
- std::stringstream markup;
- Lens::Hints::const_iterator it;
-
- it = hints.find("no-results-hint");
- markup << "<span size='larger' weight='bold'>";
-
- if (it != hints.end())
- {
- markup << it->second.GetString();
- }
- else
- {
- markup << _("Sorry, there is nothing that matches your search.");
- }
- markup << "</span>";
-
- LOG_DEBUG(logger) << "The no-result-hint is: " << markup.str();
-
- scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_CENTER);
-
- no_results_active_ = true;
- no_results_->SetText(markup.str());
- no_results_->SetVisible(true);
- }
- else if (count && no_results_active_)
- {
- scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START);
-
- no_results_active_ = false;
- no_results_->SetText("");
- no_results_->SetVisible(false);
- }
-}
-
-void LensView::CheckCategoryExpansion()
-{
- int number_of_displayed_categories = 0;
-
- // Check if we had expanded a group in last run
- // If so, collapse it for now
- if (last_expanded_group_ != nullptr)
- {
- last_expanded_group_->SetExpanded(false);
- last_expanded_group_ = nullptr;
- }
-
- // Cycle through all categories
- for (auto category : categories_)
- {
- if (counts_[category] > 0) {
- number_of_displayed_categories++;
- last_expanded_group_ = category;
- }
- }
-
- if (number_of_displayed_categories == 1 && last_expanded_group_ != nullptr)
- last_expanded_group_->SetExpanded(true);
- else
- last_expanded_group_ = nullptr;
-}
-
-void LensView::HideResultsMessage()
-{
- if (no_results_active_)
- {
- scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START);
- no_results_active_ = false;
- no_results_->SetText("");
- no_results_->SetVisible(false);
- }
-}
-
-void LensView::PerformSearch(std::string const& search_query, Lens::SearchFinishedCallback const& cb)
-{
- search_string_ = search_query;
- if (lens_)
- {
- lens_->Search(search_query, cb);
- }
-}
-
-std::string LensView::get_search_string() const
-{
- return search_string_;
-}
-
-void LensView::OnGroupExpanded(PlacesGroup* group)
-{
- ResultViewGrid* grid = static_cast<ResultViewGrid*>(group->GetChildView());
- grid->expanded = group->GetExpanded();
-
- QueueRelayout();
-}
-
-void LensView::CheckScrollBarState()
-{
- if (scroll_layout_->GetHeight() > scroll_view_->GetHeight())
- {
- scroll_view_->EnableVerticalScrollBar(true);
- }
- else
- {
- scroll_view_->EnableVerticalScrollBar(false);
- }
-}
-
-void LensView::OnColumnsChanged()
-{
- unsigned int columns = dash::Style::Instance().GetDefaultNColumns();
- columns -= filters_expanded ? 2 : 0;
-
- for (auto group: categories_)
- {
- group->SetCounts(columns, counts_[group]);
- }
-}
-
-void LensView::OnFilterAdded(Filter::Ptr filter)
-{
- filter_bar_->AddFilter(filter);
- can_refine_search = true;
-}
-
-void LensView::OnFilterRemoved(Filter::Ptr filter)
-{
- filter_bar_->RemoveFilter(filter);
-}
-
-void LensView::OnViewTypeChanged(ViewType view_type)
-{
- if (!lens_)
- return;
-
- if (view_type != HIDDEN && initial_activation_)
- {
- /* We reset the lens for ourselves, in case this is a restart or something */
- lens_->Search(search_string_, [] (Lens::Hints const&, glib::Error const&) {});
- initial_activation_ = false;
- }
-
- lens_->view_type = view_type;
-}
-
-void LensView::OnLensFilterExpanded(bool expanded)
-{
- if (fscroll_view_->IsVisible() != expanded)
- {
- fscroll_view_->SetVisible(expanded);
- QueueRelayout();
- OnColumnsChanged();
- }
-
- for (auto it = categories_.begin(); it != categories_.end(); ++it)
- {
- (*it)->SetFiltersExpanded(expanded);
- }
-}
-
-void LensView::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
-{
- if (RedirectedAncestor())
- graphics::ClearGeometry(GetGeometry());
-}
-
-void LensView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
-{
- nux::Geometry const& geo(GetGeometry());
- graphics_engine.PushClippingRectangle(geo);
- CheckScrollBarState();
-
- if (!IsFullRedraw() && RedirectedAncestor())
- {
- for (PlacesGroup* category : categories_)
- {
- if (category->IsRedrawNeeded() && category->IsVisible())
- graphics::ClearGeometry(category->GetGeometry());
- }
- if (filter_bar_ && filter_bar_->IsVisible() && filter_bar_->IsRedrawNeeded())
- graphics::ClearGeometry(filter_bar_->GetGeometry());
- }
-
- layout_->ProcessDraw(graphics_engine, force_draw);
- graphics_engine.PopClippingRectangle();
-}
-
-Lens::Ptr LensView::lens() const
-{
- return lens_;
-}
-
-nux::Area* LensView::fscroll_view() const
-{
- return fscroll_view_;
-}
-
-int LensView::GetNumRows()
-{
- unsigned int columns = dash::Style::Instance().GetDefaultNColumns();
- columns -= filters_expanded ? 2 : 0;
-
- int num_rows = 0;
- for (auto group: categories_)
- {
- if (group->IsVisible())
- {
- num_rows += 1; // The category header
-
- if (group->GetExpanded() && columns)
- num_rows += ceil(counts_[group] / static_cast<double>(columns));
- else
- num_rows += 1;
- }
- }
-
- return num_rows;
-}
-
-void LensView::AboutToShow()
-{
- JumpToTop();
- OnLensFilterExpanded(filters_expanded);
-}
-
-void LensView::JumpToTop()
-{
- scroll_view_->ScrollToPosition(nux::Geometry(0, 0, 0, 0));
-}
-
-void LensView::ActivateFirst()
-{
- if (!lens_)
- return;
-
- Results::Ptr results = lens_->results;
- if (results->count())
- {
- // the first displayed category might not be categories_[0]
- auto category_order = lens_->GetCategoriesOrder();
- for (unsigned int i = 0; i < category_order.size(); i++)
- {
- unsigned cat_index = category_order.at(i);
- ResultView* result_view = GetResultViewForCategory(cat_index);
- if (result_view == nullptr) continue;
- auto it = result_view->GetIteratorAtRow(0);
- if (!it.IsLast())
- {
- Result result(*it);
- result_view->Activate(result.uri, result_view->GetIndexForUri(result.uri), ResultView::ActivateType::DIRECT);
- return;
- }
- }
-
- // Fallback
- Result result = results->RowAtIndex(0);
- if (result.uri != "")
- {
- uri_activated.emit(ResultView::ActivateType::DIRECT, result.uri, nullptr, "");
- lens_->Activate(result.uri);
- }
- }
-}
-
-// Keyboard navigation
-bool LensView::AcceptKeyNavFocus()
-{
- return false;
-}
-
-void LensView::ForceCategoryExpansion(std::string const& view_id, bool expand)
-{
- for (auto it = categories_.begin(); it != categories_.end(); ++it)
- {
- if ((*it)->GetChildView()->unique_id == view_id)
- { if (expand)
- {
- (*it)->PushExpanded();
- (*it)->SetExpanded(true);
- }
- else
- {
- (*it)->PopExpanded();
- }
- }
- }
-}
-
-void LensView::SetResultsPreviewAnimationValue(float preview_animation)
-{
- for (auto it = categories_.begin(); it != categories_.end(); ++it)
- {
- (*it)->SetResultsPreviewAnimationValue(preview_animation);
- }
-}
-
-void LensView::EnableResultTextures(bool enable_result_textures)
-{
- scroll_view_->EnableScrolling(!enable_result_textures);
-
- for (auto it = categories_.begin(); it != categories_.end(); ++it)
- {
- ResultView* result_view = (*it)->GetChildView();
- if (result_view)
- {
- result_view->enable_texture_render = enable_result_textures;
- }
- }
-}
-
-std::vector<ResultViewTexture::Ptr> LensView::GetResultTextureContainers()
-{
- // iterate in visual order
- std::vector<ResultViewTexture::Ptr> textures;
- auto category_order = lens_->GetCategoriesOrder();
- for (unsigned int i = 0; i < category_order.size(); i++)
- {
- unsigned category_index = category_order.at(i);
- if (categories_.size() <= category_index)
- continue;
-
- PlacesGroup* category = categories_.at(category_index);
- if (!category || !category->IsVisible())
- continue;
-
- ResultView* result_view = category->GetChildView();
- if (result_view)
- {
- // concatenate textures
- std::vector<ResultViewTexture::Ptr> const& category_textures = result_view->GetResultTextureContainers();
- for (auto it = category_textures.begin(); it != category_textures.end(); ++it)
- {
- ResultViewTexture::Ptr const& result_texture = *it;
- result_texture->category_index = category_index;
- textures.push_back(result_texture);
- }
- }
- }
- return textures;
-}
-
-void LensView::RenderResultTexture(ResultViewTexture::Ptr const& result_texture)
-{
- ResultView* result_view = GetResultViewForCategory(result_texture->category_index);
- if (result_view)
- result_view->RenderResultTexture(result_texture);
-}
-
-void LensView::PushFilterExpansion(bool expand)
-{
- filter_expansion_pushed_ = filters_expanded;
- filters_expanded = expand;
-}
-
-void LensView::PopFilterExpansion()
-{
- filters_expanded = GetPushedFilterExpansion();
-}
-
-bool LensView::GetPushedFilterExpansion() const
-{
- return filter_expansion_pushed_;
-}
-
-PlacesGroup* LensView::CreatePlacesGroup()
-{
- return new PlacesGroup(dash::Style::Instance());
-}
-
-// Introspectable
-std::string LensView::GetName() const
-{
- return "LensView";
-}
-
-void LensView::AddProperties(GVariantBuilder* builder)
-{
- unity::variant::BuilderWrapper(builder)
- .add("name", lens_->id)
- .add("lens-name", lens_->name)
- .add("visible", IsVisible())
- .add("no-results-active", no_results_active_);
-}
-
-}
-}
diff --git a/dash/PlacesGroup.cpp b/dash/PlacesGroup.cpp
index b9419ba59..c85282fa0 100755
--- a/dash/PlacesGroup.cpp
+++ b/dash/PlacesGroup.cpp
@@ -122,7 +122,6 @@ PlacesGroup::PlacesGroup(dash::StyleInterface& style)
_is_expanded_pushed(false),
_n_visible_items_in_unexpand_mode(0),
_n_total_items(0),
- _category_index(0),
_coverflow_enabled(false),
disabled_header_count_(false)
{
@@ -244,17 +243,6 @@ PlacesGroup::SetName(std::string const& name)
}
}
-void
-PlacesGroup::SetRendererName(const char *renderer_name)
-{
- _renderer_name = renderer_name;
-
- if (g_strcmp0(renderer_name, "tile-horizontal") == 0)
- (static_cast<dash::ResultView*>(_child_view))->SetModelRenderer(new dash::ResultRendererHorizontalTile(NUX_TRACKER_LOCATION));
- else if (g_strcmp0(renderer_name, "tile-vertical") == 0)
- (static_cast<dash::ResultView*>(_child_view))->SetModelRenderer(new dash::ResultRendererTile(NUX_TRACKER_LOCATION));
-}
-
void PlacesGroup::SetHeaderCountVisible(bool disable)
{
disabled_header_count_ = !disable;
@@ -342,7 +330,7 @@ PlacesGroup::RefreshLabel()
}
else
{
- LOG_DEBUG(logger) << _n_total_items << " - " << _n_visible_items_in_unexpand_mode;
+ LOG_TRACE(logger) << _n_total_items << " - " << _n_visible_items_in_unexpand_mode;
result_string = glib::String(g_strdup_printf(g_dngettext(GETTEXT_PACKAGE,
"See one more result",
"See %d more results",
@@ -353,7 +341,7 @@ PlacesGroup::RefreshLabel()
bool visible = !(_n_visible_items_in_unexpand_mode >= _n_total_items && _n_total_items != 0);
- _expand_icon->SetVisible(visible);;
+ _expand_icon->SetVisible(visible);
SetName(_cached_name);
_expand_label->SetText(result_string);
@@ -511,20 +499,7 @@ PlacesGroup::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
}
void
-PlacesGroup::SetCategoryIndex(unsigned index)
-{
- _category_index = index;
-}
-
-unsigned
-PlacesGroup::GetCategoryIndex() const
-{
- return _category_index;
-}
-
-void
-PlacesGroup::SetCounts(unsigned n_visible_items_in_unexpand_mode,
- unsigned n_total_items)
+PlacesGroup::SetCounts(unsigned n_total_items)
{
_n_total_items = n_total_items;
diff --git a/dash/PlacesGroup.h b/dash/PlacesGroup.h
index e76f3ca7c..b0b105541 100644
--- a/dash/PlacesGroup.h
+++ b/dash/PlacesGroup.h
@@ -55,12 +55,12 @@ class PlacesGroup : public nux::View, public debug::Introspectable
{
NUX_DECLARE_OBJECT_TYPE(PlacesGroup, nux::View);
public:
+ typedef nux::ObjectPtr<PlacesGroup> Ptr;
PlacesGroup(dash::StyleInterface& style);
void SetIcon(std::string const& icon);
void SetName(std::string const& name);
- void SetRendererName(const char *renderer_name);
void SetHeaderCountVisible(bool disable);
StaticCairoText* GetLabel();
@@ -69,15 +69,12 @@ public:
void SetChildView(dash::ResultView* view);
dash::ResultView* GetChildView();
+
void SetChildLayout(nux::Layout* layout);
void Relayout();
- void SetCategoryIndex(unsigned index);
- unsigned GetCategoryIndex() const;
-
- void SetCounts(unsigned n_visible_items_in_unexpand_mode,
- unsigned n_total_items);
+ void SetCounts(unsigned n_total_items);
void SetExpanded(bool is_expanded);
bool GetExpanded() const;
@@ -94,7 +91,6 @@ public:
void SetFiltersExpanded(bool filters_expanded);
sigc::signal<void, PlacesGroup*> expanded;
- sigc::signal<void, std::string const&> UriActivated;
protected:
long ComputeContentSize();
@@ -125,6 +121,7 @@ private:
void RefreshLabel();
private:
+ std::string _category_id;
dash::StyleInterface& _style;
nux::VLayout* _group_layout;
@@ -151,11 +148,9 @@ private:
bool _is_expanded_pushed;
unsigned _n_visible_items_in_unexpand_mode;
unsigned _n_total_items;
- unsigned _category_index;
std::string _cached_name;
nux::Geometry _cached_geometry;
- std::string _renderer_name;
bool _coverflow_enabled;
bool disabled_header_count_;
@@ -163,7 +158,7 @@ private:
glib::Source::UniquePtr _relayout_idle;
UBusManager _ubus;
- friend class TestLensView;
+ friend class TestScopeView;
};
} // namespace dash
diff --git a/dash/PreviewStateMachine.cpp b/dash/PreviewStateMachine.cpp
index 3a48eeab0..3e0c65c0b 100644
--- a/dash/PreviewStateMachine.cpp
+++ b/dash/PreviewStateMachine.cpp
@@ -93,7 +93,7 @@ void PreviewStateMachine::CheckPreviewRequirementsFulfilled()
*
if (GetSplitPosition(CONTENT_AREA) < 0) return;
if (GetSplitPosition(FILTER_BAR) < 0) return;
- if (GetSplitPosition(LENS_BAR) < 0) return;
+ if (GetSplitPosition(SCOPE_BAR) < 0) return;
if (GetSplitPosition(SEARCH_BAR) < 0) return;
*/
diff --git a/dash/PreviewStateMachine.h b/dash/PreviewStateMachine.h
index f98c73f47..08839c84b 100644
--- a/dash/PreviewStateMachine.h
+++ b/dash/PreviewStateMachine.h
@@ -32,7 +32,7 @@ typedef enum
START,
CONTENT_AREA,
FILTER_BAR,
- LENS_BAR,
+ SCOPE_BAR,
SEARCH_BAR,
END
} SplitPosition;
diff --git a/dash/ResultRenderer.cpp b/dash/ResultRenderer.cpp
index 7ddc35391..2454d298b 100644
--- a/dash/ResultRenderer.cpp
+++ b/dash/ResultRenderer.cpp
@@ -133,12 +133,12 @@ void ResultRenderer::Render(nux::GraphicsEngine& GfxContext,
nux::GetPainter().PushDrawSliceScaledTextureLayer(GfxContext, geometry, nux::eBUTTON_NORMAL, nux::color::White, nux::eAllCorners);
}
-void ResultRenderer::Preload(Result& row)
+void ResultRenderer::Preload(Result const& row)
{
// pre-load the given row
}
-void ResultRenderer::Unload(Result& row)
+void ResultRenderer::Unload(Result const& row)
{
// unload any resources
}
diff --git a/dash/ResultRenderer.h b/dash/ResultRenderer.h
index a26429b6f..d9f3689c0 100644
--- a/dash/ResultRenderer.h
+++ b/dash/ResultRenderer.h
@@ -59,10 +59,10 @@ public:
// this is just to start preloading images and text that the renderer might
// need - can be ignored
- virtual void Preload(Result& row);
+ virtual void Preload(Result const& row);
// unload any previous grabbed images
- virtual void Unload(Result& row);
+ virtual void Unload(Result const& row);
// get a image to drag
virtual nux::NBitmapData* GetDndImage(Result const& row) const;
diff --git a/dash/ResultRendererHorizontalTile.cpp b/dash/ResultRendererHorizontalTile.cpp
index 65f4e26a4..26b13ac9b 100644
--- a/dash/ResultRendererHorizontalTile.cpp
+++ b/dash/ResultRendererHorizontalTile.cpp
@@ -268,7 +268,7 @@ nux::BaseTexture* ResultRendererHorizontalTile::DrawNormal(std::string const& te
return texture_from_cairo_graphics(cairo_graphics);
}
-void ResultRendererHorizontalTile::LoadText(Result& row)
+void ResultRendererHorizontalTile::LoadText(Result const& row)
{
std::stringstream final_text;
char *name = g_markup_escape_text(row.name().c_str() , -1);
diff --git a/dash/ResultRendererHorizontalTile.h b/dash/ResultRendererHorizontalTile.h
index 3efbeb278..476c66ac7 100644
--- a/dash/ResultRendererHorizontalTile.h
+++ b/dash/ResultRendererHorizontalTile.h
@@ -51,7 +51,7 @@ public:
virtual nux::NBitmapData* GetDndImage(Result const& row) const;
protected:
- virtual void LoadText(Result& row);
+ virtual void LoadText(Result const& row);
private:
nux::BaseTexture* DrawHighlight(std::string const& texid,
diff --git a/dash/ResultRendererTile.cpp b/dash/ResultRendererTile.cpp
index a3c9781a1..4e6c34fa8 100644
--- a/dash/ResultRendererTile.cpp
+++ b/dash/ResultRendererTile.cpp
@@ -208,21 +208,26 @@ nux::BaseTexture* ResultRendererTile::DrawHighlight(std::string const& texid, in
return texture_from_cairo_graphics(cairo_graphics);
}
-void ResultRendererTile::Preload(Result& row)
+void ResultRendererTile::Preload(Result const& row)
{
if (row.renderer<TextureContainer*>() == nullptr)
{
- row.set_renderer(new TextureContainer());
+ // Shouldn't really do this, but it's safe in this case and quicker than making a copy.
+ const_cast<Result&>(row).set_renderer(new TextureContainer());
LoadIcon(row);
LoadText(row);
}
}
-void ResultRendererTile::Unload(Result& row)
+void ResultRendererTile::Unload(Result const& row)
{
TextureContainer *container = row.renderer<TextureContainer*>();
- delete container;
- row.set_renderer<TextureContainer*>(nullptr);
+ if (container)
+ {
+ delete container;
+ // Shouldn't really do this, but it's safe in this case and quicker than making a copy.
+ const_cast<Result&>(row).set_renderer<TextureContainer*>(nullptr);
+ }
}
nux::NBitmapData* ResultRendererTile::GetDndImage(Result const& row) const
@@ -239,7 +244,7 @@ nux::NBitmapData* ResultRendererTile::GetDndImage(Result const& row) const
return bitmap ? bitmap : ResultRenderer::GetDndImage(row);
}
-void ResultRendererTile::LoadIcon(Result& row)
+void ResultRendererTile::LoadIcon(Result const& row)
{
Style& style = Style::Instance();
std::string icon_hint(row.icon_hint);
@@ -354,7 +359,7 @@ void ResultRendererTile::IconLoaded(std::string const& texid,
int max_height,
glib::Object<GdkPixbuf> const& pixbuf,
std::string icon_name,
- Result& row)
+ Result const& row)
{
TextureContainer *container = row.renderer<TextureContainer*>();
@@ -386,7 +391,7 @@ void ResultRendererTile::IconLoaded(std::string const& texid,
}
-void ResultRendererTile::LoadText(Result& row)
+void ResultRendererTile::LoadText(Result const& row)
{
Style& style = Style::Instance();
nux::CairoGraphics _cairoGraphics(CAIRO_FORMAT_ARGB32,
diff --git a/dash/ResultRendererTile.h b/dash/ResultRendererTile.h
index 4349d66c4..929f93f60 100644
--- a/dash/ResultRendererTile.h
+++ b/dash/ResultRendererTile.h
@@ -69,8 +69,8 @@ public:
nux::Color const& color,
float saturate);
- virtual void Preload(Result& row);
- virtual void Unload(Result& row);
+ virtual void Preload(Result const& row);
+ virtual void Unload(Result const& row);
virtual nux::NBitmapData* GetDndImage(Result const& row) const;
@@ -78,15 +78,15 @@ public:
int padding;
protected:
- virtual void LoadText(Result& row);
- void LoadIcon(Result& row);
+ virtual void LoadText(Result const& row);
+ void LoadIcon(Result const& row);
nux::ObjectPtr<nux::BaseTexture> prelight_cache_;
nux::ObjectPtr<nux::BaseTexture> normal_cache_;
private:
//icon loading callbacks
void IconLoaded(std::string const& texid, int max_width, int max_height,
glib::Object<GdkPixbuf> const& pixbuf,
- std::string icon_name, Result& row);
+ std::string icon_name, Result const& row);
nux::BaseTexture* CreateTextureCallback(std::string const& texid,
int width, int height,
glib::Object<GdkPixbuf> const& pixbuf);
diff --git a/dash/ResultView.cpp b/dash/ResultView.cpp
index f279e2e67..0d18cf3bf 100644
--- a/dash/ResultView.cpp
+++ b/dash/ResultView.cpp
@@ -89,68 +89,44 @@ void ResultView::SetModelRenderer(ResultRenderer* renderer)
NeedRedraw();
}
-void ResultView::AddResult(Result& result)
+void ResultView::AddResult(Result const& result)
{
renderer_->Preload(result);
NeedRedraw();
}
-void ResultView::RemoveResult(Result& result)
+void ResultView::RemoveResult(Result const& result)
{
renderer_->Unload(result);
}
-void ResultView::OnRowAdded(DeeModel* model, DeeModelIter* iter)
-{
- cached_result_.SetTarget(model, iter, renderer_tag_);
- AddResult(cached_result_);
-}
-
-void ResultView::OnRowRemoved(DeeModel* model, DeeModelIter* iter)
-{
- cached_result_.SetTarget(model, iter, renderer_tag_);
- RemoveResult(cached_result_);
-}
-
-void ResultView::SetModel(glib::Object<DeeModel> const& model, DeeModelTag* tag)
+void ResultView::SetResultsModel(Results::Ptr const& result_model)
{
// cleanup
if (result_model_)
{
- sig_manager_.Disconnect(result_model_);
-
+ result_added_connection_.disconnect();
+ result_removed_connection_.disconnect();
for (ResultIterator it(GetIteratorAtRow(0)); !it.IsLast(); ++it)
{
RemoveResult(*it);
}
}
- result_model_ = model;
- renderer_tag_ = tag;
+ result_model_ = result_model;
- if (model)
+ if (result_model_)
{
- typedef glib::Signal<void, DeeModel*, DeeModelIter*> RowSignalType;
-
- sig_manager_.Add(new RowSignalType(model,
- "row-added",
- sigc::mem_fun(this, &ResultView::OnRowAdded)));
- sig_manager_.Add(new RowSignalType(model,
- "row-removed",
- sigc::mem_fun(this, &ResultView::OnRowRemoved)));
-
- for (ResultIterator it(GetIteratorAtRow(0)); !it.IsLast(); ++it)
- {
- AddResult(*it);
- }
+ result_added_connection_ = result_model_->result_added.connect(sigc::mem_fun(this, &ResultView::AddResult));
+ result_removed_connection_ = result_model_->result_removed.connect(sigc::mem_fun(this, &ResultView::RemoveResult));
}
}
unsigned ResultView::GetNumResults()
{
if (result_model_)
- return dee_model_get_n_rows(result_model_);
+ return result_model_->count();
return 0;
}
@@ -160,20 +136,23 @@ ResultIterator ResultView::GetIteratorAtRow(unsigned row)
DeeModelIter* iter = NULL;
if (result_model_)
{
- iter = row > 0 ? dee_model_get_iter_at_row(result_model_, row) :
- dee_model_get_first_iter(result_model_);
+ if (result_model_->model())
+ {
+ iter = row > 0 ? dee_model_get_iter_at_row(result_model_->model(), row) :
+ dee_model_get_first_iter(result_model_->model());
+
+ return ResultIterator(result_model_->model(), iter, result_model_->GetTag());
+ }
}
- return ResultIterator(result_model_, iter, renderer_tag_);
+ return ResultIterator(glib::Object<DeeModel>());
}
-// it would be nice to return a result here, but c++ does not have a good mechanism
-// for indicating out of bounds errors. so i return the index
-unsigned int ResultView::GetIndexForUri(const std::string& uri)
+unsigned int ResultView::GetIndexForLocalResult(LocalResult const& local_result)
{
unsigned int index = 0;
for (ResultIterator it(GetIteratorAtRow(0)); !it.IsLast(); ++it)
{
- if ((*it).uri == uri)
+ if ((*it).uri == local_result.uri)
break;
index++;
@@ -182,23 +161,16 @@ unsigned int ResultView::GetIndexForUri(const std::string& uri)
return index;
}
-std::string ResultView::GetUriForIndex(unsigned int index)
+LocalResult ResultView::GetLocalResultForIndex(unsigned int index)
{
if (index >= GetNumResults())
- return "";
+ return LocalResult();
- return (*GetIteratorAtRow(index)).uri();
-}
-
-long ResultView::ComputeContentSize()
-{
- return View::ComputeContentSize();
+ return LocalResult(*GetIteratorAtRow(index));
}
void ResultView::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
-{
-
-}
+{}
void ResultView::DrawContent(nux::GraphicsEngine& GfxContent, bool force_draw)
{
@@ -290,6 +262,12 @@ std::string ResultView::GetName() const
return "ResultView";
}
+void ResultView::GetResultDimensions(int& rows, int& columns)
+{
+ columns = results_per_row;
+ rows = result_model_ ? ceil(static_cast<double>(result_model_->count()) / static_cast<double>(std::max(1, columns))) : 0.0;
+}
+
void ResultView::AddProperties(GVariantBuilder* builder)
{
unity::variant::BuilderWrapper(builder)
@@ -310,7 +288,7 @@ debug::Introspectable::IntrospectableList ResultView::GetIntrospectableChildren(
int index = 0;
if (result_model_)
{
- for (ResultIterator iter(result_model_); !iter.IsLast(); ++iter)
+ for (ResultIterator iter(result_model_->model()); !iter.IsLast(); ++iter)
{
Result const& result = *iter;
diff --git a/dash/ResultView.h b/dash/ResultView.h
index e7124fb57..5dbc316d7 100644
--- a/dash/ResultView.h
+++ b/dash/ResultView.h
@@ -29,7 +29,6 @@
#include <UnityCore/GLibSignal.h>
#include <UnityCore/Results.h>
-#include <UnityCore/ResultIterator.h>
#include "unity-shared/Introspectable.h"
#include "ResultRenderer.h"
@@ -70,37 +69,38 @@ public:
virtual ~ResultView();
void SetModelRenderer(ResultRenderer* renderer);
- void SetModel(glib::Object<DeeModel> const& model, DeeModelTag* tag);
+ void SetResultsModel(Results::Ptr const& results);
- unsigned int GetIndexForUri(const std::string& uri);
- std::string GetUriForIndex(unsigned int);
+ unsigned int GetIndexForLocalResult(LocalResult const& local_result);
+ LocalResult GetLocalResultForIndex(unsigned int);
nux::Property<bool> expanded;
nux::Property<int> results_per_row;
nux::Property<std::string> unique_id;
nux::Property<float> desaturation_progress;
nux::Property<bool> enable_texture_render;
- sigc::signal<void, std::string const&, ActivateType, GVariant*> UriActivated;
+ sigc::signal<void, LocalResult const&, ActivateType, GVariant*> ResultActivated;
std::string GetName() const;
ResultIterator GetIteratorAtRow(unsigned row);
void AddProperties(GVariantBuilder* builder);
IntrospectableList GetIntrospectableChildren();
- virtual void Activate(std::string const& uri, int index, ActivateType type) = 0;
+ virtual void Activate(LocalResult const& local_result, int index, ActivateType type) = 0;
std::vector<ResultViewTexture::Ptr> const& GetResultTextureContainers();
virtual void RenderResultTexture(ResultViewTexture::Ptr const& result_texture);
+ virtual void GetResultDimensions(int& rows, int& columns);
+
protected:
virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
- virtual long ComputeContentSize();
virtual void UpdateRenderTextures();
- virtual void AddResult(Result& result);
- virtual void RemoveResult(Result& result);
+ virtual void AddResult(Result const& result);
+ virtual void RemoveResult(Result const& result);
unsigned GetNumResults();
@@ -111,9 +111,7 @@ protected:
// properties
ResultRenderer* renderer_;
- glib::Object<DeeModel> result_model_;
- DeeModelTag* renderer_tag_;
- glib::SignalManager sig_manager_;
+ Results::Ptr result_model_;
std::map<std::string, debug::ResultWrapper*> introspectable_children_;
std::vector<ResultViewTexture::Ptr> result_textures_;
@@ -123,6 +121,8 @@ private:
void OnRowRemoved(DeeModel* model, DeeModelIter* iter);
Result cached_result_;
+ sigc::connection result_added_connection_;
+ sigc::connection result_removed_connection_;
};
}
diff --git a/dash/ResultViewGrid.cpp b/dash/ResultViewGrid.cpp
index 134b8c021..cfeb7aacb 100644
--- a/dash/ResultViewGrid.cpp
+++ b/dash/ResultViewGrid.cpp
@@ -63,8 +63,8 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
, mouse_over_index_(-1)
, active_index_(-1)
, selected_index_(-1)
- , activated_uri_("NULL")
, last_lazy_loaded_result_(0)
+ , all_results_preloaded_(true)
, last_mouse_down_x_(-1)
, last_mouse_down_y_(-1)
, drag_index_(~0)
@@ -81,11 +81,13 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
vertical_spacing.changed.connect(needredraw_lambda);
padding.changed.connect(needredraw_lambda);
selected_index_.changed.connect(needredraw_lambda);
+ expanded.changed.connect([&](bool value) { if (value) all_results_preloaded_ = false; });
+ results_per_row.changed.connect([&](int value) { if (value > 0) all_results_preloaded_ = false; });
key_nav_focus_change.connect(sigc::mem_fun(this, &ResultViewGrid::OnKeyNavFocusChange));
- key_nav_focus_activate.connect([&] (nux::Area *area)
- {
- Activate(focused_uri_, selected_index_, ResultView::ActivateType::DIRECT);
+ key_nav_focus_activate.connect([&] (nux::Area *area)
+ {
+ Activate(focused_result_, selected_index_, ResultView::ActivateType::DIRECT);
});
key_down.connect(sigc::mem_fun(this, &ResultViewGrid::OnKeyDown));
mouse_move.connect(sigc::mem_fun(this, &ResultViewGrid::MouseMove));
@@ -125,17 +127,19 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
ubus_.RegisterInterest(UBUS_DASH_PREVIEW_NAVIGATION_REQUEST, [&] (GVariant* data) {
int nav_mode = 0;
- gchar* uri = NULL;
- gchar* proposed_unique_id = NULL;
- g_variant_get(data, "(iss)", &nav_mode, &uri, &proposed_unique_id);
+ GVariant* local_result_variant = NULL;
+ glib::String proposed_unique_id;
+ g_variant_get(data, "(ivs)", &nav_mode, &local_result_variant, &proposed_unique_id);
+ LocalResult local_result(LocalResult::FromVariant(local_result_variant));
+ g_variant_unref(local_result_variant);
- if (std::string(proposed_unique_id) != unique_id())
+ if (proposed_unique_id.Str() != unique_id())
return;
unsigned num_results = GetNumResults();
- if (std::string(uri) == activated_uri_)
+ if (local_result == activated_result_)
{
- int current_index = GetIndexForUri(activated_uri_);
+ int current_index = GetIndexForLocalResult(activated_result_);
if (nav_mode == -1) // left
{
current_index--;
@@ -154,29 +158,25 @@ ResultViewGrid::ResultViewGrid(NUX_FILE_LINE_DECL)
// closed
if (nav_mode == 0)
{
- activated_uri_ = "";
+ activated_result_.clear();
}
else
{
selected_index_ = active_index_ = current_index;
- activated_uri_ = GetUriForIndex(current_index);
+ activated_result_ = GetLocalResultForIndex(current_index);
LOG_DEBUG(logger) << "activating preview for index: "
<< "(" << current_index << ")"
- << " " << activated_uri_;
- Activate(activated_uri_, current_index, ActivateType::PREVIEW);
+ << " " << activated_result_.uri;
+ Activate(activated_result_, current_index, ActivateType::PREVIEW);
}
-
}
- g_free(uri);
- g_free(proposed_unique_id);
-
});
SetDndEnabled(true, false);
}
-void ResultViewGrid::Activate(std::string const& uri, int index, ResultView::ActivateType type)
+void ResultViewGrid::Activate(LocalResult const& local_result, int index, ResultView::ActivateType type)
{
unsigned num_results = GetNumResults();
@@ -210,28 +210,44 @@ void ResultViewGrid::Activate(std::string const& uri, int index, ResultView::Act
active_index_ = index;
guint64 timestamp = nux::GetGraphicsDisplay()->GetCurrentEvent().x11_timestamp;
glib::Variant data(g_variant_new("(tiiiiii)", timestamp, column_x, row_y, column_width, row_height, left_results, right_results));
- UriActivated.emit(uri, type, data);
+ ResultActivated.emit(local_result, type, data);
}
void ResultViewGrid::QueueLazyLoad()
{
- lazy_load_source_.reset(new glib::Idle(glib::Source::Priority::DEFAULT));
- lazy_load_source_->Run(sigc::mem_fun(this, &ResultViewGrid::DoLazyLoad));
- last_lazy_loaded_result_ = 0; // we always want to reset the lazy load index here
+ if (all_results_preloaded_ || GetNumResults() == 0)
+ return;
+
+ if (results_changed_idle_)
+ return;
+
+ if (!lazy_load_source_)
+ {
+ lazy_load_source_.reset(new glib::Idle(glib::Source::Priority::DEFAULT));
+ // dont need to reset the last start index as all the previous ones would have been preloaded already.
+ lazy_load_source_->Run(sigc::mem_fun(this, &ResultViewGrid::DoLazyLoad));
+ }
}
-void ResultViewGrid::QueueViewChanged()
+void ResultViewGrid::QueueResultsChanged()
{
- if (!view_changed_idle_)
+ // even if we're not going to run the lazy load, we need to reset the start in case it's running already.
+ last_lazy_loaded_result_ = 0;
+
+ if (!results_changed_idle_)
{
// using glib::Source::Priority::HIGH because this needs to happen *before* next draw
- view_changed_idle_.reset(new glib::Idle(glib::Source::Priority::HIGH));
- view_changed_idle_->Run([&] () {
+ results_changed_idle_.reset(new glib::Idle(glib::Source::Priority::HIGH));
+ results_changed_idle_->Run([this] () {
SizeReallocate();
- last_lazy_loaded_result_ = 0; // reset the lazy load index
- DoLazyLoad(); // also calls QueueDraw
-
- view_changed_idle_.reset();
+ results_changed_idle_.reset();
+ lazy_load_source_.reset(); // no point doing this one as well.
+
+ if (!all_results_preloaded_)
+ {
+ last_lazy_loaded_result_ = 0; // reset the lazy load index in case we got an insert
+ DoLazyLoad(); // also calls QueueDraw
+ }
return false;
});
}
@@ -239,26 +255,6 @@ void ResultViewGrid::QueueViewChanged()
bool ResultViewGrid::DoLazyLoad()
{
- // FIXME - so this code was nice, it would only load the visible entries on the screen
- // however nux does not give us a good enough indicator right now that we are scrolling,
- // thus if you scroll more than a screen in one frame, you will end up with at least one frame where
- // no icons are displayed (they have not been preloaded yet) - it sucked. we should fix this next cycle when we can break api
- //~ int index = 0;
-//~
- //~ ResultListBounds visible_bounds = GetVisableResults();
- //~ int lower_bound = std::get<0>(visible_bounds);
- //~ int upper_bound = std::get<1>(visible_bounds);
-//~
- //~ ResultList::iterator it;
- //~ for (it = results_.begin(); it != results_.end(); it++)
- //~ {
- //~ if (index >= lower_bound && index <= upper_bound)
- //~ {
- //~ renderer_->Preload((*it));
- //~ }
- //~ index++;
- //~ }
-
util::Timer timer;
bool queue_additional_load = false; // if this is set, we will return early and start loading more next frame
@@ -270,31 +266,34 @@ bool ResultViewGrid::DoLazyLoad()
if ((!expanded && index < items_per_row) || expanded)
{
renderer_->Preload(*it);
- last_lazy_loaded_result_ = index;
}
+ if (!expanded && index >= items_per_row)
+ break; //early exit
+
if (timer.ElapsedSeconds() > 0.008)
{
queue_additional_load = true;
break;
}
- if (!expanded && index >= items_per_row)
- break; //early exit
-
+ last_lazy_loaded_result_++;
index++;
}
- if (queue_additional_load)
+ if (!queue_additional_load)
{
- //we didn't load all the results because we exceeded our time budget, so queue another lazy load
- lazy_load_source_.reset(new glib::Timeout(1000/60 - 8));
- lazy_load_source_->Run(sigc::mem_fun(this, &ResultViewGrid::DoLazyLoad));
+ all_results_preloaded_ = true;
+ lazy_load_source_.reset();
+ }
+ else if (!lazy_load_source_)
+ {
+ lazy_load_source_.reset(new glib::Idle(glib::Source::Priority::DEFAULT));
+ lazy_load_source_->Run(sigc::mem_fun(this, &ResultViewGrid::DoLazyLoad));
}
-
QueueDraw();
- return false;
+ return queue_additional_load;
}
@@ -304,21 +303,28 @@ int ResultViewGrid::GetItemsPerRow()
return (items_per_row) ? items_per_row : 1; // always at least one item per row
}
+void ResultViewGrid::GetResultDimensions(int& rows, int& columns)
+{
+ columns = GetItemsPerRow();
+ rows = result_model_ ? ceil(static_cast<double>(result_model_->count()) / static_cast<double>(std::max<int>(1, columns))) : 0.0;
+}
+
void ResultViewGrid::SetModelRenderer(ResultRenderer* renderer)
{
ResultView::SetModelRenderer(renderer);
SizeReallocate();
}
-void ResultViewGrid::AddResult(Result& result)
+void ResultViewGrid::AddResult(Result const& result)
{
- QueueViewChanged();
+ all_results_preloaded_ = false;
+ QueueResultsChanged();
}
-void ResultViewGrid::RemoveResult(Result& result)
+void ResultViewGrid::RemoveResult(Result const& result)
{
ResultView::RemoveResult(result);
- QueueViewChanged();
+ QueueResultsChanged();
}
void ResultViewGrid::SizeReallocate()
@@ -461,8 +467,8 @@ void ResultViewGrid::OnKeyDown (unsigned long event_type, unsigned long event_ke
// if we got this far, we definately got a keynav signal
- if (focused_uri_.empty())
- focused_uri_ = (*GetIteratorAtRow(0)).uri;
+ if (focused_result_.uri.empty())
+ focused_result_ = (*GetIteratorAtRow(0));
int items_per_row = GetItemsPerRow();
unsigned num_results = GetNumResults();
@@ -507,7 +513,7 @@ void ResultViewGrid::OnKeyDown (unsigned long event_type, unsigned long event_ke
selected_index_ = std::max(0, selected_index_());
selected_index_ = std::min(static_cast<int>(num_results - 1), selected_index_());
ResultIterator iter(GetIteratorAtRow(selected_index_));
- focused_uri_ = (*iter).uri;
+ focused_result_ = (*iter);
std::tuple<int, int> focused_coord = GetResultPosition(selected_index_);
@@ -520,7 +526,7 @@ void ResultViewGrid::OnKeyDown (unsigned long event_type, unsigned long event_ke
if (event_type == nux::NUX_KEYDOWN && event_keysym == XK_Menu)
{
- Activate(focused_uri_, selected_index_, ActivateType::PREVIEW);
+ Activate(focused_result_, selected_index_, ActivateType::PREVIEW);
}
}
@@ -533,10 +539,10 @@ void ResultViewGrid::OnKeyNavFocusChange(nux::Area *area, bool has_focus, nux::K
{
if (HasKeyFocus())
{
- if (selected_index_ < 0 && GetNumResults())
+ if (result_model_ && selected_index_ < 0 && GetNumResults())
{
- ResultIterator first_iter(result_model_);
- focused_uri_ = (*first_iter).uri;
+ ResultIterator first_iter(result_model_->model());
+ focused_result_ = (*first_iter);
selected_index_ = 0;
}
@@ -568,7 +574,7 @@ void ResultViewGrid::OnKeyNavFocusChange(nux::Area *area, bool has_focus, nux::K
else
{
selected_index_ = -1;
- focused_uri_.clear();
+ focused_result_.clear();
selection_change.emit();
}
@@ -790,13 +796,13 @@ void ResultViewGrid::MouseClick(int x, int y, unsigned long button_flags, unsign
ResultIterator it(GetIteratorAtRow(index));
Result result = *it;
selected_index_ = index;
- focused_uri_ = result.uri;
+ focused_result_ = result;
ActivateType type = nux::GetEventButton(button_flags) == nux::MouseButton::MOUSE_BUTTON3 ? ResultView::ActivateType::PREVIEW :
ResultView::ActivateType::DIRECT;
- activated_uri_ = result.uri();
- Activate(activated_uri_, index, type);
+ activated_result_ = result;
+ Activate(activated_result_, index, type);
}
}
@@ -824,9 +830,9 @@ unsigned ResultViewGrid::GetIndexAtPosition(int x, int y)
return (row_number * items_per_row) + column_number;
}
-std::tuple<int, int> ResultViewGrid::GetResultPosition(const std::string& uri)
+std::tuple<int, int> ResultViewGrid::GetResultPosition(LocalResult const& local_result)
{
- unsigned int index = GetIndexForUri(uri);
+ unsigned int index = GetIndexForLocalResult(local_result);
return GetResultPosition(index);
}
@@ -863,15 +869,13 @@ bool ResultViewGrid::DndSourceDragBegin()
Reference();
ResultIterator iter(GetIteratorAtRow(drag_index_));
- Result drag_result = *iter;
-
- current_drag_uri_ = drag_result.dnd_uri;
- if (current_drag_uri_ == "")
- current_drag_uri_ = drag_result.uri().substr(drag_result.uri().find(":") + 1);
+ current_drag_result_ = *iter;
+ if (current_drag_result_.empty())
+ current_drag_result_.uri = current_drag_result_.uri.substr(current_drag_result_.uri.find(":") + 1);
LOG_DEBUG (logger) << "Dnd begin at " <<
last_mouse_down_x_ << ", " << last_mouse_down_y_ << " - using; "
- << current_drag_uri_;
+ << current_drag_result_.uri;
return true;
#else
@@ -901,10 +905,10 @@ const char* ResultViewGrid::DndSourceGetDataForType(const char* type, int* size,
{
*format = 8;
- if (!current_drag_uri_.empty())
+ if (!current_drag_result_.empty())
{
- *size = strlen(current_drag_uri_.c_str());
- return current_drag_uri_.c_str();
+ *size = strlen(current_drag_result_.uri.c_str());
+ return current_drag_result_.uri.c_str();
}
else
{
@@ -919,7 +923,7 @@ void ResultViewGrid::DndSourceDragFinished(nux::DndAction result)
UnReference();
last_mouse_down_x_ = -1;
last_mouse_down_y_ = -1;
- current_drag_uri_.clear();
+ current_drag_result_.clear();
drag_index_ = ~0;
// We need this because the drag can start in a ResultViewGrid and can
diff --git a/dash/ResultViewGrid.h b/dash/ResultViewGrid.h
index 822689980..9c066185d 100644
--- a/dash/ResultViewGrid.h
+++ b/dash/ResultViewGrid.h
@@ -23,7 +23,6 @@
#ifndef UNITYSHELL_RESULTVIEWGRID_H
#define UNITYSHELL_RESULTVIEWGRID_H
-#include <UnityCore/Categories.h>
#include <UnityCore/GLibSource.h>
#include "ResultView.h"
@@ -53,10 +52,12 @@ public:
int GetSelectedIndex();
virtual unsigned GetIndexAtPosition(int x, int y);
- virtual void Activate(std::string const& uri, int index, ActivateType type);
+ virtual void Activate(LocalResult const& local_result, int index, ActivateType type);
virtual void RenderResultTexture(ResultViewTexture::Ptr const& result_texture);
+ virtual void GetResultDimensions(int& rows, int& columns);
+
protected:
void MouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags);
void MouseClick(int x, int y, unsigned long button_flags, unsigned long key_flags);
@@ -79,8 +80,8 @@ protected:
virtual void UpdateRenderTextures();
- void AddResult(Result& result);
- void RemoveResult(Result& result);
+ virtual void AddResult(Result const& result);
+ virtual void RemoveResult(Result const& result);
// This is overridden so we can include position of results.
virtual debug::ResultWrapper* CreateResultWrapper(Result const& result, int index);
@@ -93,25 +94,26 @@ private:
void DrawRow(nux::GraphicsEngine& GfxContext, ResultListBounds const& visible_bounds, int row_index, int y_position, nux::Geometry const& absolute_position);
void QueueLazyLoad();
- void QueueViewChanged();
+ void QueueResultsChanged();
bool DoLazyLoad();
int GetItemsPerRow();
void SizeReallocate();
- std::tuple<int, int> GetResultPosition(const std::string& uri);
+ std::tuple<int, int> GetResultPosition(LocalResult const& local_result);
std::tuple<int, int> GetResultPosition(const unsigned int& index);
unsigned mouse_over_index_;
int active_index_;
nux::Property<int> selected_index_;
- std::string focused_uri_;
+ LocalResult focused_result_;
- std::string activated_uri_;
+ LocalResult activated_result_;
unsigned last_lazy_loaded_result_;
+ bool all_results_preloaded_;
int last_mouse_down_x_;
int last_mouse_down_y_;
- std::string current_drag_uri_;
+ LocalResult current_drag_result_;
unsigned drag_index_;
int recorded_dash_width_;
@@ -124,7 +126,7 @@ private:
UBusManager ubus_;
glib::Source::UniquePtr lazy_load_source_;
- glib::Source::UniquePtr view_changed_idle_;
+ glib::Source::UniquePtr results_changed_idle_;
nux::Color background_color_;
};
diff --git a/dash/LensBar.cpp b/dash/ScopeBar.cpp
index d01689626..ce9f87690 100644
--- a/dash/LensBar.cpp
+++ b/dash/ScopeBar.cpp
@@ -17,7 +17,7 @@
*/
#include <glib/gstdio.h>
-#include "LensBar.h"
+#include "ScopeBar.h"
#include <NuxCore/Logger.h>
#include "config.h"
#include <Nux/HLayout.h>
@@ -27,25 +27,24 @@
#include "unity-shared/StaticCairoText.h"
#include "unity-shared/CairoTexture.h"
#include "unity-shared/GraphicsUtils.h"
-#include "LensBar.h"
#include "unity-shared/UBusMessages.h"
namespace unity
{
namespace dash
{
-DECLARE_LOGGER(logger, "unity.dash.lensbar");
+DECLARE_LOGGER(logger, "unity.dash.scopebar");
namespace
{
-// according to Q design the inner area of the lensbar should be 40px
+// according to Q design the inner area of the scopebar should be 40px
// (without any borders)
-const int LENSBAR_HEIGHT = 41;
+const int SCOPEBAR_HEIGHT = 41;
}
-NUX_IMPLEMENT_OBJECT_TYPE(LensBar);
+NUX_IMPLEMENT_OBJECT_TYPE(ScopeBar);
-LensBar::LensBar()
+ScopeBar::ScopeBar()
: nux::View(NUX_TRACKER_LOCATION)
, info_previously_shown_(false)
{
@@ -55,10 +54,9 @@ LensBar::LensBar()
SetupBackground();
SetupLayout();
- SetupHomeLens();
}
-void LensBar::SetupBackground()
+void ScopeBar::SetupBackground()
{
nux::ROPConfig rop;
rop.Blend = true;
@@ -67,7 +65,7 @@ void LensBar::SetupBackground()
bg_layer_.reset(new nux::ColorLayer(nux::Color(0.0f, 0.0f, 0.0f, 0.2f), true, rop));
}
-void LensBar::SetupLayout()
+void ScopeBar::SetupLayout()
{
legal_layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
std::string legal_text("<span underline='single'>");
@@ -113,24 +111,11 @@ void LensBar::SetupLayout()
SetLayout(layered_layout_);
- SetMinimumHeight(LENSBAR_HEIGHT);
- SetMaximumHeight(LENSBAR_HEIGHT);
+ SetMinimumHeight(SCOPEBAR_HEIGHT);
+ SetMaximumHeight(SCOPEBAR_HEIGHT);
}
-void LensBar::SetupHomeLens()
-{
- LensBarIcon* icon = new LensBarIcon("home.lens", PKGDATADIR"/lens-nav-home.svg");
- icon->SetVisible(true);
- icon->active = true;
- icons_.push_back(icon);
- layout_->AddView(icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL);
- AddChild(icon);
-
- icon->mouse_click.connect([&, icon] (int x, int y, unsigned long button, unsigned long keyboard) { SetActive(icon); });
- icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
-}
-
-void LensBar::DoOpenLegalise()
+void ScopeBar::DoOpenLegalise()
{
glib::Error error;
std::string legal_file_path = "file://";
@@ -147,11 +132,12 @@ void LensBar::DoOpenLegalise()
ubus_.SendMessage(UBUS_OVERLAY_CLOSE_REQUEST);
}
-void LensBar::AddLens(Lens::Ptr& lens)
+void ScopeBar::AddScope(Scope::Ptr const& scope)
{
- LensBarIcon* icon = new LensBarIcon(lens->id, lens->icon_hint);
- icon->SetVisible(lens->visible);
- lens->visible.changed.connect([icon](bool visible) { icon->SetVisible(visible); } );
+ ScopeBarIcon* icon = new ScopeBarIcon(scope->id, scope->icon_hint);
+
+ icon->SetVisible(scope->visible);
+ scope->visible.changed.connect([icon](bool visible) { icon->SetVisible(visible); } );
icons_.push_back(icon);
layout_->AddView(icon, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
AddChild(icon);
@@ -160,7 +146,7 @@ void LensBar::AddLens(Lens::Ptr& lens)
icon->key_nav_focus_activate.connect([&, icon](nux::Area*){ SetActive(icon); });
}
-void LensBar::Activate(std::string id)
+void ScopeBar::Activate(std::string id)
{
for (auto icon: icons_)
{
@@ -172,7 +158,7 @@ void LensBar::Activate(std::string id)
}
}
-void LensBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
+void ScopeBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
nux::Geometry const& base = GetGeometry();
@@ -190,7 +176,7 @@ void LensBar::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
graphics_engine.PopClippingRectangle();
}
-void LensBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
+void ScopeBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
nux::Geometry const& base = GetGeometry();
@@ -201,7 +187,7 @@ void LensBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
if (RedirectedAncestor())
{
- // Whole Lens bar needs to be cleared because the PaintAll forces redraw.
+ // Whole Scope bar needs to be cleared because the PaintAll forces redraw.
graphics::ClearGeometry(base);
}
@@ -251,10 +237,10 @@ void LensBar::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
graphics_engine.PopClippingRectangle();
}
-nux::Area* LensBar::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
+nux::Area* ScopeBar::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
{
//LayeredLayout is acting a little screwy, events are not passing past the first layout like instructed,
- //so we manually override if the cursor is on the right hand side of the lensbar
+ //so we manually override if the cursor is on the right hand side of the scopebar
auto geo = GetAbsoluteGeometry();
int info_width = (info_previously_shown_) ? info_icon_->GetGeometry().width : legal_->GetGeometry().width;
@@ -272,7 +258,7 @@ nux::Area* LensBar::FindAreaUnderMouse(const nux::Point& mouse_position, nux::Nu
}
-void LensBar::SetActive(LensBarIcon* activated)
+void ScopeBar::SetActive(ScopeBarIcon* activated)
{
bool state_changed = false;
@@ -287,24 +273,17 @@ void LensBar::SetActive(LensBarIcon* activated)
}
if (state_changed)
- lens_activated.emit(activated->id);
+ scope_activated.emit(activated->id);
}
-void LensBar::ActivateNext()
+void ScopeBar::ActivateNext()
{
- // Special case when switching from the command lens.
- if (GetActiveLensId() == "commands.lens")
- {
- SetActive(icons_[0]);
- return;
- }
-
bool activate_next = false;
for (auto it = icons_.begin();
it < icons_.end();
it++)
{
- LensBarIcon *icon = *it;
+ ScopeBarIcon *icon = *it;
if (activate_next && icon->IsVisible())
{
@@ -314,25 +293,27 @@ void LensBar::ActivateNext()
if (icon->active)
activate_next = true;
}
- SetActive(icons_[0]);
-
-}
-void LensBar::ActivatePrevious()
-{
- // Special case when switching from the command lens.
- if (GetActiveLensId() == "commands.lens")
+ // fallback. select first visible icon.
+ for (auto it = icons_.begin(); it != icons_.end(); ++it)
{
- SetActive(icons_.back());
- return;
+ ScopeBarIcon *icon = *it;
+ if (icon->IsVisible())
+ {
+ SetActive(icon);
+ break;
+ }
}
+}
+void ScopeBar::ActivatePrevious()
+{
bool activate_previous = false;
- for (auto it = icons_.rbegin();
- it < icons_.rend();
- ++it)
+ for (auto rit = icons_.rbegin();
+ rit < icons_.rend();
+ ++rit)
{
- LensBarIcon *icon = *it;
+ ScopeBarIcon *icon = *rit;
if (activate_previous && icon->IsVisible())
{
@@ -342,39 +323,48 @@ void LensBar::ActivatePrevious()
if (icon->active)
activate_previous = true;
}
- SetActive(icons_.back());
+ // fallback. select last visible icon.
+ for (auto rit = icons_.rbegin(); rit != icons_.rend(); ++rit)
+ {
+ ScopeBarIcon *icon = *rit;
+ if (icon->IsVisible())
+ {
+ SetActive(icon);
+ break;
+ }
+ }
}
// Keyboard navigation
-bool LensBar::AcceptKeyNavFocus()
+bool ScopeBar::AcceptKeyNavFocus()
{
return false;
}
// Introspectable
-std::string LensBar::GetName() const
+std::string ScopeBar::GetName() const
{
- return "LensBar";
+ return "ScopeBar";
}
-void LensBar::AddProperties(GVariantBuilder* builder)
+void ScopeBar::AddProperties(GVariantBuilder* builder)
{
unity::variant::BuilderWrapper wrapper(builder);
- wrapper.add("focused-lens-icon", "");
+ wrapper.add("focused-scope-icon", "");
for( auto icon : icons_)
{
if (icon->active)
- wrapper.add("active-lens", icon->id.Get());
+ wrapper.add("active-scope", icon->id.Get());
if (icon->HasKeyFocus())
- wrapper.add("focused-lens-icon", icon->id.Get());
+ wrapper.add("focused-scope-icon", icon->id.Get());
}
}
-std::string LensBar::GetActiveLensId() const
+std::string ScopeBar::GetActiveScopeId() const
{
for (auto icon : icons_)
{
diff --git a/dash/LensBar.h b/dash/ScopeBar.h
index 49869736c..fa87eea88 100644
--- a/dash/LensBar.h
+++ b/dash/ScopeBar.h
@@ -16,8 +16,8 @@
* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
*/
-#ifndef UNITYSHELL_LENS_BAR_H
-#define UNITYSHELL_LENS_BAR_H
+#ifndef UNITYSHELL_SCOPE_BAR_H
+#define UNITYSHELL_SCOPE_BAR_H
#include <memory>
#include <string>
@@ -27,12 +27,12 @@
#include <Nux/Nux.h>
#include <Nux/PaintLayer.h>
#include <Nux/View.h>
-#include <UnityCore/Lens.h>
+#include <UnityCore/Scope.h>
#include "unity-shared/IconTexture.h"
#include "unity-shared/Introspectable.h"
#include "unity-shared/UBusWrapper.h"
-#include "LensBarIcon.h"
+#include "ScopeBarIcon.h"
namespace nux
{
@@ -49,26 +49,26 @@ class StaticCairoText;
namespace dash
{
-class LensBar : public nux::View, public unity::debug::Introspectable
+class ScopeBar : public nux::View, public unity::debug::Introspectable
{
- NUX_DECLARE_OBJECT_TYPE(LensBar, nux::View);
- typedef std::vector<LensBarIcon*> LensIcons;
+ NUX_DECLARE_OBJECT_TYPE(ScopeBar, nux::View);
+ typedef std::vector<ScopeBarIcon*> ScopeIcons;
public:
- LensBar();
+ ScopeBar();
- void AddLens(Lens::Ptr& lens);
+ void AddScope(Scope::Ptr const& scope);
void Activate(std::string id);
void ActivateNext();
void ActivatePrevious();
- std::string GetActiveLensId() const;
- sigc::signal<void, std::string const&> lens_activated;
+ std::string GetActiveScopeId() const;
+
+ sigc::signal<void, std::string const&> scope_activated;
private:
void SetupBackground();
void SetupLayout();
- void SetupHomeLens();
void DoOpenLegalise();
void Draw(nux::GraphicsEngine& gfx_context, bool force_draw);
@@ -76,7 +76,7 @@ private:
nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type);
- void SetActive(LensBarIcon* icon);
+ void SetActive(ScopeBarIcon* icon);
bool AcceptKeyNavFocus();
std::string GetName() const;
@@ -84,7 +84,7 @@ private:
typedef std::unique_ptr<nux::AbstractPaintLayer> LayerPtr;
- LensIcons icons_;
+ ScopeIcons icons_;
UBusManager ubus_;
@@ -97,9 +97,11 @@ private:
bool info_previously_shown_;
std::string legal_seen_file_path_;
+
+ friend class TestScopeBar;
};
} // namespace dash
} // namespace unity
-#endif // UNITYSHELL_LENS_BAR_H
+#endif // UNITYSHELL_SCOPE_BAR_H
diff --git a/dash/LensBarIcon.cpp b/dash/ScopeBarIcon.cpp
index 3f4a7682b..ed8519cc8 100644
--- a/dash/LensBarIcon.cpp
+++ b/dash/ScopeBarIcon.cpp
@@ -19,7 +19,7 @@
#include <UnityCore/Variant.h>
#include "unity-shared/DashStyle.h"
-#include "LensBarIcon.h"
+#include "ScopeBarIcon.h"
#include "config.h"
@@ -35,9 +35,9 @@ const int FOCUS_OVERLAY_WIDTH = 60;
}
-NUX_IMPLEMENT_OBJECT_TYPE(LensBarIcon);
+NUX_IMPLEMENT_OBJECT_TYPE(ScopeBarIcon);
-LensBarIcon::LensBarIcon(std::string id_, std::string icon_hint)
+ScopeBarIcon::ScopeBarIcon(std::string id_, std::string icon_hint)
: IconTexture(icon_hint, 24)
, id(id_)
, active(false)
@@ -56,14 +56,14 @@ LensBarIcon::LensBarIcon(std::string id_, std::string icon_hint)
SetAcceptKeyNavFocusOnMouseDown(false);
SetAcceptKeyNavFocusOnMouseEnter(true);
- active.changed.connect(sigc::mem_fun(this, &LensBarIcon::OnActiveChanged));
+ active.changed.connect(sigc::mem_fun(this, &ScopeBarIcon::OnActiveChanged));
key_nav_focus_change.connect([&](nux::Area*, bool, nux::KeyNavDirection){ QueueDraw(); });
}
-LensBarIcon::~LensBarIcon()
+ScopeBarIcon::~ScopeBarIcon()
{}
-void LensBarIcon::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
+void ScopeBarIcon::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
{
nux::Geometry const& geo = GetGeometry();
@@ -109,18 +109,18 @@ void LensBarIcon::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
graphics_engine.PopClippingRectangle();
}
-void LensBarIcon::OnActiveChanged(bool is_active)
+void ScopeBarIcon::OnActiveChanged(bool is_active)
{
QueueDraw();
}
// Introspectable
-std::string LensBarIcon::GetName() const
+std::string ScopeBarIcon::GetName() const
{
- return "LensBarIcon";
+ return "ScopeBarIcon";
}
-void LensBarIcon::AddProperties(GVariantBuilder* builder)
+void ScopeBarIcon::AddProperties(GVariantBuilder* builder)
{
unity::variant::BuilderWrapper wrapper(builder);
diff --git a/dash/LensBarIcon.h b/dash/ScopeBarIcon.h
index ba150d8cb..a07d64e47 100644
--- a/dash/LensBarIcon.h
+++ b/dash/ScopeBarIcon.h
@@ -16,8 +16,8 @@
* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
*/
-#ifndef UNITY_LENS_BAR_ICON_H_
-#define UNITY_LENS_BAR_ICON_H_
+#ifndef UNITY_SCOPE_BAR_ICON_H_
+#define UNITY_SCOPE_BAR_ICON_H_
#include <string>
@@ -33,12 +33,12 @@ namespace unity
namespace dash
{
-class LensBarIcon : public IconTexture
+class ScopeBarIcon : public IconTexture
{
- NUX_DECLARE_OBJECT_TYPE(LensBarIcon, IconTexture);
+ NUX_DECLARE_OBJECT_TYPE(ScopeBarIcon, IconTexture);
public:
- LensBarIcon(std::string id, std::string icon_hint);
- ~LensBarIcon();
+ ScopeBarIcon(std::string id, std::string icon_hint);
+ ~ScopeBarIcon();
nux::Property<std::string> id;
nux::Property<bool> active;
@@ -60,4 +60,4 @@ private:
}
}
-#endif
+#endif // UNITY_SCOPE_BAR_ICON_H_
diff --git a/dash/ScopeView.cpp b/dash/ScopeView.cpp
new file mode 100755
index 000000000..ee85a9b48
--- /dev/null
+++ b/dash/ScopeView.cpp
@@ -0,0 +1,1106 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright (C) 2010, 2011 Canonical Ltd
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 3 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
+ */
+
+#include "ScopeView.h"
+
+#include <boost/lexical_cast.hpp>
+
+#include <NuxCore/Logger.h>
+#include <Nux/HScrollBar.h>
+#include <Nux/VScrollBar.h>
+
+#include "unity-shared/DashStyle.h"
+#include "CoverflowResultView.h"
+
+#include "ResultRendererTile.h"
+#include "ResultRendererHorizontalTile.h"
+#include "unity-shared/UBusMessages.h"
+#include "unity-shared/UBusWrapper.h"
+#include "unity-shared/PlacesOverlayVScrollBar.h"
+#include "unity-shared/GraphicsUtils.h"
+
+#include "config.h"
+#include <glib/gi18n-lib.h>
+
+namespace unity
+{
+namespace dash
+{
+DECLARE_LOGGER(logger, "unity.dash.scopeview");
+namespace
+{
+const int CARD_VIEW_GAP_VERT = 24; // pixels
+const int CARD_VIEW_GAP_HORIZ = 25; // pixels
+}
+
+// This is so we can access some protected members in scrollview.
+class ScopeScrollView: public nux::ScrollView
+{
+public:
+ ScopeScrollView(nux::VScrollBar* scroll_bar, NUX_FILE_LINE_DECL)
+ : nux::ScrollView(NUX_FILE_LINE_PARAM)
+ , right_area_(nullptr)
+ , up_area_(nullptr)
+ {
+ SetVScrollBar(scroll_bar);
+
+ OnVisibleChanged.connect([&] (nux::Area* /*area*/, bool visible) {
+ if (m_horizontal_scrollbar_enable)
+ _hscrollbar->SetVisible(visible);
+ if (m_vertical_scrollbar_enable)
+ _vscrollbar->SetVisible(visible);
+ });
+ }
+
+ void ScrollToPosition(nux::Geometry const& position)
+ {
+ // much of this code is copied from Nux/ScrollView.cpp
+ nux::Geometry const& geo = GetGeometry();
+
+ int child_y = position.y - geo.y;
+ int child_y_diff = child_y - abs (_delta_y);
+
+ if (child_y_diff + position.height < geo.height && child_y_diff >= 0)
+ {
+ return;
+ }
+
+ if (child_y_diff < 0)
+ {
+ ScrollUp (1, abs (child_y_diff));
+ }
+ else
+ {
+ int size = child_y_diff - geo.height;
+
+ // always keeps the top of a view on the screen
+ size += position.height;
+
+ ScrollDown (1, size);
+ }
+ }
+
+ void SetRightArea(nux::Area* area)
+ {
+ right_area_ = area;
+ }
+
+ void SetUpArea(nux::Area* area)
+ {
+ up_area_ = area;
+ }
+
+ void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
+ {
+ if (RedirectedAncestor())
+ {
+ if (m_horizontal_scrollbar_enable && _hscrollbar->IsRedrawNeeded())
+ graphics::ClearGeometry(_hscrollbar->GetGeometry());
+ if (m_vertical_scrollbar_enable && _vscrollbar->IsRedrawNeeded())
+ graphics::ClearGeometry(_vscrollbar->GetGeometry());
+ }
+
+ ScrollView::DrawContent(graphics_engine, force_draw);
+ }
+
+ void EnableScrolling(bool enable_scrolling)
+ {
+ _vscrollbar->SetInputEventSensitivity(enable_scrolling);
+ }
+
+protected:
+
+ // This is so we can break the natural key navigation path.
+ nux::Area* KeyNavIteration(nux::KeyNavDirection direction)
+ {
+ nux::Area* focus_area = nux::GetWindowCompositor().GetKeyFocusArea();
+
+ if (direction == nux::KEY_NAV_RIGHT && focus_area && focus_area->IsChildOf(this))
+ return right_area_;
+ else if (direction == nux::KEY_NAV_UP && focus_area && focus_area->IsChildOf(this))
+ return up_area_;
+ else
+ return nux::ScrollView::KeyNavIteration(direction);
+ }
+
+private:
+ nux::Area* right_area_;
+ nux::Area* up_area_;
+};
+
+
+NUX_IMPLEMENT_OBJECT_TYPE(ScopeView);
+
+ScopeView::ScopeView(Scope::Ptr scope, nux::Area* show_filters)
+: nux::View(NUX_TRACKER_LOCATION)
+, filters_expanded(false)
+, can_refine_search(false)
+, scope_(scope)
+, cancellable_(g_cancellable_new())
+, no_results_active_(false)
+, last_good_filter_model_(-1)
+, filter_expansion_pushed_(false)
+, scope_connected_(scope ? scope->connected : false)
+, search_on_next_connect_(false)
+{
+ SetupViews(show_filters);
+
+ search_string.SetGetterFunction(sigc::mem_fun(this, &ScopeView::get_search_string));
+ filters_expanded.changed.connect(sigc::mem_fun(this, &ScopeView::OnScopeFilterExpanded));
+ view_type.changed.connect(sigc::mem_fun(this, &ScopeView::OnViewTypeChanged));
+
+ if (scope_)
+ {
+ categories_updated = scope_->categories.changed.connect([this](Categories::Ptr const& categories) { SetupCategories(categories); });
+ SetupCategories(scope->categories);
+
+ results_updated = scope_->results.changed.connect([this](Results::Ptr const& results) { SetupResults(results); });
+ SetupResults(scope->results);
+
+ filters_updated = scope_->filters.changed.connect([this](Filters::Ptr const& filters) { SetupFilters(filters); });
+ SetupFilters(scope->filters);
+
+ scope_->connected.changed.connect([&](bool is_connected)
+ {
+ // We need to search again if we were reconnected after being connected before.
+ if (scope_connected_ && !is_connected)
+ search_on_next_connect_ = true;
+ else if (is_connected && search_on_next_connect_)
+ {
+ search_on_next_connect_ = false;
+ if (IsVisible())
+ PerformSearch(search_string_, nullptr);
+ }
+ scope_connected_ = is_connected;
+ });
+ }
+
+ ubus_manager_.RegisterInterest(UBUS_RESULT_VIEW_KEYNAV_CHANGED, [&] (GVariant* data) {
+ // we get this signal when a result view keynav changes,
+ // its a bad way of doing this but nux ABI needs to be broken
+ // to do it properly
+ nux::Geometry focused_pos;
+ g_variant_get (data, "(iiii)", &focused_pos.x, &focused_pos.y, &focused_pos.width, &focused_pos.height);
+
+ for (auto group : category_views_)
+ {
+ if (group->GetLayout() != nullptr)
+ {
+ auto expand_label = group->GetHeaderFocusableView();
+ auto child = group->GetChildView();
+
+ if ((child && child->HasKeyFocus()) ||
+ (expand_label && expand_label->HasKeyFocus()))
+ {
+ focused_pos.x += child->GetGeometry().x;
+ focused_pos.y += child->GetGeometry().y - 30;
+ focused_pos.height += 30;
+ scroll_view_->ScrollToPosition(focused_pos);
+ break;
+ }
+ }
+ }
+ });
+
+ OnVisibleChanged.connect([&] (nux::Area* area, bool visible) {
+ scroll_view_->SetVisible(visible);
+ });
+}
+
+ScopeView::~ScopeView()
+{
+ results_updated.disconnect();
+ result_added_connection.disconnect();
+ result_removed_connection.disconnect();
+
+ categories_updated.disconnect();
+ category_added_connection.disconnect();
+ category_changed_connection.disconnect();
+ category_removed_connection.disconnect();
+
+ filters_updated.disconnect();
+ filter_added_connection.disconnect();
+ filter_removed_connection.disconnect();
+
+ g_cancellable_cancel(cancellable_);
+ if (search_cancellable_) g_cancellable_cancel(search_cancellable_);
+}
+
+void ScopeView::SetupViews(nux::Area* show_filters)
+{
+ dash::Style& style = dash::Style::Instance();
+
+ layout_ = new nux::HLayout(NUX_TRACKER_LOCATION);
+ layout_->SetSpaceBetweenChildren(style.GetSpaceBetweenScopeAndFilters());
+
+ scroll_view_ = new ScopeScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION),
+ NUX_TRACKER_LOCATION);
+ scroll_view_->EnableVerticalScrollBar(true);
+ scroll_view_->EnableHorizontalScrollBar(false);
+ layout_->AddView(scroll_view_);
+
+ scroll_layout_ = new nux::VLayout(NUX_TRACKER_LOCATION);
+ scroll_view_->SetLayout(scroll_layout_);
+ scroll_view_->SetRightArea(show_filters);
+
+ no_results_ = new StaticCairoText("", NUX_TRACKER_LOCATION);
+ no_results_->SetTextColor(nux::color::White);
+ no_results_->SetVisible(false);
+ scroll_layout_->AddView(no_results_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
+
+ fscroll_view_ = new ScopeScrollView(new PlacesOverlayVScrollBar(NUX_TRACKER_LOCATION), NUX_TRACKER_LOCATION);
+ fscroll_view_->EnableVerticalScrollBar(true);
+ fscroll_view_->EnableHorizontalScrollBar(false);
+ fscroll_view_->SetVisible(false);
+ fscroll_view_->SetUpArea(show_filters);
+ layout_->AddView(fscroll_view_, 1);
+
+ fscroll_layout_ = new nux::VLayout();
+ fscroll_view_->SetLayout(fscroll_layout_);
+
+ filter_bar_ = new FilterBar();
+ int width = style.GetFilterBarWidth() +
+ style.GetFilterBarLeftPadding() +
+ style.GetFilterBarRightPadding();
+
+ fscroll_view_->SetMinimumWidth(width + style.GetFilterViewRightPadding());
+ fscroll_view_->SetMaximumWidth(width + style.GetFilterViewRightPadding());
+ filter_bar_->SetMinimumWidth(width);
+ filter_bar_->SetMaximumWidth(width);
+ AddChild(filter_bar_);
+ fscroll_layout_->AddView(filter_bar_, 0);
+
+ SetLayout(layout_);
+}
+
+void ScopeView::SetupCategories(Categories::Ptr const& categories)
+{
+ category_added_connection.disconnect();
+ category_changed_connection.disconnect();
+ category_removed_connection.disconnect();
+
+ if (!categories)
+ return;
+
+ category_added_connection = categories->category_added.connect(sigc::mem_fun(this, &ScopeView::OnCategoryAdded));
+ category_changed_connection = categories->category_changed.connect(sigc::mem_fun(this, &ScopeView::OnCategoryChanged));
+ category_removed_connection = categories->category_removed.connect(sigc::mem_fun(this, &ScopeView::OnCategoryRemoved));
+
+ auto resync_categories = [categories, this] (glib::Object<DeeModel> model)
+ {
+ ClearCategories();
+ for (unsigned int i = 0; i < categories->count(); ++i)
+ OnCategoryAdded(categories->RowAtIndex(i));
+ };
+
+ categories->model.changed.connect(resync_categories);
+ resync_categories(categories->model());
+
+ scope_->category_order.changed.connect([this](std::vector<unsigned int> const& category_order) {
+ category_order_ = category_order;
+ OnCategoryOrderChanged();
+ });
+}
+
+
+void ScopeView::OnCategoryOrderChanged()
+{
+ LOG_DEBUG(logger) << "Reordering categories for " << scope_->name();
+
+ for (auto iter = category_views_.begin(); iter != category_views_.end(); ++iter)
+ {
+ PlacesGroup::Ptr group = *iter;
+ scroll_layout_->RemoveChildObject(group.GetPointer());
+ }
+
+ if (scope_)
+ {
+ Categories::Ptr category_model = scope_->categories();
+ if (!category_model)
+ return;
+
+ // there should be ~10 categories, so this shouldn't be too big of a deal
+ for (unsigned i = 0; i < category_order_.size(); i++)
+ {
+ unsigned int desired_category_index = category_order_[i];
+
+ if (category_views_.size() <= desired_category_index)
+ continue;
+
+ scroll_layout_->AddView(category_views_[desired_category_index].GetPointer(), 0);
+ }
+ }
+ QueueRelayout();
+}
+
+void ScopeView::SetupResults(Results::Ptr const& results)
+{
+ result_added_connection.disconnect();
+ result_removed_connection.disconnect();
+
+ if (!results)
+ return;
+
+ result_added_connection = results->result_added.connect(sigc::mem_fun(this, &ScopeView::OnResultAdded));
+ result_added_connection = results->result_removed.connect(sigc::mem_fun(this, &ScopeView::OnResultRemoved));
+
+ results->model.changed.connect([this] (glib::Object<DeeModel> model)
+ {
+ for (unsigned int i = 0; i < category_views_.size(); ++i)
+ {
+ ResultView* result_view = GetResultViewForCategory(i);
+ if (result_view)
+ {
+ result_view->SetResultsModel(scope_->GetResultsForCategory(i));
+ }
+ }
+ });
+
+ for (unsigned int i = 0; i < results->count(); ++i)
+ OnResultAdded(results->RowAtIndex(i));
+}
+
+void ScopeView::SetupFilters(Filters::Ptr const& filters)
+{
+ filter_added_connection.disconnect();
+ filter_removed_connection.disconnect();
+
+ if (!filters)
+ return;
+
+ filter_added_connection = filters->filter_added.connect(sigc::mem_fun(this, &ScopeView::OnFilterAdded));
+ filter_removed_connection = filters->filter_removed.connect(sigc::mem_fun(this, &ScopeView::OnFilterRemoved));
+
+ auto resync_filters = [filters, this] (glib::Object<DeeModel> model)
+ {
+ bool blocked = filter_added_connection.block(true);
+
+ filter_bar_->ClearFilters();
+ for (unsigned int i = 0; i < filters->count(); ++i)
+ OnFilterAdded(filters->FilterAtIndex(i));
+
+ filter_added_connection.block(blocked);
+ };
+
+ filters->model.changed.connect(resync_filters);
+ resync_filters(filters->model());
+}
+
+void ScopeView::OnCategoryAdded(Category const& category)
+{
+ std::string name = category.name;
+ std::string icon_hint = category.icon_hint;
+ std::string renderer_name = category.renderer_name;
+ if (category.index == unsigned(-1))
+ return;
+ unsigned index = category.index;
+ bool reset_filter_models = index < category_views_.size();
+
+ LOG_DEBUG(logger) << "Category added '" << (scope_ ? scope_->name() : "unknown") << "': "
+ << name
+ << "(" << icon_hint
+ << ", " << renderer_name
+ << ", " << boost::lexical_cast<int>(index) << ")";
+
+
+ PlacesGroup::Ptr group(CreatePlacesGroup(category));
+ AddChild(group.GetPointer());
+ group->SetName(name);
+ group->SetIcon(icon_hint);
+ group->SetExpanded(false);
+ group->SetVisible(false);
+
+ int view_index = category_order_.size();
+ auto find_view_index = std::find(category_order_.begin(), category_order_.end(), index);
+ if (find_view_index == category_order_.end())
+ {
+ category_order_.push_back(index);
+ }
+ else
+ view_index = find_view_index - category_order_.begin();
+
+ category_views_.insert(category_views_.begin() + index, group);
+
+ group->expanded.connect(sigc::mem_fun(this, &ScopeView::OnGroupExpanded));
+
+ /* Reset result count */
+ counts_[group] = 0;
+
+ ResultView* results_view = nullptr;
+ if (category.renderer_name == "tile-horizontal")
+ {
+ results_view = new ResultViewGrid(NUX_TRACKER_LOCATION);
+ results_view->SetModelRenderer(new ResultRendererHorizontalTile(NUX_TRACKER_LOCATION));
+ static_cast<ResultViewGrid*> (results_view)->horizontal_spacing = CARD_VIEW_GAP_HORIZ;
+ static_cast<ResultViewGrid*> (results_view)->vertical_spacing = CARD_VIEW_GAP_VERT;
+ }
+ else
+ {
+ results_view = new ResultViewGrid(NUX_TRACKER_LOCATION);
+ results_view->SetModelRenderer(new ResultRendererTile(NUX_TRACKER_LOCATION));
+ }
+
+ if (scope_)
+ {
+ std::string unique_id = category.name() + scope_->name();
+ results_view->unique_id = unique_id;
+ results_view->expanded = false;
+
+ results_view->ResultActivated.connect([this, unique_id] (LocalResult const& local_result, ResultView::ActivateType type, GVariant* data)
+ {
+ result_activated.emit(type, local_result, data, unique_id);
+ switch (type)
+ {
+ case ResultView::ActivateType::DIRECT:
+ {
+ scope_->Activate(local_result, nullptr, cancellable_);
+ } break;
+ case ResultView::ActivateType::PREVIEW:
+ {
+ scope_->Preview(local_result, nullptr, cancellable_);
+ } break;
+ default: break;
+ };
+ });
+
+ /* Set up filter model for this category */
+ Results::Ptr results_model = scope_->GetResultsForCategory(index);
+ counts_[group] = results_model ? results_model->count() : 0;
+
+ results_view->SetResultsModel(results_model);
+ }
+
+ group->SetChildView(results_view);
+
+ /* We need the full range of method args so we can specify the offset
+ * of the group into the layout */
+ scroll_layout_->AddView(group.GetPointer(), 0, nux::MinorDimensionPosition::MINOR_POSITION_START,
+ nux::MinorDimensionSize::MINOR_SIZE_FULL, 100.0f,
+ (nux::LayoutPosition)view_index);
+
+ if (reset_filter_models)
+ {
+ QueueReinitializeFilterCategoryModels(index);
+ }
+
+ QueueCategoryCountsCheck();
+}
+
+void ScopeView::OnCategoryChanged(Category const& category)
+{
+ if (category_views_.size() <= category.index)
+ return;
+
+ PlacesGroup::Ptr group = category_views_[category.index];
+
+ group->SetName(category.name);
+ group->SetIcon(category.icon_hint);
+
+ QueueCategoryCountsCheck();
+}
+
+void ScopeView::OnCategoryRemoved(Category const& category)
+{
+ std::string name = category.name;
+ std::string icon_hint = category.icon_hint;
+ std::string renderer_name = category.renderer_name;
+ unsigned index = category.index;
+ if (index == unsigned(-1) || category_views_.size() <= index)
+ return;
+ bool reset_filter_models = index < category_views_.size()-1;
+
+ LOG_DEBUG(logger) << "Category removed '" << (scope_ ? scope_->name() : "unknown") << "': "
+ << name
+ << "(" << icon_hint
+ << ", " << renderer_name
+ << ", " << boost::lexical_cast<int>(index) << ")";
+
+ auto category_pos = category_views_.begin() + index;
+ PlacesGroup::Ptr group = *category_pos;
+
+ if (last_expanded_group_ == group)
+ last_expanded_group_.Release();
+
+ counts_.erase(group);
+ category_views_.erase(category_pos);
+
+ // remove from order
+ auto order_pos = std::find(category_order_.begin(), category_order_.end(), index);
+ if (order_pos != category_order_.end())
+ category_order_.erase(order_pos);
+
+ scroll_layout_->RemoveChildObject(group.GetPointer());
+ RemoveChild(group.GetPointer());
+ QueueRelayout();
+
+ if (reset_filter_models)
+ {
+ QueueReinitializeFilterCategoryModels(index);
+ }
+}
+
+void ScopeView::ClearCategories()
+{
+ for (auto iter = category_views_.begin(), end = category_views_.end(); iter != end; ++iter)
+ {
+ PlacesGroup::Ptr group = *iter;
+ RemoveChild(group.GetPointer());
+ scroll_layout_->RemoveChildObject(group.GetPointer());
+ }
+ counts_.clear();
+ category_views_.clear();
+ last_expanded_group_.Release();
+ QueueRelayout();
+}
+
+void ScopeView::QueueReinitializeFilterCategoryModels(unsigned int start_category_index)
+{
+ if (!scope_)
+ return;
+
+ Categories::Ptr category_model = scope_->categories();
+ unsigned int category_count = 0;
+ if (!category_model || (category_count=category_model->count()) <= start_category_index)
+ return;
+
+ if (category_views_.size() <= (start_category_index + 1))
+ return;
+
+ /* Scope is reodering the categories, and since their category index is based
+ * on the row position in the model, we need to re-initialize the category result
+ * models if we got insert and not an append */
+ for (auto iter = category_views_.begin() + start_category_index +1, end = category_views_.end(); iter != end; ++iter)
+ {
+ ResultView* result_view = (*iter)->GetChildView();
+ if (result_view)
+ result_view->SetResultsModel(Results::Ptr());
+ }
+
+ if (last_good_filter_model_ == -1 || static_cast<int>(start_category_index) < last_good_filter_model_)
+ {
+ last_good_filter_model_ = static_cast<int>(start_category_index);
+ }
+ if (!fix_filter_models_idle_)
+ {
+ fix_filter_models_idle_.reset(new glib::Idle(sigc::mem_fun(this, &ScopeView::ReinitializeCategoryResultModels), glib::Source::Priority::HIGH));
+ }
+}
+
+bool ScopeView::ReinitializeCategoryResultModels()
+{
+ if (!scope_)
+ return false;
+
+ if (last_good_filter_model_ < 0)
+ return false;
+
+ if (category_views_.size() > static_cast<unsigned int>(last_good_filter_model_)+1)
+ {
+ unsigned int category_index = static_cast<unsigned int>(last_good_filter_model_) +1;
+ for (auto iter = category_views_.begin() + category_index, end = category_views_.end(); iter != end; ++iter, category_index++)
+ {
+ ResultView* result_view = (*iter)->GetChildView();
+ if (result_view)
+ result_view->SetResultsModel(scope_->GetResultsForCategory(category_index));
+ }
+ }
+
+ last_good_filter_model_ = -1;
+ fix_filter_models_idle_.reset();
+ return false;
+}
+
+ResultView* ScopeView::GetResultViewForCategory(unsigned int category_index)
+{
+ if (category_views_.size() <= category_index)
+ return nullptr;
+
+ auto category_pos = category_views_.begin() + category_index;
+ PlacesGroup::Ptr group = *category_pos;
+ return static_cast<ResultView*>(group->GetChildView());
+}
+
+void ScopeView::OnResultAdded(Result const& result)
+{
+ // category not added yet.
+ if (category_views_.size() <= result.category_index)
+ return;
+
+ std::string uri = result.uri;
+ LOG_TRACE(logger) << "Result added '" << (scope_ ? scope_->name() : "unknown") << "': " << uri;
+
+ counts_[category_views_[result.category_index]]++;
+ // make sure we don't display the no-results-hint if we do have results
+ CheckNoResults(glib::HintsMap());
+
+ QueueCategoryCountsCheck();
+}
+
+void ScopeView::OnResultRemoved(Result const& result)
+{
+ // category not added yet.
+ if (category_views_.size() <= result.category_index)
+ return;
+
+ std::string uri = result.uri;
+ LOG_TRACE(logger) << "Result removed '" << (scope_ ? scope_->name() : "unknown") << "': " << uri;
+
+ counts_[category_views_[result.category_index]]--;
+ // make sure we don't display the no-results-hint if we do have results
+ CheckNoResults(glib::HintsMap());
+
+ QueueCategoryCountsCheck();
+}
+
+void ScopeView::CheckNoResults(glib::HintsMap const& hints)
+{
+ gint const count = scope_->results()->count();
+
+ if (count == 0)
+ {
+ std::stringstream markup;
+ glib::HintsMap::const_iterator it;
+
+ it = hints.find("no-results-hint");
+ markup << "<span size='larger' weight='bold'>";
+
+ if (it != hints.end())
+ markup << it->second.GetString();
+ else
+ markup << _("Sorry, there is nothing that matches your search.");
+
+ markup << "</span>";
+
+ LOG_DEBUG(logger) << "The no-result-hint is: " << markup.str();
+
+ scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_CENTER);
+
+ no_results_active_ = true;
+ no_results_->SetText(markup.str());
+ no_results_->SetVisible(true);
+ }
+ else if (count && no_results_active_)
+ {
+ scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START);
+
+ no_results_active_ = false;
+ no_results_->SetText("");
+ no_results_->SetVisible(false);
+ }
+}
+
+void ScopeView::QueueCategoryCountsCheck()
+{
+ if (!model_updated_timeout_)
+ {
+ model_updated_timeout_.reset(new glib::Idle([&] () {
+ // Check if all results so far are from one category
+ // If so, then expand that category.
+ CheckCategoryCounts();
+ model_updated_timeout_.reset();
+ return false;
+ }, glib::Source::Priority::HIGH));
+ }
+}
+
+void ScopeView::CheckCategoryCounts()
+{
+ int number_of_displayed_categories = 0;
+
+ PlacesGroup::Ptr new_expanded_group;
+
+ for (auto iter = category_order_.begin(); iter != category_order_.end(); ++iter)
+ {
+ unsigned int category_index = *iter;
+ if (category_views_.size() <= category_index)
+ continue;
+
+ PlacesGroup::Ptr group = category_views_[category_index];
+
+ group->SetCounts(counts_[group]);
+ group->SetVisible(counts_[group] > 0);
+
+ if (counts_[group] > 0)
+ {
+ number_of_displayed_categories++;
+ new_expanded_group = group;
+ }
+ }
+
+ if (new_expanded_group && get_search_string().empty())
+ {
+ // only expand the category if we have only one with results.
+ if (number_of_displayed_categories <= 2)
+ new_expanded_group->SetExpanded(true);
+ if (last_expanded_group_ && last_expanded_group_ != new_expanded_group)
+ last_expanded_group_->SetExpanded(false);
+ }
+ else if (last_expanded_group_)
+ {
+ last_expanded_group_->SetExpanded(false);
+ }
+
+ last_expanded_group_ = new_expanded_group;
+}
+
+void ScopeView::HideResultsMessage()
+{
+ if (no_results_active_)
+ {
+ scroll_layout_->SetContentDistribution(nux::MAJOR_POSITION_START);
+ no_results_active_ = false;
+ no_results_->SetText("");
+ no_results_->SetVisible(false);
+ }
+}
+
+bool ScopeView::PerformSearch(std::string const& search_query, SearchCallback const& callback)
+{
+ search_string_ = search_query;
+ if (scope_)
+ {
+ // 150ms to hide the no reults message if its take a while to return results
+ hide_message_delay_.reset(new glib::Timeout(150, [&] () {
+ HideResultsMessage();
+ return false;
+ }));
+
+ // cancel old search.
+ if (search_cancellable_) g_cancellable_cancel (search_cancellable_);
+ search_cancellable_ = g_cancellable_new ();
+
+ scope_->Search(search_query, [this, callback] (std::string const& search_string, glib::HintsMap const& hints, glib::Error const& err)
+ {
+ if (err && !scope_connected_)
+ {
+ // if we've failed a search due to connection issue, we need to try again when we re-connect
+ search_on_next_connect_ = true;
+ }
+
+ CheckNoResults(hints);
+ hide_message_delay_.reset();
+ if (callback)
+ callback(scope_->id(), search_string, err);
+ }, search_cancellable_);
+ return true;
+ }
+ return false;
+}
+
+std::string ScopeView::get_search_string() const
+{
+ return search_string_;
+}
+
+void ScopeView::OnGroupExpanded(PlacesGroup* group)
+{
+ ResultViewGrid* grid = static_cast<ResultViewGrid*>(group->GetChildView());
+ grid->expanded = group->GetExpanded();
+
+ QueueRelayout();
+}
+
+void ScopeView::CheckScrollBarState()
+{
+ if (scroll_layout_->GetHeight() > scroll_view_->GetHeight())
+ {
+ scroll_view_->EnableVerticalScrollBar(true);
+ }
+ else
+ {
+ scroll_view_->EnableVerticalScrollBar(false);
+ }
+}
+
+void ScopeView::OnFilterAdded(Filter::Ptr filter)
+{
+ filter_bar_->AddFilter(filter);
+ can_refine_search = true;
+}
+
+void ScopeView::OnFilterRemoved(Filter::Ptr filter)
+{
+ filter_bar_->RemoveFilter(filter);
+}
+
+void ScopeView::OnViewTypeChanged(ScopeViewType view_type)
+{
+ if (!scope_)
+ return;
+
+ scope_->view_type = view_type;
+}
+
+void ScopeView::OnScopeFilterExpanded(bool expanded)
+{
+ if (fscroll_view_->IsVisible() != expanded)
+ {
+ fscroll_view_->SetVisible(expanded);
+ QueueRelayout();
+ }
+
+ for (auto category_view : category_views_)
+ category_view->SetFiltersExpanded(expanded);
+}
+
+void ScopeView::Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
+{
+ if (RedirectedAncestor())
+ graphics::ClearGeometry(GetGeometry());
+}
+
+void ScopeView::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
+{
+ nux::Geometry const& geo = GetGeometry();
+ graphics_engine.PushClippingRectangle(geo);
+ CheckScrollBarState();
+
+ if (!IsFullRedraw() && RedirectedAncestor())
+ {
+ if (filter_bar_ && filter_bar_->IsVisible() && filter_bar_->IsRedrawNeeded())
+ graphics::ClearGeometry(filter_bar_->GetGeometry());
+ else if (no_results_ && no_results_->IsVisible() && no_results_->IsRedrawNeeded())
+ graphics::ClearGeometry(no_results_->GetGeometry());
+ }
+
+ layout_->ProcessDraw(graphics_engine, force_draw);
+ graphics_engine.PopClippingRectangle();
+}
+
+Scope::Ptr ScopeView::scope() const
+{
+ return scope_;
+}
+
+nux::Area* ScopeView::fscroll_view() const
+{
+ return fscroll_view_;
+}
+
+int ScopeView::GetNumRows()
+{
+ int num_rows = 0;
+ for (PlacesGroup::Ptr const& group : category_views_)
+ {
+ if (group->IsVisible() && group->GetChildView())
+ {
+ num_rows += 1; // The category header
+
+ if (group->GetExpanded())
+ {
+ int result_rows = 0, result_columns = 0;
+ group->GetChildView()->GetResultDimensions(result_rows, result_columns);
+ num_rows += result_rows;
+ }
+ else
+ num_rows += 1;
+ }
+ }
+
+ return num_rows;
+}
+
+void ScopeView::AboutToShow()
+{
+ JumpToTop();
+ OnScopeFilterExpanded(filters_expanded);
+}
+
+void ScopeView::JumpToTop()
+{
+ scroll_view_->ScrollToPosition(nux::Geometry(0, 0, 0, 0));
+}
+
+void ScopeView::ActivateFirst()
+{
+ if (!scope_)
+ return;
+
+ Results::Ptr results = scope_->results;
+ if (results->count())
+ {
+ // the first displayed category might not be category_views_[0]
+ for (auto iter = category_order_.begin(); iter != category_order_.end(); ++iter)
+ {
+ unsigned int category_index = *iter;
+ if (category_views_.size() <= category_index)
+ continue;
+ PlacesGroup::Ptr group = category_views_[category_index];
+
+ ResultView* result_view = group->GetChildView();
+ if (result_view == nullptr) continue;
+
+ auto it = result_view->GetIteratorAtRow(0);
+ if (!it.IsLast())
+ {
+ Result result(*it);
+ result_view->Activate(result, result_view->GetIndexForLocalResult(result), ResultView::ActivateType::DIRECT);
+ return;
+ }
+ }
+
+ // Fallback
+ Result result = results->RowAtIndex(0);
+ if (result.uri != "")
+ {
+ result_activated.emit(ResultView::ActivateType::DIRECT, LocalResult(result), nullptr, "");
+ scope_->Activate(result);
+ }
+ }
+}
+
+// Keyboard navigation
+bool ScopeView::AcceptKeyNavFocus()
+{
+ return false;
+}
+
+void ScopeView::ForceCategoryExpansion(std::string const& view_id, bool expand)
+{
+ for (auto iter = category_views_.begin(); iter != category_views_.end(); ++iter)
+ {
+ PlacesGroup::Ptr group = *iter;
+ if (group->GetChildView()->unique_id == view_id)
+ {
+ if (expand)
+ {
+ group->PushExpanded();
+ group->SetExpanded(true);
+ }
+ else
+ {
+ group->PopExpanded();
+ }
+ }
+ }
+}
+
+void ScopeView::SetResultsPreviewAnimationValue(float preview_animation)
+{
+ for (auto it = category_views_.begin(); it != category_views_.end(); ++it)
+ {
+ (*it)->SetResultsPreviewAnimationValue(preview_animation);
+ }
+}
+
+void ScopeView::EnableResultTextures(bool enable_result_textures)
+{
+ scroll_view_->EnableScrolling(!enable_result_textures);
+
+ for (auto it = category_views_.begin(); it != category_views_.end(); ++it)
+ {
+ ResultView* result_view = (*it)->GetChildView();
+ if (result_view)
+ {
+ result_view->enable_texture_render = enable_result_textures;
+ }
+ }
+}
+
+std::vector<ResultViewTexture::Ptr> ScopeView::GetResultTextureContainers()
+{
+ // iterate in visual order
+ std::vector<ResultViewTexture::Ptr> textures;
+
+ for (auto iter = category_order_.begin(); iter != category_order_.end(); ++iter)
+ {
+ unsigned int category_index = *iter;
+ if (category_views_.size() <= category_index)
+ continue;
+ PlacesGroup::Ptr cateogry_view = category_views_[category_index];
+
+ if (!cateogry_view || !cateogry_view->IsVisible())
+ continue;
+
+ ResultView* result_view = cateogry_view->GetChildView();
+ if (result_view)
+ {
+ // concatenate textures
+ std::vector<ResultViewTexture::Ptr> const& category_textures = result_view->GetResultTextureContainers();
+ for (auto iter2 = category_textures.begin(); iter2 != category_textures.end(); ++iter2)
+ {
+ ResultViewTexture::Ptr const& result_texture = *iter2;
+ result_texture->category_index = category_index;
+ textures.push_back(result_texture);
+ }
+ }
+ }
+ return textures;
+}
+
+void ScopeView::RenderResultTexture(ResultViewTexture::Ptr const& result_texture)
+{
+ ResultView* result_view = GetResultViewForCategory(result_texture->category_index);
+ if (result_view)
+ result_view->RenderResultTexture(result_texture);
+}
+
+void ScopeView::PushFilterExpansion(bool expand)
+{
+ filter_expansion_pushed_ = filters_expanded;
+ filters_expanded = expand;
+}
+
+void ScopeView::PopFilterExpansion()
+{
+ filters_expanded = GetPushedFilterExpansion();
+}
+
+bool ScopeView::GetPushedFilterExpansion() const
+{
+ return filter_expansion_pushed_;
+}
+
+PlacesGroup::Ptr ScopeView::CreatePlacesGroup(Category const& category)
+{
+ return PlacesGroup::Ptr(new PlacesGroup(dash::Style::Instance()));
+}
+
+ScopeView::CategoryGroups ScopeView::GetOrderedCategoryViews() const
+{
+ CategoryGroups category_view_ordered;
+ for (auto iter = category_order_.begin(); iter != category_order_.end(); ++iter)
+ {
+ unsigned int category_index = *iter;
+ if (category_views_.size() <= category_index)
+ continue;
+
+ PlacesGroup::Ptr group = category_views_[category_index];
+ category_view_ordered.push_back(group);
+ }
+ return category_view_ordered;
+}
+
+// Introspectable
+std::string ScopeView::GetName() const
+{
+ return "ScopeView";
+}
+
+void ScopeView::AddProperties(GVariantBuilder* builder)
+{
+ unity::variant::BuilderWrapper(builder)
+ .add("name", scope_->id)
+ .add("scope-name", scope_->name)
+ .add("visible", IsVisible())
+ .add("no-results-active", no_results_active_);
+}
+
+}
+}
diff --git a/dash/LensView.h b/dash/ScopeView.h
index 503fd53ce..4263e05a0 100644
--- a/dash/LensView.h
+++ b/dash/ScopeView.h
@@ -17,8 +17,8 @@
* Authored by: Neil Jagdish Patel <neil.patel@canonical.com>
*/
-#ifndef UNITY_LENS_VIEW_H_
-#define UNITY_LENS_VIEW_H_
+#ifndef UNITY_SCOPE_VIEW_H_
+#define UNITY_SCOPE_VIEW_H_
#include <string>
@@ -27,7 +27,7 @@
#include <Nux/HLayout.h>
#include <Nux/View.h>
#include <Nux/VLayout.h>
-#include <UnityCore/Lens.h>
+#include <UnityCore/Scope.h>
#include <UnityCore/GLibSource.h>
#include "FilterBar.h"
@@ -42,20 +42,21 @@ namespace unity
namespace dash
{
-class LensScrollView;
+class ScopeScrollView;
-class LensView : public nux::View, public unity::debug::Introspectable
+class ScopeView : public nux::View, public unity::debug::Introspectable
{
- NUX_DECLARE_OBJECT_TYPE(LensView, nux::View);
- typedef std::vector<PlacesGroup*> CategoryGroups;
- typedef std::map<PlacesGroup*, unsigned int> ResultCounts;
+ NUX_DECLARE_OBJECT_TYPE(ScopeView, nux::View);
+ typedef std::vector<PlacesGroup::Ptr> CategoryGroups;
+ typedef std::map<PlacesGroup::Ptr, unsigned int> ResultCounts;
public:
- LensView(Lens::Ptr lens, nux::Area* show_filters);
+ ScopeView(Scope::Ptr scope, nux::Area* show_filters);
+ ~ScopeView();
- CategoryGroups& categories() { return categories_; }
+ CategoryGroups GetOrderedCategoryViews() const;
FilterBar* filter_bar() const { return filter_bar_; }
- Lens::Ptr lens() const;
+ Scope::Ptr scope() const;
nux::Area* fscroll_view() const;
int GetNumRows();
@@ -66,15 +67,13 @@ public:
nux::ROProperty<std::string> search_string;
nux::Property<bool> filters_expanded;
- nux::Property<ViewType> view_type;
+ nux::Property<ScopeViewType> view_type;
nux::Property<bool> can_refine_search;
- sigc::signal<void, ResultView::ActivateType, std::string const&, GVariant*, std::string const&> uri_activated;
+ sigc::signal<void, ResultView::ActivateType, LocalResult const&, GVariant*, std::string const&> result_activated;
- void PerformSearch(std::string const& search_query, Lens::SearchFinishedCallback const& cb);
- void CheckNoResults(Lens::Hints const& hints);
- void CheckCategoryExpansion();
- void HideResultsMessage();
+ typedef std::function<void(std::string const& scope_id, std::string const& search_query, glib::Error const& err)> SearchCallback;
+ bool PerformSearch(std::string const& search_query, SearchCallback const& callback);
void ForceCategoryExpansion(std::string const& view_id, bool expand);
void PushFilterExpansion(bool expand);
@@ -89,27 +88,40 @@ public:
private:
void SetupViews(nux::Area* show_filters);
- void SetupCategories();
- void SetupResults();
- void SetupFilters();
+ void SetupCategories(Categories::Ptr const& categories);
+ void SetupResults(Results::Ptr const& results);
+ void SetupFilters(Filters::Ptr const& filters);
void OnCategoryAdded(Category const& category);
- void OnCategoryOrderChanged();
+ void OnCategoryChanged(Category const& category);
+ void OnCategoryRemoved(Category const& category);
+
void OnResultAdded(Result const& result);
void OnResultRemoved(Result const& result);
- void UpdateCounts(PlacesGroup* group, unsigned int);
+
+ void OnSearchComplete(std::string const& search_string, glib::HintsMap const& hints, glib::Error const& err);
+
void OnGroupExpanded(PlacesGroup* group);
void CheckScrollBarState();
void OnColumnsChanged();
void OnFilterAdded(Filter::Ptr filter);
void OnFilterRemoved(Filter::Ptr filter);
- void OnViewTypeChanged(ViewType view_type);
- void OnLensFilterExpanded(bool expanded);
- bool ReinitializeFilterModels();
- ResultViewGrid* GetGridForCategory(unsigned category_index);
- ResultView* GetResultViewForCategory(unsigned category_index);
+ void OnViewTypeChanged(ScopeViewType view_type);
+ void OnScopeFilterExpanded(bool expanded);
+ void QueueReinitializeFilterCategoryModels(unsigned int index);
+ bool ReinitializeCategoryResultModels();
+ void ClearCategories();
+ void OnCategoryOrderChanged();
- virtual PlacesGroup* CreatePlacesGroup();
+ void QueueCategoryCountsCheck();
+ void CheckCategoryCounts();
+
+ void CheckNoResults(glib::HintsMap const& hints);
+ void HideResultsMessage();
+
+ ResultView* GetResultViewForCategory(unsigned int category_index);
+
+ virtual PlacesGroup::Ptr CreatePlacesGroup(Category const& category);
void BuildPreview(std::string const& uri, Preview::Ptr model);
@@ -122,18 +134,21 @@ private:
std::string get_search_string() const;
- Lens::Ptr lens_;
- CategoryGroups categories_;
+ CategoryGroups category_views_;
+
+ Scope::Ptr scope_;
+ glib::Object<GCancellable> cancellable_;
+ glib::Object<GCancellable> search_cancellable_;
+ std::vector<unsigned int> category_order_;
ResultCounts counts_;
- bool initial_activation_;
bool no_results_active_;
std::string search_string_;
- PlacesGroup* last_expanded_group_;
+ PlacesGroup::Ptr last_expanded_group_;
nux::HLayout* layout_;
- LensScrollView* scroll_view_;
+ ScopeScrollView* scroll_view_;
nux::VLayout* scroll_layout_;
- LensScrollView* fscroll_view_;
+ ScopeScrollView* fscroll_view_;
nux::VLayout* fscroll_layout_;
FilterBar* filter_bar_;
StaticCairoText* no_results_;
@@ -142,13 +157,30 @@ private:
glib::Source::UniquePtr model_updated_timeout_;
int last_good_filter_model_;
glib::Source::UniquePtr fix_filter_models_idle_;
+ glib::Source::UniquePtr hide_message_delay_;
bool filter_expansion_pushed_;
- friend class TestLensView;
+ sigc::connection results_updated;
+ sigc::connection result_added_connection;
+ sigc::connection result_removed_connection;
+
+ sigc::connection categories_updated;
+ sigc::connection category_added_connection;
+ sigc::connection category_changed_connection;
+ sigc::connection category_removed_connection;
+
+ sigc::connection filters_updated;
+ sigc::connection filter_added_connection;
+ sigc::connection filter_removed_connection;
+
+ bool scope_connected_;
+ bool search_on_next_connect_;
+
+ friend class TestScopeView;
};
+} // namespace dash
+} // namespace unity
-}
-}
-#endif
+#endif // UNITY_SCOPE_VIEW_H_
diff --git a/dash/StandaloneDash.cpp b/dash/StandaloneDash.cpp
index a6e69e1be..326e3a28a 100644
--- a/dash/StandaloneDash.cpp
+++ b/dash/StandaloneDash.cpp
@@ -36,6 +36,7 @@
#include "unity-shared/DashStyle.h"
#include "unity-shared/PanelStyle.h"
#include "unity-shared/ThumbnailGenerator.h"
+#include "UnityCore/GSettingsScopes.h"
#define WIDTH 1024
#define HEIGHT 768
@@ -65,7 +66,7 @@ void TestRunner::Init ()
{
layout = new nux::HLayout(NUX_TRACKER_LOCATION);
- DashView* view = new DashView(std::make_shared<unity::dash::FilesystemLenses>(),
+ DashView* view = new DashView(std::make_shared<unity::dash::GSettingsScopes>(),
std::make_shared<unity::ApplicationStarterImp>());
view->DisableBlur();
view->SetMinMaxSize(WIDTH, HEIGHT);
@@ -75,6 +76,7 @@ void TestRunner::Init ()
view->AboutToShow();
nux::GetWindowThread()->SetLayout (layout);
+ nux::GetWindowCompositor().SetKeyFocusArea(view->default_focus());
}
void TestRunner::InitWindowThread(nux::NThread* thread, void* InitData)
diff --git a/dash/previews/ApplicationPreview.cpp b/dash/previews/ApplicationPreview.cpp
index f2e898f70..7ab91a2d2 100644
--- a/dash/previews/ApplicationPreview.cpp
+++ b/dash/previews/ApplicationPreview.cpp
@@ -153,14 +153,16 @@ void ApplicationPreview::SetupViews()
app_icon_->mouse_click.connect(on_mouse_down);
icon_layout->AddView(app_icon_.GetPointer(), 0);
- app_rating_ = new PreviewRatingsWidget();
- AddChild(app_rating_.GetPointer());
- app_rating_->SetMaximumHeight(style.GetRatingWidgetHeight());
- app_rating_->SetMinimumHeight(style.GetRatingWidgetHeight());
- app_rating_->SetRating(app_preview_model->rating);
- app_rating_->SetReviews(app_preview_model->num_ratings);
- app_rating_->request_close().connect([this]() { preview_container_->request_close.emit(); });
- icon_layout->AddView(app_rating_.GetPointer(), 0);
+ if (app_preview_model->rating >= 0) {
+ app_rating_ = new PreviewRatingsWidget();
+ AddChild(app_rating_.GetPointer());
+ app_rating_->SetMaximumHeight(style.GetRatingWidgetHeight());
+ app_rating_->SetMinimumHeight(style.GetRatingWidgetHeight());
+ app_rating_->SetRating(app_preview_model->rating);
+ app_rating_->SetReviews(app_preview_model->num_ratings);
+ app_rating_->request_close().connect([this]() { preview_container_->request_close.emit(); });
+ icon_layout->AddView(app_rating_.GetPointer(), 0);
+ }
/////////////////////
diff --git a/dash/previews/DBusTestRunner.h b/dash/previews/DBusTestRunner.h
index b271bea34..54b856151 100644
--- a/dash/previews/DBusTestRunner.h
+++ b/dash/previews/DBusTestRunner.h
@@ -24,7 +24,6 @@
#include <UnityCore/GLibDBusProxy.h>
#include <UnityCore/Preview.h>
-#include <UnityCore/Lens.h>
#include <UnityCore/Results.h>
#include <NuxCore/Logger.h>
diff --git a/dash/previews/LensDBusTestRunner.h b/dash/previews/LensDBusTestRunner.h
index 0eb594068..745981745 100644
--- a/dash/previews/LensDBusTestRunner.h
+++ b/dash/previews/LensDBusTestRunner.h
@@ -23,6 +23,7 @@
#include "DBusTestRunner.h"
+#include "UnityCore/ScopeProxyInterface.h"
namespace unity
{
@@ -31,18 +32,18 @@ namespace dash
namespace previews
{
-class LensDBusTestRunner : public DBusTestRunner
+class ScopeDBusTestRunner : public DBusTestRunner
{
public:
typedef std::map<std::string, unity::glib::Variant> Hints;
- LensDBusTestRunner(std::string const& dbus_name, std::string const& dbus_path, std::string const& interface_name)
+ ScopeDBusTestRunner(std::string const& dbus_name, std::string const& dbus_path, std::string const& interface_name)
: DBusTestRunner(dbus_name, dbus_path, interface_name)
, results_(new Results(ModelType::REMOTE))
, results_variant_(NULL)
{
- proxy_->Connect("Changed", sigc::mem_fun(this, &LensDBusTestRunner::OnChanged));
- results_->end_transaction.connect(sigc::mem_fun(this, &LensDBusTestRunner::ResultsModelUpdated));
+ proxy_->Connect("Changed", sigc::mem_fun(this, &ScopeDBusTestRunner::OnChanged));
+ results_->end_transaction.connect(sigc::mem_fun(this, &ScopeDBusTestRunner::ResultsModelUpdated));
}
void OnProxyConnectionChanged()
@@ -52,7 +53,7 @@ public:
if (proxy_->IsConnected())
{
proxy_->Call("InfoRequest");
- proxy_->Call("SetViewType", g_variant_new("(u)", LENS_VIEW));
+ proxy_->Call("SetViewType", g_variant_new("(u)", ScopeViewType::SCOPE_VIEW));
}
}
@@ -81,7 +82,7 @@ public:
&filters_model_name,
&hints_iter);
- LOG_DEBUG(logger) << "Lens info changed for " << dbus_name_ << "\n"
+ LOG_DEBUG(logger) << "Scope info changed for " << dbus_name_ << "\n"
<< " Path: " << dbus_path << "\n"
<< " SearchInGlobal: " << search_in_global << "\n"
<< " Visible: " << visible << "\n"
@@ -125,7 +126,7 @@ public:
g_variant_new("(sa{sv})",
search_string.c_str(),
&b),
- sigc::mem_fun(this, &LensDBusTestRunner::OnSearchFinished),
+ sigc::mem_fun(this, &ScopeDBusTestRunner::OnSearchFinished),
search_cancellable_);
g_variant_builder_clear(&b);
@@ -183,7 +184,7 @@ public:
proxy_->Call("Activate",
g_variant_new("(su)", uri.c_str(),
UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_RESULT),
- sigc::mem_fun(this, &LensDBusTestRunner::ActivationReply),
+ sigc::mem_fun(this, &ScopeDBusTestRunner::ActivationReply),
preview_cancellable_);
}
@@ -208,7 +209,7 @@ public:
{
dash::Preview::Ptr preview(dash::Preview::PreviewForVariant(iter->second));
- // would be nice to make parent_lens a shared_ptr,
+ // would be nice to make parent_scope a shared_ptr,
// but that's not really doable from here
preview_ready.emit(uri.Str(), preview);
return;
diff --git a/dash/previews/MusicPaymentPreview.cpp b/dash/previews/MusicPaymentPreview.cpp
index f85b7578c..69d5e4b17 100644
--- a/dash/previews/MusicPaymentPreview.cpp
+++ b/dash/previews/MusicPaymentPreview.cpp
@@ -1,4 +1,4 @@
-// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 4 -*-
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
/*
* Copyright 2012-2013 Canonical Ltd.
*
@@ -94,7 +94,7 @@ void MusicPaymentPreview::OnActionActivated(ActionButton* button, std::string co
// HACK: We need to think a better way to do this
auto const& password = password_entry_->text_entry()->GetText();
glib::Variant variant_pw(g_variant_new_string(password.c_str()));
- Lens::Hints hints {
+ glib::HintsMap hints {
std::make_pair(MusicPaymentPreview::DATA_PASSWORD_KEY, variant_pw)
};
preview_model_->PerformAction(id, hints);
diff --git a/dash/previews/MusicPaymentPreview.h b/dash/previews/MusicPaymentPreview.h
index 423ac6547..40062f562 100644
--- a/dash/previews/MusicPaymentPreview.h
+++ b/dash/previews/MusicPaymentPreview.h
@@ -25,7 +25,6 @@
#include <Nux/Nux.h>
#include <Nux/AbstractButton.h>
-#include <UnityCore/Lens.h>
#include <UnityCore/PaymentPreview.h>
#include "ActionButton.h"
#include "ActionLink.h"
diff --git a/dash/previews/MusicPreview.cpp b/dash/previews/MusicPreview.cpp
index 21e4f2868..9e1fb98f0 100644
--- a/dash/previews/MusicPreview.cpp
+++ b/dash/previews/MusicPreview.cpp
@@ -34,6 +34,7 @@
#include "ActionButton.h"
#include "Tracks.h"
#include "PreviewInfoHintWidget.h"
+#include "PreviewPlayer.h"
namespace unity
{
@@ -177,8 +178,6 @@ void MusicPreview::SetupViews()
{
tracks_ = new previews::Tracks(tracks_model, NUX_TRACKER_LOCATION);
AddChild(tracks_.GetPointer());
- tracks_->play.connect(sigc::mem_fun(this, &MusicPreview::OnPlayTrack));
- tracks_->pause.connect(sigc::mem_fun(this, &MusicPreview::OnPauseTrack));
tracks_->mouse_click.connect(on_mouse_down);
}
/////////////////////
@@ -264,30 +263,6 @@ void MusicPreview::SetupViews()
SetLayout(image_data_layout);
}
-void MusicPreview::OnPlayTrack(std::string const& uri)
-{
- dash::MusicPreview* music_preview_model = dynamic_cast<dash::MusicPreview*>(preview_model_.get());
- if (!music_preview_model)
- {
- LOG_ERROR(logger) << "Play failed. No preview found";
- return;
- }
-
- music_preview_model->PlayUri(uri);
-}
-
-void MusicPreview::OnPauseTrack(std::string const& uri)
-{
- dash::MusicPreview* music_preview_model = dynamic_cast<dash::MusicPreview*>(preview_model_.get());
- if (!music_preview_model)
- {
- LOG_ERROR(logger) << "Pause failed. No preview found";
- return;
- }
-
- music_preview_model->PauseUri(uri);
-}
-
void MusicPreview::PreLayoutManagement()
{
nux::Geometry geo = GetGeometry();
@@ -314,6 +289,12 @@ void MusicPreview::PreLayoutManagement()
Preview::PreLayoutManagement();
}
+void MusicPreview::OnNavigateOut()
+{
+ PreviewPlayer player;
+ player.Stop();
}
-}
-}
+
+} // namespace previews
+} // namespace dash
+} // namespace unity
diff --git a/dash/previews/MusicPreview.h b/dash/previews/MusicPreview.h
index cf56b1e0e..f215dadd5 100644
--- a/dash/previews/MusicPreview.h
+++ b/dash/previews/MusicPreview.h
@@ -54,9 +54,7 @@ protected:
virtual void SetupViews();
- void OnPlayTrack(std::string const& uri);
- void OnPauseTrack(std::string const& uri);
- bool HasUbuntuOneCredentials();
+ virtual void OnNavigateOut();
protected:
nux::ObjectPtr<Tracks> tracks_;
diff --git a/dash/previews/PaymentPreview.cpp.moved b/dash/previews/PaymentPreview.cpp.moved
new file mode 100644
index 000000000..388734b34
--- /dev/null
+++ b/dash/previews/PaymentPreview.cpp.moved
@@ -0,0 +1,368 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/*
+ * Copyright 2012-2013 Canonical Ltd.
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License version 3, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the applicable version of the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of both the GNU Lesser General Public
+ * License version 3 along with this program. If not, see
+ * <http://www.gnu.org/licenses/>
+ *
+ * Authored by: Diego Sarmentero <diego.sarmentero@canonical.com>
+ * Manuel de la Pena <manuel.delapena@canonical.com>
+ *
+ */
+#include <NuxCore/Logger.h>
+#include "PaymentPreview.h"
+#include "unity-shared/CoverArt.h"
+#include "unity-shared/PreviewStyle.h"
+
+namespace unity
+{
+
+namespace dash
+{
+
+namespace previews
+{
+
+namespace
+{
+
+nux::logging::Logger logger("unity.dash.previews.payment.preview");
+
+}
+
+class OverlaySpinner : public unity::debug::Introspectable, public nux::View
+{
+ NUX_DECLARE_OBJECT_TYPE(OverlaySpinner, nux::View);
+public:
+ OverlaySpinner();
+
+ void Draw(nux::GraphicsEngine& GfxContext, bool force_draw);
+ void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw);
+
+protected:
+ // Introspectable methods
+ std::string GetName() const;
+ void AddProperties(GVariantBuilder* builder);
+
+ // Key navigation
+ virtual bool AcceptKeyNavFocus();
+
+private:
+ bool OnFrameTimeout();
+
+ nux::BaseTexture* spin_;
+
+ glib::Source::UniquePtr frame_timeout_;
+
+ nux::Matrix4 rotate_;
+ float rotation_;
+};
+
+NUX_IMPLEMENT_OBJECT_TYPE(OverlaySpinner);
+
+OverlaySpinner::OverlaySpinner()
+ : nux::View(NUX_TRACKER_LOCATION),
+ rotation_(0.0f)
+{
+ previews::Style& style = dash::previews::Style::Instance();
+
+ spin_ = style.GetSearchSpinIcon();
+
+ rotate_.Identity();
+ rotate_.Rotate_z(0.0);
+}
+
+void OverlaySpinner::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
+{
+ nux::Geometry const& geo = GetGeometry();
+ nux::TexCoordXForm texxform;
+
+ GfxContext.PushClippingRectangle(geo);
+
+ nux::GetPainter().PaintBackground(GfxContext, geo);
+
+ texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
+ texxform.SetWrap(nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT);
+ texxform.min_filter = nux::TEXFILTER_LINEAR;
+ texxform.mag_filter = nux::TEXFILTER_LINEAR;
+
+ unsigned int current_alpha_blend;
+ unsigned int current_src_blend_factor;
+ unsigned int current_dest_blend_factor;
+ GfxContext.GetRenderStates().GetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor);
+ GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ nux::Geometry spin_geo(geo.x + ((geo.width - spin_->GetWidth()) / 2),
+ geo.y + ((geo.height - spin_->GetHeight()) / 2),
+ spin_->GetWidth(),
+ spin_->GetHeight());
+ // Geometry (== Rect) uses integers which were rounded above,
+ // hence an extra 0.5 offset for odd sizes is needed
+ // because pure floating point is not being used.
+ int spin_offset_w = !(geo.width % 2) ? 0 : 1;
+ int spin_offset_h = !(geo.height % 2) ? 0 : 1;
+
+ nux::Matrix4 matrix_texture;
+ matrix_texture = nux::Matrix4::TRANSLATE(-spin_geo.x - (spin_geo.width + spin_offset_w) / 2.0f,
+ -spin_geo.y - (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture;
+ matrix_texture = rotate_ * matrix_texture;
+ matrix_texture = nux::Matrix4::TRANSLATE(spin_geo.x + (spin_geo.width + spin_offset_w) / 2.0f,
+ spin_geo.y + (spin_geo.height + spin_offset_h) / 2.0f, 0) * matrix_texture;
+
+ GfxContext.SetModelViewMatrix(GfxContext.GetModelViewMatrix() * matrix_texture);
+
+ GfxContext.QRP_1Tex(spin_geo.x,
+ spin_geo.y,
+ spin_geo.width,
+ spin_geo.height,
+ spin_->GetDeviceTexture(),
+ texxform,
+ nux::color::White);
+
+ // revert to model view matrix stack
+ GfxContext.ApplyModelViewMatrix();
+
+ GfxContext.PopClippingRectangle();
+
+ GfxContext.GetRenderStates().SetBlend(current_alpha_blend, current_src_blend_factor, current_dest_blend_factor);
+
+ if (!frame_timeout_)
+ {
+ frame_timeout_.reset(new glib::Timeout(22, sigc::mem_fun(this, &OverlaySpinner::OnFrameTimeout)));
+ }
+}
+
+
+void OverlaySpinner::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
+{
+}
+
+
+bool OverlaySpinner::OnFrameTimeout()
+{
+ rotation_ += 0.1f;
+
+ if (rotation_ >= 360.0f)
+ rotation_ = 0.0f;
+
+ rotate_.Rotate_z(rotation_);
+ QueueDraw();
+
+ frame_timeout_.reset();
+ return false;
+}
+
+std::string OverlaySpinner::GetName() const
+{
+ return "OverlaySpinner";
+}
+
+void OverlaySpinner::AddProperties(GVariantBuilder* builder)
+{
+ nux::Geometry geo = GetGeometry();
+
+ variant::BuilderWrapper(builder)
+ .add("x", geo.x)
+ .add("y", geo.y)
+ .add("width", geo.width)
+ .add("height", geo.height);
+}
+
+
+bool OverlaySpinner::AcceptKeyNavFocus()
+{
+ return false;
+}
+
+PaymentPreview::PaymentPreview(dash::Preview::Ptr preview_model)
+: Preview(preview_model)
+, data_(nullptr)
+, full_data_layout_(nullptr)
+{
+}
+
+std::string PaymentPreview::GetName() const
+{
+ return "";
+}
+
+
+nux::Layout* PaymentPreview::GetHeader()
+{
+ nux::HLayout* header_data_layout = new nux::HLayout();
+ header_data_layout->SetSpaceBetweenChildren(10);
+ header_data_layout->SetMaximumHeight(76);
+ header_data_layout->SetMinimumHeight(76);
+
+ image_ = new CoverArt();
+ image_->SetMinMaxSize(64, 64);
+ AddChild(image_.GetPointer());
+ UpdateCoverArtImage(image_.GetPointer());
+
+ header_data_layout->AddView(image_.GetPointer(), 0);
+ header_data_layout->AddLayout(GetTitle(), 0);
+ header_data_layout->AddSpace(10, 1);
+ header_data_layout->AddLayout(GetPrice(), 0);
+ return header_data_layout;
+}
+
+nux::ObjectPtr<ActionLink> PaymentPreview::CreateLink(dash::Preview::ActionPtr action)
+{
+ previews::Style& style = dash::previews::Style::Instance();
+
+ nux::ObjectPtr<ActionLink> link;
+ link = new ActionLink(action->id,
+ action->display_name, NUX_TRACKER_LOCATION);
+ link->font_hint.Set(style.payment_form_labels_font().c_str());
+ link->SetMinimumWidth(178);
+ link->SetMaximumHeight(34);
+ return link;
+}
+
+
+nux::ObjectPtr<ActionButton> PaymentPreview::CreateButton(dash::Preview::ActionPtr action)
+{
+ previews::Style& style = dash::previews::Style::Instance();
+
+ nux::ObjectPtr<ActionButton> button;
+ button = new ActionButton(action->id,
+ action->display_name, action->icon_hint,
+ NUX_TRACKER_LOCATION);
+ button->SetFont(style.action_font());
+ button->SetExtraHint(action->extra_text, style.action_extra_font());
+ button->SetMinimumWidth(178);
+ button->SetMaximumHeight(34);
+ return button;
+}
+
+
+void PaymentPreview::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw)
+{
+ nux::Geometry const& base = GetGeometry();
+
+ gfx_engine.PushClippingRectangle(base);
+ nux::GetPainter().PaintBackground(gfx_engine, base);
+
+ if (full_data_layout_)
+ {
+ unsigned int alpha, src, dest = 0;
+ gfx_engine.GetRenderStates().GetBlend(alpha, src, dest);
+ gfx_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ details_bg_layer_->SetGeometry(full_data_layout_->GetGeometry());
+ nux::GetPainter().RenderSinglePaintLayer(gfx_engine, full_data_layout_->GetGeometry(), details_bg_layer_.get());
+
+ gfx_engine.GetRenderStates().SetBlend(alpha, src, dest);
+ }
+
+ gfx_engine.PopClippingRectangle();
+}
+
+void PaymentPreview::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw)
+{
+ nux::Geometry const& base = GetGeometry();
+ gfx_engine.PushClippingRectangle(base);
+
+ if (!IsFullRedraw())
+ nux::GetPainter().PushLayer(gfx_engine, details_bg_layer_->GetGeometry(), details_bg_layer_.get());
+
+ unsigned int alpha, src, dest = 0;
+ gfx_engine.GetRenderStates().GetBlend(alpha, src, dest);
+ gfx_engine.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+
+ if (GetCompositionLayout())
+ GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw);
+
+ gfx_engine.GetRenderStates().SetBlend(alpha, src, dest);
+
+ if (!IsFullRedraw())
+ nux::GetPainter().PopBackground();
+
+ gfx_engine.PopClippingRectangle();
+}
+
+void PaymentPreview::ShowOverlay(bool isShown)
+{
+ if (!full_data_layout_)
+ return;
+
+ if (isShown)
+ {
+ full_data_layout_->SetActiveLayerN(1);
+ }
+ else
+ {
+ full_data_layout_->SetActiveLayerN(0);
+ }
+ QueueDraw();
+}
+
+void PaymentPreview::ShowOverlay()
+{
+ ShowOverlay(true);
+}
+
+void PaymentPreview::HideOverlay()
+{
+ ShowOverlay(false);
+}
+
+void PaymentPreview::SetupBackground()
+{
+ details_bg_layer_.reset(dash::previews::Style::Instance().GetBackgroundLayer());
+}
+
+void PaymentPreview::SetupViews()
+{
+ full_data_layout_ = new nux::LayeredLayout();
+
+ // layout to be used to show the info
+ content_data_layout_ = new nux::VLayout();
+ content_data_layout_->SetSpaceBetweenChildren(5);
+ content_data_layout_->SetPadding(10, 10, 0, 10);
+
+ header_layout_ = GetHeader();
+
+ content_data_layout_->AddLayout(header_layout_.GetPointer(), 1);
+
+ body_layout_ = GetBody();
+ content_data_layout_->AddLayout(body_layout_.GetPointer(), 1);
+
+ footer_layout_ = GetFooter();
+ content_data_layout_->AddLayout(footer_layout_.GetPointer(), 1);
+
+ full_data_layout_->AddLayout(content_data_layout_.GetPointer());
+
+ // layout to draw an overlay
+ overlay_layout_ = new nux::VLayout();
+ StaticCairoText* calculating = new StaticCairoText(
+ "Performing purchase", true,
+ NUX_TRACKER_LOCATION);
+
+ OverlaySpinner* spinner_ = new OverlaySpinner();
+ overlay_layout_->AddSpace(20, 1);
+ overlay_layout_->AddView(calculating, 0, nux::MINOR_POSITION_CENTER);
+ overlay_layout_->AddView(spinner_, 1, nux::MINOR_POSITION_CENTER);
+ overlay_layout_->AddSpace(20, 1);
+
+ full_data_layout_->AddLayout(overlay_layout_.GetPointer());
+
+ SetLayout(full_data_layout_.GetPointer());
+}
+
+}
+
+}
+
+}
diff --git a/dash/previews/PaymentPreview.h b/dash/previews/PaymentPreview.h
index 3359d8952..3a09e895b 100644
--- a/dash/previews/PaymentPreview.h
+++ b/dash/previews/PaymentPreview.h
@@ -28,7 +28,6 @@
#include <Nux/HLayout.h>
#include <Nux/LayeredLayout.h>
#include <Nux/AbstractButton.h>
-#include <UnityCore/Lens.h>
#include <UnityCore/PaymentPreview.h>
#include "ActionButton.h"
#include "ActionLink.h"
diff --git a/dash/previews/Preview.cpp b/dash/previews/Preview.cpp
index 44eaca080..c32038444 100644
--- a/dash/previews/Preview.cpp
+++ b/dash/previews/Preview.cpp
@@ -88,10 +88,6 @@ previews::Preview::Ptr Preview::PreviewForModel(dash::Preview::Ptr model)
{
return Preview::Ptr(new SocialPreview(model));
}
- // else if (renderer_name == "preview-series")
- // {
- // return Preview::Ptr(new SeriesPreview(model));
- // }
else
{
LOG_WARN(logger) << "Unable to create Preview for renderer: " << model->renderer_name.Get() << "; using generic";
@@ -116,9 +112,6 @@ Preview::Preview(dash::Preview::Ptr preview_model)
Preview::~Preview()
{
- if (preview_model_)
- preview_model_->EmitClosed();
-
delete tab_iterator_;
}
@@ -131,7 +124,7 @@ void Preview::AddProperties(GVariantBuilder* builder)
{
variant::BuilderWrapper(builder)
.add(GetAbsoluteGeometry())
- .add("uri", preview_model_->preview_uri.Get());
+ .add("uri", preview_model_->preview_result.uri);
}
void Preview::OnActionActivated(ActionButton* button, std::string const& id)
diff --git a/dash/previews/StandaloneMusicPreview.cpp b/dash/previews/StandaloneMusicPreview.cpp
index 830fdd330..c4680e587 100644
--- a/dash/previews/StandaloneMusicPreview.cpp
+++ b/dash/previews/StandaloneMusicPreview.cpp
@@ -116,7 +116,7 @@ protected:
LayerPtr bg_layer_;
};
-class TestRunner : public previews::LensDBusTestRunner
+class TestRunner : public previews::ScopeDBusTestRunner
{
public:
TestRunner(std::string const& search_string);
@@ -136,7 +136,7 @@ public:
};
TestRunner::TestRunner (std::string const& search_string)
-: LensDBusTestRunner("com.canonical.Unity.Lens.Music","/com/canonical/unity/lens/music", "com.canonical.Unity.Lens")
+: ScopeDBusTestRunner("com.canonical.Unity.Scope.Music","/com/canonical/unity/scope/music", "com.canonical.Unity.Scope")
, search_string_(search_string)
, first_(true)
{
diff --git a/dash/previews/Track.cpp b/dash/previews/Track.cpp
index 92e38ece2..0e43f3bc1 100644
--- a/dash/previews/Track.cpp
+++ b/dash/previews/Track.cpp
@@ -125,7 +125,8 @@ private:
Track::Track(NUX_FILE_LINE_DECL)
: View(NUX_FILE_LINE_PARAM)
- , play_state_(dash::STOPPED)
+ , play_state_(PlayerState::STOPPED)
+ , progress_(0.0)
, mouse_over_(false)
{
SetupBackground();
@@ -134,6 +135,7 @@ Track::Track(NUX_FILE_LINE_DECL)
Track::~Track()
{
+ player_connection_.disconnect();
}
std::string Track::GetName() const
@@ -145,7 +147,7 @@ void Track::AddProperties(GVariantBuilder* builder)
{
variant::BuilderWrapper(builder)
.add("uri", uri_)
- .add("play-state", play_state_)
+ .add("play-state", (int)play_state_)
.add("progress", progress_)
.add("playpause-x", track_status_layout_->GetAbsoluteX())
.add("playpause-y", track_status_layout_->GetAbsoluteX())
@@ -156,8 +158,6 @@ void Track::AddProperties(GVariantBuilder* builder)
void Track::Update(dash::Track const& track)
{
uri_ = track.uri;
- progress_ = track.progress;
-
title_->SetText(track.title, true);
std::stringstream ss_track_number;
@@ -168,9 +168,25 @@ void Track::Update(dash::Track const& track)
duration_->SetText(duration);
g_free(duration);
- play_state_ = track.play_state;
- UpdateTrackState();
+ player_connection_.disconnect();
+ player_connection_ = player_.updated.connect([this](std::string const& uri, PlayerState player_state, double progress)
+ {
+ if (uri != uri_)
+ {
+ // If we're received an update for another track, we're obviously not playing this track anymore.
+ if (progress_ != 0.0 || play_state_ != PlayerState::STOPPED)
+ {
+ progress_ = 0.0;
+ play_state_ = PlayerState::STOPPED;
+ UpdateTrackState();
+ }
+ return;
+ }
+ progress_ = progress;
+ play_state_ = player_state;
+ UpdateTrackState();
+ });
QueueDraw();
}
@@ -264,13 +280,17 @@ void Track::SetupViews()
{
switch (play_state_)
{
- case dash::PLAYING:
- pause.emit(uri_);
+ case PlayerState::PLAYING:
+ player_.Pause();
+ break;
+
+ case PlayerState::PAUSED:
+ player_.Resume();
break;
- case dash::PAUSED:
- case dash::STOPPED:
+
+ case PlayerState::STOPPED:
default:
- play.emit(uri_);
+ player_.Play(uri_);
break;
}
});
@@ -357,7 +377,7 @@ nux::Area* Track::FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxE
bool Track::HasStatusFocus() const
{
- return mouse_over_ || play_state_ == dash::PLAYING || play_state_ == dash::PAUSED;
+ return mouse_over_ || play_state_ == PlayerState::PLAYING || play_state_ == PlayerState::PAUSED;
}
void Track::OnTrackControlMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags)
@@ -382,11 +402,11 @@ void Track::UpdateTrackState()
{
switch (play_state_)
{
- case dash::PLAYING:
+ case PlayerState::PLAYING:
track_status_layout_->SetActiveLayer(status_pause_layout_);
break;
- case dash::PAUSED:
- case dash::STOPPED:
+ case PlayerState::PAUSED:
+ case PlayerState::STOPPED:
default:
track_status_layout_->SetActiveLayer(status_play_layout_);
break;
@@ -396,18 +416,19 @@ void Track::UpdateTrackState()
{
switch (play_state_)
{
- case dash::PLAYING:
+ case PlayerState::PLAYING:
track_status_layout_->SetActiveLayer(status_play_layout_);
break;
- case dash::PAUSED:
+ case PlayerState::PAUSED:
track_status_layout_->SetActiveLayer(status_pause_layout_);
break;
- case dash::STOPPED:
+ case PlayerState::STOPPED:
default:
track_status_layout_->SetActiveLayer(track_number_layout_);
break;
}
}
+ QueueDraw();
}
@@ -425,8 +446,6 @@ void Track::PreLayoutManagement()
View::PreLayoutManagement();
}
-
-
-}
-}
-}
+} // namespace previews
+} // namespace dash
+} // namesapce unity
diff --git a/dash/previews/Track.h b/dash/previews/Track.h
index b1815dae1..329e17f9e 100644
--- a/dash/previews/Track.h
+++ b/dash/previews/Track.h
@@ -27,6 +27,7 @@
#include <Nux/View.h>
#include <UnityCore/Tracks.h>
#include "unity-shared/Introspectable.h"
+#include "PreviewPlayer.h"
namespace nux
{
@@ -54,9 +55,6 @@ public:
void Update(dash::Track const& track_row);
- sigc::signal<void, std::string const&> play;
- sigc::signal<void, std::string const&> pause;
-
protected:
virtual void Draw(nux::GraphicsEngine& gfx_engine, bool force_draw);
virtual void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw);
@@ -81,7 +79,11 @@ protected:
protected:
std::string uri_;
+ PlayerState play_state_;
float progress_;
+ PreviewPlayer player_;
+ sigc::connection player_connection_;
+
unity::StaticCairoText* track_number_;
unity::StaticCairoText* title_;
unity::StaticCairoText* duration_;
@@ -97,7 +99,6 @@ protected:
nux::View* track_number_layout_;
nux::LayeredLayout* track_status_layout_;
- dash::PlayState play_state_;
bool mouse_over_;
};
diff --git a/dash/previews/Tracks.cpp b/dash/previews/Tracks.cpp
index 1c5a3872c..7f53519cc 100644
--- a/dash/previews/Tracks.cpp
+++ b/dash/previews/Tracks.cpp
@@ -47,9 +47,9 @@ Tracks::Tracks(dash::Tracks::Ptr tracks, NUX_FILE_LINE_DECL)
if (tracks_)
{
- tracks_->track_added.connect(sigc::mem_fun(this, &Tracks::OnTrackAdded));
- tracks_->track_changed.connect(sigc::mem_fun(this, &Tracks::OnTrackUpdated));
- tracks_->track_removed.connect(sigc::mem_fun(this, &Tracks::OnTrackRemoved));
+ add_track_ = tracks_->track_added.connect(sigc::mem_fun(this, &Tracks::OnTrackAdded));
+ change_track_ = tracks_->track_changed.connect(sigc::mem_fun(this, &Tracks::OnTrackUpdated));
+ remove_track_ = tracks_->track_removed.connect(sigc::mem_fun(this, &Tracks::OnTrackRemoved));
// Add what we've got.
for (std::size_t i = 0; i < tracks_->count.Get(); i++)
@@ -61,6 +61,9 @@ Tracks::Tracks(dash::Tracks::Ptr tracks, NUX_FILE_LINE_DECL)
Tracks::~Tracks()
{
+ add_track_.disconnect();
+ change_track_.disconnect();
+ remove_track_.disconnect();
}
std::string Tracks::GetName() const
@@ -105,8 +108,6 @@ void Tracks::OnTrackAdded(dash::Track const& track_row)
previews::Track::Ptr track_view(new previews::Track(NUX_TRACKER_LOCATION));
AddChild(track_view.GetPointer());
- track_view->play.connect([&](std::string const& uri) { play.emit(uri); });
- track_view->pause.connect([&](std::string const& uri) { pause.emit(uri); });
track_view->Update(track_row);
track_view->SetMinimumHeight(style.GetTrackHeight());
diff --git a/dash/previews/Tracks.h b/dash/previews/Tracks.h
index ca4a0a25c..1854ddc01 100644
--- a/dash/previews/Tracks.h
+++ b/dash/previews/Tracks.h
@@ -56,9 +56,6 @@ public:
std::string GetName() const;
void AddProperties(GVariantBuilder* builder);
- sigc::signal<void, std::string const&> play;
- sigc::signal<void, std::string const&> pause;
-
protected:
virtual bool AcceptKeyNavFocus() { return false; }
@@ -68,15 +65,14 @@ protected:
void OnTrackAdded(dash::Track const& track);
void OnTrackRemoved(dash::Track const&track);
- void onPlayTrack(std::string const& uri);
- void onPauseTrack(std::string const& uri);
-
protected:
dash::Tracks::Ptr tracks_;
nux::VLayout* layout_;
std::map<std::string, previews::Track::Ptr> m_tracks;
- int track_count_;
+ sigc::connection add_track_;
+ sigc::connection change_track_;
+ sigc::connection remove_track_;
};
}