diff options
| author | Nick Dedekind <nicholas.dedekind@gmail.com> | 2012-07-09 16:59:23 +0100 |
|---|---|---|
| committer | Nick Dedekind <nicholas.dedekind@gmail.com> | 2012-07-09 16:59:23 +0100 |
| commit | 70300516f0b78ea0266fcd0768276a830959f8ec (patch) | |
| tree | 4a60979cb484a83fe846448b0dbc8ad73b5f9338 | |
| parent | b9e222da37b35634f3caded759901d97d06f49dd (diff) | |
More UI/Layout work.
(bzr r2419.4.14)
38 files changed, 1733 insertions, 218 deletions
diff --git a/UnityCore/ApplicationPreview.cpp b/UnityCore/ApplicationPreview.cpp index efd5f8df3..2c350f7b2 100644 --- a/UnityCore/ApplicationPreview.cpp +++ b/UnityCore/ApplicationPreview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <unity-protocol.h> @@ -85,7 +86,6 @@ ApplicationPreview::ApplicationPreview(unity::glib::Object<GObject> const& proto ApplicationPreview::~ApplicationPreview() { - delete pimpl; } } diff --git a/UnityCore/ApplicationPreview.h b/UnityCore/ApplicationPreview.h index 2dfc72556..f04075682 100644 --- a/UnityCore/ApplicationPreview.h +++ b/UnityCore/ApplicationPreview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_APPLICATION_PREVIEW_H @@ -46,7 +47,7 @@ public: private: class Impl; - Impl* pimpl; + std::unique_ptr<Impl> pimpl; }; } diff --git a/UnityCore/GenericPreview.cpp b/UnityCore/GenericPreview.cpp index 413db02a7..5172db775 100644 --- a/UnityCore/GenericPreview.cpp +++ b/UnityCore/GenericPreview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <unity-protocol.h> @@ -31,6 +32,10 @@ GenericPreview::GenericPreview(unity::glib::Object<GObject> const& proto_obj) { } +GenericPreview::~GenericPreview() +{ +} + } } diff --git a/UnityCore/GenericPreview.h b/UnityCore/GenericPreview.h index 89d7d12fb..7d82107ab 100644 --- a/UnityCore/GenericPreview.h +++ b/UnityCore/GenericPreview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_GENERIC_PREVIEW_H @@ -37,10 +38,7 @@ public: typedef std::shared_ptr<GenericPreview> Ptr; GenericPreview(unity::glib::Object<GObject> const& proto_obj); - - //unsigned int date_modified; - //unsigned int size; - //std::string type; + ~GenericPreview(); }; } diff --git a/UnityCore/Lens.cpp b/UnityCore/Lens.cpp index d4e34f509..d0def4ad9 100644 --- a/UnityCore/Lens.cpp +++ b/UnityCore/Lens.cpp @@ -85,7 +85,11 @@ public: void Activate(std::string const& uri); void ActivationReply(GVariant* parameters); void Preview(std::string const& uri); - void PreviewReply(GVariant* parameters); + void ActivatePreviewAction(std::string const& action_id, + std::string const& uri); + void SignalPreview(std::string const& preview_uri, + glib::Variant const& preview_update, + glib::DBusProxy::ReplyCallback reply_cb); string const& id() const; string const& dbus_name() const; @@ -514,7 +518,7 @@ void Lens::Impl::ActivationReply(GVariant* parameters) glib::Variant dict (hints_variant, glib::StealRef()); dict.ASVToHints(hints); - if (handled == 4) // FIXME: enum from proto (SHOW_PREVIEW) + if (handled == UNITY_PROTOCOL_HANDLED_TYPE_SHOW_PREVIEW) { auto iter = hints.find("preview"); if (iter != hints.end()) @@ -522,6 +526,10 @@ void Lens::Impl::ActivationReply(GVariant* parameters) Preview::Ptr preview(Preview::PreviewForVariant(iter->second)); if (preview) { + // would be nice to make parent_lens a shared_ptr, + // but that's not really doable from here + preview->parent_lens = owner_; + preview->preview_uri = uri.Str(); owner_->preview_ready.emit(uri.Str(), preview); return; } @@ -558,21 +566,46 @@ void Lens::Impl::Preview(std::string const& uri) preview_cancellable_); } -void Lens::Impl::PreviewReply(GVariant* parameters) +void Lens::Impl::ActivatePreviewAction(std::string const& action_id, + std::string const& uri) { - glib::String uri; - glib::String renderer_name; - GVariant* hints_variant; - Hints hints; - - g_variant_get(parameters, "((ss@a{sv}))", &uri, &renderer_name, &hints_variant); + LOG_DEBUG(logger) << "Activating action '" << action_id << "' on '" << id_ << "'"; - glib::Variant dict (hints_variant, glib::StealRef()); - //dict.ASVToHints(hints); + if (!proxy_->IsConnected()) + { + LOG_DEBUG(logger) << "Skipping activation. Proxy not connected. ('" << id_ << "')"; + return; + } + + std::string activation_uri(action_id); + activation_uri += ":"; + activation_uri += uri; + + proxy_->Call("Activate", + g_variant_new("(su)", activation_uri.c_str(), + UNITY_PROTOCOL_ACTION_TYPE_PREVIEW_ACTION), + sigc::mem_fun(this, &Lens::Impl::ActivationReply)); +} - //Preview::Ptr preview = Preview::PreviewForProperties(renderer_name.Str(), hints); - //owner_->preview_ready.emit(uri.Str(), preview); +void Lens::Impl::SignalPreview(std::string const& preview_uri, + glib::Variant const& preview_update, + glib::DBusProxy::ReplyCallback reply_cb) +{ + LOG_DEBUG(logger) << "Signalling preview '" << preview_uri << "' on '" << id_ << "'"; + + if (!proxy_->IsConnected()) + { + LOG_DEBUG(logger) << "Can't signal preview. Proxy not connected. ('" << id_ << "')"; + return; + } + + GVariant *preview_update_variant = preview_update; + proxy_->Call("UpdatePreviewProperty", + g_variant_new("(s@a{sv})", preview_uri.c_str(), + preview_update_variant), + reply_cb); } + string const& Lens::Impl::id() const { return id_; @@ -731,5 +764,19 @@ void Lens::Preview(std::string const& uri) pimpl->Preview(uri); } +void Lens::ActivatePreviewAction(std::string const& action_id, + std::string const& uri) +{ + pimpl->ActivatePreviewAction(action_id, uri); +} + +void Lens::SignalPreview(std::string const& uri, + glib::Variant const& preview_update, + glib::DBusProxy::ReplyCallback reply_cb) +{ + pimpl->SignalPreview(uri, preview_update, reply_cb); +} + + } } diff --git a/UnityCore/Lens.h b/UnityCore/Lens.h index 886665211..c706ad138 100644 --- a/UnityCore/Lens.h +++ b/UnityCore/Lens.h @@ -26,6 +26,7 @@ #include <sigc++/trackable.h> #include "Variant.h" +#include "GLibDBusProxy.h" #include "Categories.h" #include "Filters.h" #include "Preview.h" @@ -84,6 +85,12 @@ public: virtual void Search(std::string const& search_string); virtual void Activate(std::string const& uri); virtual void Preview(std::string const& uri); + virtual void ActivatePreviewAction(std::string const& action_id, + std::string const& uri); + virtual void SignalPreview(std::string const& uri, + glib::Variant const& preview_update, + glib::DBusProxy::ReplyCallback reply_cb = + sigc::ptr_fun(&glib::DBusProxy::NoReplyCallback)); nux::RWProperty<std::string> id; nux::RWProperty<std::string> dbus_name; @@ -106,7 +113,7 @@ public: sigc::signal<void, Hints const&> search_finished; sigc::signal<void, Hints const&> global_search_finished; sigc::signal<void, std::string const&, HandledType, Hints const&> activated; - sigc::signal<void, std::string const&, Preview::Ptr> preview_ready; + sigc::signal<void, std::string const&, Preview::Ptr const&> preview_ready; private: class Impl; diff --git a/UnityCore/MoviePreview.cpp b/UnityCore/MoviePreview.cpp index ebc5444e6..83cae5127 100644 --- a/UnityCore/MoviePreview.cpp +++ b/UnityCore/MoviePreview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <unity-protocol.h> @@ -75,7 +76,6 @@ MoviePreview::MoviePreview(unity::glib::Object<GObject> const& proto_obj) MoviePreview::~MoviePreview() { - delete pimpl; } } diff --git a/UnityCore/MoviePreview.h b/UnityCore/MoviePreview.h index d2c9aa0fa..5b10914af 100644 --- a/UnityCore/MoviePreview.h +++ b/UnityCore/MoviePreview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_MOVIE_PREVIEW_H @@ -45,7 +46,7 @@ public: private: class Impl; - Impl* pimpl; + std::unique_ptr<Impl> pimpl; }; } diff --git a/UnityCore/MusicPreview.cpp b/UnityCore/MusicPreview.cpp index 8d4fd6974..b7246ec18 100644 --- a/UnityCore/MusicPreview.cpp +++ b/UnityCore/MusicPreview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <unity-protocol.h> @@ -32,8 +33,12 @@ class MusicPreview::Impl public: Impl(MusicPreview* owner, glib::Object<GObject> const& proto_obj); + void PlayUri(std::string const& uri) const; + void PauseUri(std::string const& uri) const; + MusicPreview* owner_; - // TODO: keep ref to the proto object as well? + + glib::Object<UnityProtocolMusicPreview> raw_preview_; Tracks::Ptr tracks_model; }; @@ -43,11 +48,11 @@ MusicPreview::Impl::Impl(MusicPreview* owner, , tracks_model(new Tracks()) { const gchar* s; - auto preview = glib::object_cast<UnityProtocolMusicPreview>(proto_obj); + raw_preview_ = glib::object_cast<UnityProtocolMusicPreview>(proto_obj); - s = unity_protocol_music_preview_get_track_data_swarm_name(preview); + s = unity_protocol_music_preview_get_track_data_swarm_name(raw_preview_); std::string swarm_name(s != NULL ? s : ""); - s = unity_protocol_music_preview_get_track_data_address(preview); + s = unity_protocol_music_preview_get_track_data_address(raw_preview_); std::string peer_address(s != NULL ? s : ""); // TODO: we're not using private connection yet @@ -57,6 +62,28 @@ MusicPreview::Impl::Impl(MusicPreview* owner, } } +void MusicPreview::Impl::PlayUri(std::string const& uri) const +{ + UnityProtocolPreview *preview = UNITY_PROTOCOL_PREVIEW(raw_preview_.RawPtr()); + + unity_protocol_preview_begin_updates(preview); + unity_protocol_music_preview_play_uri(raw_preview_, uri.c_str()); + glib::Variant properties(unity_protocol_preview_end_updates(preview), + glib::StealRef()); + owner_->Update(properties); +} + +void MusicPreview::Impl::PauseUri(std::string const& uri) const +{ + UnityProtocolPreview *preview = UNITY_PROTOCOL_PREVIEW(raw_preview_.RawPtr()); + + unity_protocol_preview_begin_updates(preview); + unity_protocol_music_preview_pause_uri(raw_preview_, uri.c_str()); + glib::Variant properties(unity_protocol_preview_end_updates(preview), + glib::StealRef()); + owner_->Update(properties); +} + MusicPreview::MusicPreview(unity::glib::Object<GObject> const& proto_obj) : Preview(proto_obj) , pimpl(new Impl(this, proto_obj)) @@ -65,7 +92,6 @@ MusicPreview::MusicPreview(unity::glib::Object<GObject> const& proto_obj) MusicPreview::~MusicPreview() { - delete pimpl; } Tracks::Ptr MusicPreview::GetTracksModel() const @@ -73,5 +99,15 @@ Tracks::Ptr MusicPreview::GetTracksModel() const return pimpl->tracks_model; } +void MusicPreview::PlayUri(std::string const& uri) const +{ + pimpl->PlayUri(uri); +} + +void MusicPreview::PauseUri(std::string const& uri) const +{ + pimpl->PauseUri(uri); +} + } } diff --git a/UnityCore/MusicPreview.h b/UnityCore/MusicPreview.h index aa9d5b0cf..ec440ea0f 100644 --- a/UnityCore/MusicPreview.h +++ b/UnityCore/MusicPreview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_MUSIC_PREVIEW_H @@ -42,9 +43,12 @@ public: Tracks::Ptr GetTracksModel() const; + void PlayUri(std::string const& uri) const; + void PauseUri(std::string const& uri) const; + private: class Impl; - Impl* pimpl; + std::unique_ptr<Impl> pimpl; }; } diff --git a/UnityCore/Preview.cpp b/UnityCore/Preview.cpp index d8d3da471..ce37ca7db 100644 --- a/UnityCore/Preview.cpp +++ b/UnityCore/Preview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,11 +15,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <NuxCore/Logger.h> #include <unity-protocol.h> +#include "Lens.h" #include "Preview.h" #include "ApplicationPreview.h" @@ -118,6 +120,13 @@ public: ActionPtrList get_actions() const { return actions_list_; }; InfoHintPtrList get_info_hints() const { return info_hint_list_; }; + Lens* get_parent_lens() const { return parent_lens_; }; + bool set_parent_lens(Lens* lens) + { + parent_lens_ = lens; + return false; // TODO: do we need the notifications here? + }; + Preview* owner_; std::string renderer_name_; @@ -127,10 +136,12 @@ public: unity::glib::Object<GIcon> image_; ActionPtrList actions_list_; InfoHintPtrList info_hint_list_; + Lens* parent_lens_; }; Preview::Impl::Impl(Preview* owner, glib::Object<GObject> const& proto_obj) : owner_(owner) + , parent_lens_(nullptr) { if (!proto_obj) { @@ -192,6 +203,11 @@ void Preview::Impl::SetupGetters() sigc::mem_fun(this, &Preview::Impl::get_description)); owner_->image.SetGetterFunction( sigc::mem_fun(this, &Preview::Impl::get_image)); + + owner_->parent_lens.SetGetterFunction( + sigc::mem_fun(this, &Preview::Impl::get_parent_lens)); + owner_->parent_lens.SetSetterFunction( + sigc::mem_fun(this, &Preview::Impl::set_parent_lens)); } Preview::Preview(glib::Object<GObject> const& proto_obj) @@ -200,7 +216,8 @@ Preview::Preview(glib::Object<GObject> const& proto_obj) } Preview::~Preview() -{} +{ +} Preview::ActionPtrList Preview::GetActions() const { @@ -212,5 +229,30 @@ Preview::InfoHintPtrList Preview::GetInfoHints() const return pimpl->get_info_hints(); } +void Preview::Update(glib::Variant const& properties, + glib::DBusProxy::ReplyCallback reply_callback) const +{ + if (pimpl->parent_lens_) + { + pimpl->parent_lens_->SignalPreview(preview_uri, properties, reply_callback); + } + else + { + LOG_WARN(logger) << "Unable to update Preview, parent_lens wasn't set!"; + } +} + +void Preview::PerformAction(std::string const& id) const +{ + if (pimpl->parent_lens_) + { + pimpl->parent_lens_->ActivatePreviewAction(id, preview_uri); + } + else + { + LOG_WARN(logger) << "Unable to perform action, parent_lens wasn't set!"; + } +} + } // namespace dash } // namespace unity diff --git a/UnityCore/Preview.h b/UnityCore/Preview.h index 60fce9169..742bc88ef 100644 --- a/UnityCore/Preview.h +++ b/UnityCore/Preview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2011-2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_PREVIEW_H @@ -31,6 +32,7 @@ #include <NuxCore/Property.h> #include "GLibWrapper.h" +#include "GLibDBusProxy.h" #include "Variant.h" namespace unity @@ -38,6 +40,8 @@ namespace unity namespace dash { +class Lens; + class Preview : public sigc::trackable { public: @@ -85,19 +89,28 @@ public: static Preview::Ptr PreviewForVariant(glib::Variant& properties); static Preview::Ptr PreviewForProtocolObject(glib::Object<GObject> const& proto_obj); - nux::RWProperty<std::string> renderer_name; - nux::RWProperty<std::string> title; - nux::RWProperty<std::string> subtitle; - nux::RWProperty<std::string> description; - nux::RWProperty<unity::glib::Object<GIcon>> image; + nux::ROProperty<std::string> renderer_name; + nux::ROProperty<std::string> title; + nux::ROProperty<std::string> subtitle; + nux::ROProperty<std::string> description; + nux::ROProperty<unity::glib::Object<GIcon>> image; + + // can't use Lens::Ptr to avoid circular dependency + nux::RWProperty<Lens*> parent_lens; + nux::Property<std::string> preview_uri; ActionPtrList GetActions() const; InfoHintPtrList GetInfoHints() const; + void PerformAction(std::string const& id) const; + protected: // this should be UnityProtocolPreview, but we want to keep the usage // of libunity-protocol-private private to unity-core Preview(glib::Object<GObject> const& proto_obj); + void Update(glib::Variant const& properties, + glib::DBusProxy::ReplyCallback reply_callback = + sigc::ptr_fun(&glib::DBusProxy::NoReplyCallback)) const; static glib::Object<GIcon> IconForString(std::string const& icon_hint); private: diff --git a/UnityCore/SeriesPreview.cpp b/UnityCore/SeriesPreview.cpp index b13b28d6d..5f5135638 100644 --- a/UnityCore/SeriesPreview.cpp +++ b/UnityCore/SeriesPreview.cpp @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #include <unity-protocol.h> @@ -32,11 +33,21 @@ public: Impl(SeriesPreview* owner, glib::Object<GObject> const& proto_obj); void SetupGetters(); + void selected_item_reply(GVariant* reply); int get_selected_item_index() const { return selected_item_index_; }; + bool set_selected_item_index(int index); SeriesItemPtrList get_items() const { return items_list_; }; - Preview::Ptr get_child_preview() const { return child_preview_; }; + Preview::Ptr get_child_preview() const + { + if (!child_preview_->parent_lens) + child_preview_->parent_lens = owner_->parent_lens(); + if (child_preview_->preview_uri().empty()) + child_preview_->preview_uri = owner_->preview_uri(); + return child_preview_; + }; SeriesPreview* owner_; + glib::Object<UnityProtocolSeriesPreview> raw_preview_; Preview::Ptr child_preview_; SeriesItemPtrList items_list_; @@ -48,10 +59,11 @@ SeriesPreview::Impl::Impl(SeriesPreview* owner, : owner_(owner) , selected_item_index_(-1) { - auto preview = glib::object_cast<UnityProtocolSeriesPreview>(proto_obj); + raw_preview_ = glib::object_cast<UnityProtocolSeriesPreview>(proto_obj); int items_len; - auto items = unity_protocol_series_preview_get_items(preview, &items_len); + auto items = unity_protocol_series_preview_get_items(raw_preview_, + &items_len); for (int i = 0; i < items_len; i++) { UnityProtocolSeriesItemRaw* raw_item = &items[i]; @@ -60,11 +72,12 @@ SeriesPreview::Impl::Impl(SeriesPreview* owner, } glib::Object<UnityProtocolPreview> child_preview( - unity_protocol_series_preview_get_child_preview(preview), + unity_protocol_series_preview_get_child_preview(raw_preview_), glib::AddRef()); child_preview_ = Preview::PreviewForProtocolObject(glib::object_cast<GObject>(child_preview)); - selected_item_index_ = unity_protocol_series_preview_get_selected_item(preview); + selected_item_index_ = + unity_protocol_series_preview_get_selected_item(raw_preview_); SetupGetters(); } @@ -73,6 +86,43 @@ void SeriesPreview::Impl::SetupGetters() { owner_->selected_item_index.SetGetterFunction( sigc::mem_fun(this, &SeriesPreview::Impl::get_selected_item_index)); + owner_->selected_item_index.SetSetterFunction( + sigc::mem_fun(this, &SeriesPreview::Impl::set_selected_item_index)); +} + +bool SeriesPreview::Impl::set_selected_item_index(int index) +{ + if (index != selected_item_index_) + { + selected_item_index_ = index; + + UnityProtocolPreview *preview = UNITY_PROTOCOL_PREVIEW(raw_preview_.RawPtr()); + unity_protocol_preview_begin_updates(preview); + unity_protocol_series_preview_set_selected_item(raw_preview_, index); + glib::Variant properties(unity_protocol_preview_end_updates(preview), + glib::StealRef()); + owner_->Update(properties, sigc::mem_fun(this, &SeriesPreview::Impl::selected_item_reply)); + return true; + } + + return false; +} + +void SeriesPreview::Impl::selected_item_reply(GVariant *reply) +{ + glib::Variant dict(reply); + glib::HintsMap hints; + dict.ASVToHints(hints); + + auto iter = hints.find("preview"); + if (iter != hints.end()) + { + Preview::Ptr new_child = Preview::PreviewForVariant(iter->second); + new_child->parent_lens = owner_->parent_lens(); + new_child->preview_uri = owner_->preview_uri(); // FIXME: really? + child_preview_ = new_child; + owner_->child_preview_changed.emit(new_child); + } } SeriesPreview::SeriesPreview(unity::glib::Object<GObject> const& proto_obj) @@ -83,7 +133,6 @@ SeriesPreview::SeriesPreview(unity::glib::Object<GObject> const& proto_obj) SeriesPreview::~SeriesPreview() { - delete pimpl; } Preview::Ptr SeriesPreview::GetChildPreview() const diff --git a/UnityCore/SeriesPreview.h b/UnityCore/SeriesPreview.h index 1015c19b0..d67108db5 100644 --- a/UnityCore/SeriesPreview.h +++ b/UnityCore/SeriesPreview.h @@ -1,6 +1,6 @@ // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- /* - * Copyright (C) 2011 Canonical Ltd + * Copyright (C) 2012 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 @@ -15,6 +15,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Michal Hruby <michal.hruby@canonical.com> */ #ifndef UNITY_SERIES_PREVIEW_H @@ -59,9 +60,11 @@ public: SeriesItemPtrList GetItems() const; Preview::Ptr GetChildPreview() const; + sigc::signal<void, Preview::Ptr const&> child_preview_changed; + private: class Impl; - Impl* pimpl; + std::unique_ptr<Impl> pimpl; }; } diff --git a/dash/previews/ApplicationPreview.cpp b/dash/previews/ApplicationPreview.cpp index 763de4aab..7bca26a0c 100644 --- a/dash/previews/ApplicationPreview.cpp +++ b/dash/previews/ApplicationPreview.cpp @@ -24,11 +24,16 @@ #include "ActionButton.h" #include "unity-shared/IntrospectableWrappers.h" #include "unity-shared/PreviewStyle.h" +#include "unity-shared/ApplicationScreenshot.h" +#include "unity-shared/IconTexture.h" +#include <UnityCore/ApplicationPreview.h> #include <NuxCore/Logger.h> #include <Nux/HLayout.h> #include <Nux/VLayout.h> #include <Nux/Button.h> #include <PreviewFactory.h> +#include "PreviewInfoHintWidget.h" +#include "PreviewRatingsWidget.h" namespace unity @@ -50,10 +55,10 @@ public: \ virtual void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) {} \ }; -TMP_VIEW(AppImage, nux::Color(0xAA, 0x00, 0x00)) -TMP_VIEW(AppIcon, nux::Color(0x00, 0x00, 0xAA)) -TMP_VIEW(UserRating, nux::Color(0x00, 0xAA, 0x00)) -TMP_VIEW(Actions, nux::Color(0x00, 0xAA, 0xAA)) +TMP_VIEW(AppImage, nux::Color(0xAA, 0x00, 0x00, 0.1f)) +TMP_VIEW(AppIcon, nux::Color(0x00, 0x00, 0xAA, 0.1f)) +TMP_VIEW(UserRating, nux::Color(0x00, 0xAA, 0x00, 0.1f)) +TMP_VIEW(Actions, nux::Color(0x00, 0xAA, 0xAA, 0.1f)) namespace { @@ -65,7 +70,9 @@ NUX_IMPLEMENT_OBJECT_TYPE(ApplicationPreview); ApplicationPreview::ApplicationPreview(dash::Preview::Ptr preview_model) : Preview(preview_model) +, full_data_layout_(nullptr) { + SetupBackground(); SetupViews(); } @@ -75,12 +82,47 @@ ApplicationPreview::~ApplicationPreview() void ApplicationPreview::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) { - Preview::Draw(gfx_engine, 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 ApplicationPreview::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) { - Preview::DrawContent(gfx_engine, 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(); } std::string ApplicationPreview::GetName() const @@ -93,20 +135,33 @@ void ApplicationPreview::AddProperties(GVariantBuilder* builder) Preview::AddProperties(builder); } +void ApplicationPreview::SetupBackground() +{ + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + details_bg_layer_.reset(new nux::ColorLayer(nux::Color(0.03f, 0.03f, 0.03f, 0.0f), true, rop)); +} void ApplicationPreview::SetupViews() { + dash::ApplicationPreview* app_preview_model = dynamic_cast<dash::ApplicationPreview*>(preview_model_.get()); + if (!app_preview_model) + return; + previews::Style& style = dash::previews::Style::Instance(); nux::HLayout* image_data_layout = new nux::HLayout(); + image_data_layout->SetSpaceBetweenChildren(12); - app_image_ = new TmpView_AppImage(); + ApplicationScreenshot* app_image = new ApplicationScreenshot("../../../dash/previews/Skype.png"); ///////////////////// // App Data Panel - nux::VLayout* full_data_layout = new nux::VLayout(); - full_data_layout->SetPadding(10); - full_data_layout->SetSpaceBetweenChildren(12); + full_data_layout_ = new nux::VLayout(); + full_data_layout_->SetPadding(10); + full_data_layout_->SetSpaceBetweenChildren(16); ///////////////////// // Main App Info @@ -116,52 +171,57 @@ void ApplicationPreview::SetupViews() ///////////////////// // Icon Layout nux::VLayout* icon_layout = new nux::VLayout(); - app_icon_ = new TmpView_AppIcon(); - app_icon_->SetMinimumSize(128,110); - app_icon_->SetMaximumSize(128,110); + app_icon_ = new IconTexture(g_icon_to_string(app_preview_model->app_icon.Get().RawPtr()), 72); + app_icon_->SetMinimumSize(100,100); + app_icon_->SetMaximumSize(100,100); icon_layout->AddView(app_icon_, 0); - app_rating_ = new TmpView_UserRating(); + app_rating_ = new PreviewRatingsWidget(); app_rating_->SetMinimumHeight(36); + app_rating_->SetRating(0.7); + app_rating_->SetReviews(17); icon_layout->AddView(app_rating_, 0); - // buffer space - icon_layout->AddSpace(0,0); + // buffer space ///////////////////// ///////////////////// // App Data nux::VLayout* app_data_layout = new nux::VLayout(); - app_data_layout->SetSpaceBetweenChildren(16); + app_data_layout->SetSpaceBetweenChildren(14); - nux::VLayout* app_name_version_layout = new nux::VLayout(); - app_name_version_layout->SetSpaceBetweenChildren(8); + nux::VLayout* app_name_subtitle_layout = new nux::VLayout(); + app_name_subtitle_layout->SetSpaceBetweenChildren(8); - app_name_ = new nux::StaticCairoText("Skype"); + app_name_ = new nux::StaticCairoText(app_preview_model->title); app_name_->SetFont(style.app_name_font().c_str()); - version_size_ = new nux::StaticCairoText("Version 3.2, Size 32 MB"); - version_size_->SetFont(style.version_size_font().c_str()); + subtitle_ = new nux::StaticCairoText(app_preview_model->subtitle); + subtitle_->SetFont(style.version_size_font().c_str()); nux::VLayout* app_updated_copywrite_layout = new nux::VLayout(); app_updated_copywrite_layout->SetSpaceBetweenChildren(8); - last_update_ = new nux::StaticCairoText("Last updated"); + license_ = new nux::StaticCairoText(app_preview_model->license); + license_->SetFont(style.app_license_font().c_str()); + + last_update_ = new nux::StaticCairoText(std::string("Last Updated ") + app_preview_model->last_update.Get()); last_update_->SetFont(style.app_last_update_font().c_str()); - copywrite_ = new nux::StaticCairoText("Copywrite"); + copywrite_ = new nux::StaticCairoText(app_preview_model->copyright); copywrite_->SetFont(style.app_copywrite_font().c_str()); - app_name_version_layout->AddView(app_name_, 1); - app_name_version_layout->AddView(version_size_, 1); + app_name_subtitle_layout->AddView(app_name_, 1); + app_name_subtitle_layout->AddView(subtitle_, 1); + + app_updated_copywrite_layout->AddView(license_, 1); app_updated_copywrite_layout->AddView(last_update_, 1); app_updated_copywrite_layout->AddView(copywrite_, 1); - app_data_layout->AddLayout(app_name_version_layout); + app_data_layout->AddLayout(app_name_subtitle_layout); app_data_layout->AddLayout(app_updated_copywrite_layout); // buffer space - app_data_layout->AddSpace(0,0); ///////////////////// main_app_info->AddLayout(icon_layout, 0); @@ -170,15 +230,25 @@ void ApplicationPreview::SetupViews() ///////////////////// // App Description + nux::ScrollView* app_info = new nux::ScrollView(NUX_TRACKER_LOCATION); + app_info->EnableHorizontalScrollBar(false); + + nux::VLayout* app_info_layout = new nux::VLayout(); + app_info_layout->SetSpaceBetweenChildren(16); + app_info->SetLayout(app_info_layout); + app_description_ = new nux::StaticCairoText(""); app_description_->SetFont(style.app_description_font().c_str()); app_description_->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_TOP); - app_description_->SetLines(-10); + app_description_->SetLines(-20); app_description_->SetLineSpacing(1); app_description_->SetMaximumWidth(400); - app_description_->SetText("Skype is a proprietary voice-over-Internet Protocol service and software application originally \ -created by Niklas Zennström and Janus Friis in 2003, and owned by Microsoft since 2011. \ -The service allows users to communicate with peers by voice, video, and instant messaging over the Internet."); + app_description_->SetText(app_preview_model->description); + + PreviewInfoHintWidget* preview_info_hints = new PreviewInfoHintWidget(preview_model_); + + app_info_layout->AddView(app_description_); + app_info_layout->AddView(preview_info_hints); ///////////////////// ///////////////////// @@ -189,17 +259,17 @@ The service allows users to communicate with peers by voice, video, and instant for (dash::Preview::ActionPtr action : preview_model_->GetActions()) { - actions_layout->AddView(new ActionButton(action->display_name, NUX_TRACKER_LOCATION), 0, nux::MINOR_POSITION_END, nux::MINOR_SIZE_MATCHCONTENT); + actions_layout->AddView(new ActionButton(action->display_name, NUX_TRACKER_LOCATION), 0); } ///////////////////// - full_data_layout->AddLayout(main_app_info, 0); - full_data_layout->AddView(app_description_, 0); - full_data_layout->AddLayout(actions_layout, 1); + full_data_layout_->AddLayout(main_app_info, 0); + full_data_layout_->AddView(app_info, 1); + full_data_layout_->AddLayout(actions_layout, 0); ///////////////////// - image_data_layout->AddView(app_image_, 1); - image_data_layout->AddLayout(full_data_layout, 1); + image_data_layout->AddView(app_image, 1); + image_data_layout->AddLayout(full_data_layout_, 1); SetLayout(image_data_layout); } diff --git a/dash/previews/ApplicationPreview.h b/dash/previews/ApplicationPreview.h index f1302a90f..d3e880922 100644 --- a/dash/previews/ApplicationPreview.h +++ b/dash/previews/ApplicationPreview.h @@ -25,17 +25,26 @@ #include "Preview.h" #include <Nux/Nux.h> -#include <UnityCore/ApplicationPreview.h> #include "unity-shared/StaticCairoText.h" #include <Nux/StaticText.h> +namespace nux +{ +class AbstractPaintLayer; +class VLayout; +} + namespace unity { +class IconTexture; + namespace dash { namespace previews { +class PreviewRatingsWidget; + class ApplicationPreview : public Preview { public: @@ -53,18 +62,23 @@ protected: virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + void SetupBackground(); void SetupViews(); protected: - nux::View* app_image_; - nux::View* app_icon_; - nux::View* app_rating_; + IconTexture* app_icon_; + PreviewRatingsWidget* app_rating_; + nux::VLayout* full_data_layout_; nux::StaticCairoText* app_name_; - nux::StaticCairoText* version_size_; + nux::StaticCairoText* subtitle_; + nux::StaticCairoText* license_; nux::StaticCairoText* last_update_; nux::StaticCairoText* copywrite_; - nux::StaticCairoText* app_description_; + nux::StaticCairoText* app_description_; + + typedef std::unique_ptr<nux::AbstractPaintLayer> LayerPtr; + LayerPtr details_bg_layer_; }; } diff --git a/dash/previews/CMakeLists.txt b/dash/previews/CMakeLists.txt index bb86c8e8e..0640a89f3 100644 --- a/dash/previews/CMakeLists.txt +++ b/dash/previews/CMakeLists.txt @@ -28,6 +28,7 @@ include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_D # Headers & Sources # set (PREVIEWS_SOURCES + ActionButton.cpp ApplicationPreview.cpp GenericPreview.cpp MusicPreview.cpp @@ -35,8 +36,9 @@ set (PREVIEWS_SOURCES Preview.cpp PreviewContainer.cpp PreviewFactory.cpp + PreviewInfoHintWidget.cpp PreviewNavigator.cpp - ActionButton.cpp + PreviewRatingsWidget.cpp ) add_library (previews-lib STATIC ${PREVIEWS_SOURCES}) diff --git a/dash/previews/Preview.cpp b/dash/previews/Preview.cpp index c3732e1c5..9c54aed77 100644 --- a/dash/previews/Preview.cpp +++ b/dash/previews/Preview.cpp @@ -43,30 +43,12 @@ Preview::Preview(dash::Preview::Ptr preview_model) : View(NUX_TRACKER_LOCATION) , preview_model_(preview_model) { - SetupViews(); } Preview::~Preview() { } -void Preview::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) -{ - // gPainter.Paint2DQuadVGradient(gfx_engine, GetGeometry(), - // nux::Color(0x96, 0x11, 0xDA), nux::Color(0x54, 0xD9, 0x11)); -} - -void Preview::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) -{ - nux::Geometry base = GetGeometry(); - gfx_engine.PushClippingRectangle(base); - - if (GetCompositionLayout()) - GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); - - gfx_engine.PopClippingRectangle(); -} - std::string Preview::GetName() const { return "Preview"; @@ -76,10 +58,6 @@ void Preview::AddProperties(GVariantBuilder* builder) { } -void Preview::SetupViews() -{ -} - } } } diff --git a/dash/previews/Preview.h b/dash/previews/Preview.h index 63c2b355a..c28f9ea32 100644 --- a/dash/previews/Preview.h +++ b/dash/previews/Preview.h @@ -49,11 +49,7 @@ public: void AddProperties(GVariantBuilder* builder); protected: - virtual void Draw(nux::GraphicsEngine& gfx_engine, bool force_draw); - virtual void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw); - - void SetupViews(); - + protected: dash::Preview::Ptr preview_model_; diff --git a/dash/previews/PreviewContainer.cpp b/dash/previews/PreviewContainer.cpp index 35d162c3a..31058c2dc 100644 --- a/dash/previews/PreviewContainer.cpp +++ b/dash/previews/PreviewContainer.cpp @@ -28,6 +28,7 @@ #include "unity-shared/TimeUtil.h" #include "PreviewNavigator.h" #include "PreviewFactory.h" +#include <boost/math/constants/constants.hpp> namespace unity { @@ -42,7 +43,7 @@ nux::logging::Logger logger("unity.dash.previews.previewcontainer"); const int ANIM_DURATION_SHORT_SHORT = 100; const int ANIM_DURATION = 200; -const int ANIM_DURATION_LONG = 350; +const int ANIM_DURATION_LONG = 500; const std::string ANIMATION_IDLE = "animation-idle"; } @@ -50,13 +51,15 @@ const std::string ANIMATION_IDLE = "animation-idle"; class PreviewContent : public nux::Layout { public: - PreviewContent() + PreviewContent(const PreviewContainer*const parent) : progress_(0.0) - , animating_(false) {} + , animating_(false) + , parent_(parent) {} void PushPreview(previews::Preview::Ptr preview, NavButton direction) { AddView(preview.GetPointer()); + preview->SetReconfigureParentLayoutOnGeometryChange(false); preview->SetVisible(false); PreviewSwipe swipe; @@ -68,12 +71,15 @@ public: { UpdateAnimationProgress(0.0); } + start_navigation.emit(); } bool IsAnimating() { return animating_; } int SwipeQueueSize() const { return push_preview_.size(); } + float GetAnimationProgress() const { return progress_; } + void UpdateAnimationProgress(float progress) { progress_ = progress; @@ -85,8 +91,6 @@ public: animating_= true; swipe_ = push_preview_.front(); push_preview_.pop(); - - start_navigation.emit(); } } @@ -100,9 +104,9 @@ public: nux::Geometry swipeOut = geometry; if (swipe_.direction == RIGHT) - swipeOut.OffsetPosition(-(progress_ * geometry.GetWidth()), 0); + swipeOut.OffsetPosition(-(progress_ * (geometry.GetWidth() + parent_->nav_left_->GetGeometry().GetWidth())), 0); else if (swipe_.direction == LEFT) - swipeOut.OffsetPosition(progress_*geometry.GetWidth(), 0); + swipeOut.OffsetPosition(progress_* (geometry.GetWidth() + parent_->nav_right_->GetGeometry().GetWidth()), 0); current_preview_->SetGeometry(swipeOut); } @@ -113,9 +117,9 @@ public: nux::Geometry swipeIn = geometry; if (swipe_.direction == RIGHT) - swipeIn.OffsetPosition(float(geometry.GetWidth()) - (progress_ * geometry.GetWidth()), 0); + swipeIn.OffsetPosition(float(geometry.GetWidth() + parent_->nav_right_->GetGeometry().GetWidth()) - (progress_ * (geometry.GetWidth() + parent_->nav_right_->GetGeometry().GetWidth())), 0); else if (swipe_.direction == LEFT) - swipeIn.OffsetPosition(-((1.0-progress_)*geometry.GetWidth()), 0); + swipeIn.OffsetPosition(-((1.0-progress_)*(geometry.GetWidth() + parent_->nav_left_->GetGeometry().GetWidth())), 0); swipe_.preview->SetGeometry(swipeIn); } } @@ -134,7 +138,11 @@ public: if (push_preview_.size()) { progress_ = 0; - start_navigation.emit(); + continue_navigation.emit(); + } + else + { + end_navigation.emit(); } // set the geometry to the whole layout. @@ -145,13 +153,22 @@ public: } } - // void ProcessDraw(nux::GraphicsEngine& gfx_engine, bool force_draw) - // { - // if (swipe_.preview && swipe_.preview->IsVisible()) { swipe_.preview->ProcessDraw(gfx_engine, force_draw); } - // if (current_preview_) { current_preview_->ProcessDraw(gfx_engine, force_draw); } - // } + // Dont draw in process draw. this is so we can control the z order. + void ProcessDraw(nux::GraphicsEngine& gfx_engine, bool force_draw) + { + } + + void ProcessDraw2(nux::GraphicsEngine& gfx_engine, bool force_draw) + { + if (swipe_.preview && swipe_.preview->IsVisible()) { swipe_.preview->ProcessDraw(gfx_engine, force_draw); } + if (current_preview_ && swipe_.preview->IsVisible()) { current_preview_->ProcessDraw(gfx_engine, force_draw); } + + _queued_draw = false; + } sigc::signal<void> start_navigation; + sigc::signal<void> continue_navigation; + sigc::signal<void> end_navigation; protected: private: @@ -169,15 +186,20 @@ private: float progress_; bool animating_; + const PreviewContainer*const parent_; }; NUX_IMPLEMENT_OBJECT_TYPE(PreviewContainer); PreviewContainer::PreviewContainer(NUX_FILE_LINE_DECL) : View(NUX_FILE_LINE_PARAM) + , content_layout_(nullptr) + , navigation_progress_speed_(0.0) + , navigation_count_(0) { SetupViews(); - + last_progress_time_.tv_sec = 0; + last_progress_time_.tv_nsec = 0; } PreviewContainer::~PreviewContainer() @@ -189,9 +211,9 @@ void PreviewContainer::preview(glib::Variant const& preview, NavButton direction PreviewFactoryOperator previewOperator(PreviewFactory::Instance().Item(preview)); dash::Preview::Ptr model = previewOperator.CreateModel(); - current_preview_ = previewOperator.CreateView(model); + previews::Preview::Ptr preview_view = previewOperator.CreateView(model); - content_layout_->PushPreview(current_preview_, direction); + content_layout_->PushPreview(preview_view, direction); } void PreviewContainer::DisableNavButton(NavButton button) @@ -204,46 +226,35 @@ void PreviewContainer::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) void PreviewContainer::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) { - // rely on the compiz event loop to come back to us in a nice throttling - if (AnimationInProgress()) + nux::Geometry base = GetGeometry(); + gfx_engine.PushClippingRectangle(base); + + // Paint using ProcessDraw2. ProcessDraw is overrided by empty impl so we can control z order. + if (content_layout_) { - auto idle = std::make_shared<glib::Idle>(glib::Source::Priority::DEFAULT); - sources_.Add(idle, ANIMATION_IDLE); - idle->Run([&]() { + // rely on the compiz event loop to come back to us in a nice throttling + if (AnimationInProgress()) + { EnsureAnimation(); - return false; - }); - timespec current; - clock_gettime(CLOCK_MONOTONIC, ¤t); + timespec current; + clock_gettime(CLOCK_MONOTONIC, ¤t); + content_layout_->UpdateAnimationProgress(GetSwipeAnimationProgress(current)); + last_progress_time_ = current; + } + else if (content_layout_ && content_layout_->IsAnimating()) + { + content_layout_->UpdateAnimationProgress(1.0f); + } - content_layout_->UpdateAnimationProgress(GetSwipeAnimationProgress(current)); - } - else if (content_layout_->IsAnimating()) - { - content_layout_->UpdateAnimationProgress(1.0f); + content_layout_->ProcessDraw2(gfx_engine, force_draw); } - - nux::Geometry base = GetGeometry(); - gfx_engine.PushClippingRectangle(base); - if (GetCompositionLayout()) GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); gfx_engine.PopClippingRectangle(); } -float PreviewContainer::GetSwipeAnimationProgress(struct timespec const& current) const -{ - return CLAMP((float)(unity::TimeUtil::TimeDelta(¤t, &_times[TIME_PREVIEW_NAVIGATE])) / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); -} - - -void PreviewContainer::EnsureAnimation() -{ - QueueDraw(); -} - std::string PreviewContainer::GetName() const { return "PreviewContainer"; @@ -266,7 +277,7 @@ void PreviewContainer::SetupViews() nav_left_->activated.connect([&]() { navigate_left.emit(); }); layout_->AddView(nav_left_, 0); - content_layout_ = new PreviewContent(); + content_layout_ = new PreviewContent(this); layout_->AddLayout(content_layout_, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); nav_right_ = new PreviewNavigator(Orientation::RIGHT, NUX_TRACKER_LOCATION); @@ -277,9 +288,27 @@ void PreviewContainer::SetupViews() content_layout_->start_navigation.connect([&]() { - TimeUtil::SetTimeStruct(&_times[TIME_PREVIEW_NAVIGATE], &_times[TIME_PREVIEW_NAVIGATE], ANIM_DURATION_LONG); + // reset animation clock. + if (navigation_count_ == 0) + clock_gettime(CLOCK_MONOTONIC, &last_progress_time_); + + float navigation_progress_remaining = CLAMP((1.0 - content_layout_->GetAnimationProgress()) + navigation_count_, 1.0f, 10.0f); + navigation_count_++; + + navigation_progress_speed_ = navigation_progress_remaining / ANIM_DURATION_LONG; EnsureAnimation(); }); + + content_layout_->continue_navigation.connect([&]() + { + EnsureAnimation(); + }); + + content_layout_->end_navigation.connect([&]() + { + navigation_count_ = 0; + navigation_progress_speed_ = 0; + }); } bool PreviewContainer::AnimationInProgress() @@ -288,13 +317,34 @@ bool PreviewContainer::AnimationInProgress() struct timespec current; clock_gettime(CLOCK_MONOTONIC, ¤t); + if (content_layout_ == nullptr) + return false; + // hover in animation - if (unity::TimeUtil::TimeDelta(¤t, &_times[TIME_PREVIEW_NAVIGATE]) < ANIM_DURATION_LONG) + if (navigation_progress_speed_ > 0) return true; return false; } +float PreviewContainer::GetSwipeAnimationProgress(struct timespec const& current) const +{ + int time_delta = TimeUtil::TimeDelta(¤t, &last_progress_time_); + float progress = content_layout_->GetAnimationProgress() + (navigation_progress_speed_ * time_delta); + + // ease in/out. + return progress; +} + +void PreviewContainer::EnsureAnimation() +{ + auto idle = std::make_shared<glib::Idle>(glib::Source::Priority::DEFAULT); + sources_.Add(idle, ANIMATION_IDLE); + idle->Run([&]() { + QueueDraw(); + return false; + }); +} } diff --git a/dash/previews/PreviewContainer.h b/dash/previews/PreviewContainer.h index bd141d65b..98ff9f550 100644 --- a/dash/previews/PreviewContainer.h +++ b/dash/previews/PreviewContainer.h @@ -28,6 +28,7 @@ #include <UnityCore/Preview.h> #include "Preview.h" #include "unity-shared/Introspectable.h" + #include <UnityCore/GLibSource.h> namespace unity @@ -86,16 +87,14 @@ private: PreviewNavigator* nav_left_; PreviewNavigator* nav_right_; PreviewContent* content_layout_; - previews::Preview::Ptr current_preview_; // Animation - typedef enum { - TIME_PREVIEW_NAVIGATE, - TIME_LAST - } PreviewActionTimes; - struct timespec _times[TIME_LAST]; + struct timespec last_progress_time_; + float navigation_progress_speed_; + int navigation_count_; glib::SourceManager sources_; + friend class PreviewContent; }; } // napespace prviews diff --git a/dash/previews/PreviewInfoHintWidget.cpp b/dash/previews/PreviewInfoHintWidget.cpp new file mode 100644 index 000000000..f8e07563f --- /dev/null +++ b/dash/previews/PreviewInfoHintWidget.cpp @@ -0,0 +1,126 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Nick Dedekind <nick.dedekind@canonical.com> + * + */ + +#include "PreviewInfoHintWidget.h" +#include "unity-shared/IntrospectableWrappers.h" +#include <NuxCore/Logger.h> +#include <Nux/HLayout.h> +#include <Nux/VLayout.h> +#include <unity-shared/StaticCairoText.h> +#include <unity-shared/IconTexture.h> +#include <unity-shared/PreviewStyle.h> + +namespace unity +{ +namespace dash +{ +namespace previews +{ +nux::logging::Logger logger("unity.dash.previews.previewinfohintwidget"); + +NUX_IMPLEMENT_OBJECT_TYPE(PreviewInfoHintWidget); + +PreviewInfoHintWidget::PreviewInfoHintWidget(dash::Preview::Ptr preview_model) + : View(NUX_TRACKER_LOCATION) + , preview_model_(preview_model) +{ + SetupViews(); +} + +PreviewInfoHintWidget::~PreviewInfoHintWidget() +{ +} + +void PreviewInfoHintWidget::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ +} + +void PreviewInfoHintWidget::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ + nux::Geometry base = GetGeometry(); + gfx_engine.PushClippingRectangle(base); + + if (GetCompositionLayout()) + { + 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); + + GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); + + gfx_engine.GetRenderStates().SetBlend(alpha, src, dest); + } + + gfx_engine.PopClippingRectangle(); +} + +std::string PreviewInfoHintWidget::GetName() const +{ + return "PreviewInfoHintWidget"; +} + +void PreviewInfoHintWidget::AddProperties(GVariantBuilder* builder) +{ +} + +void PreviewInfoHintWidget::SetupViews() +{ + previews::Style& style = previews::Style::Instance(); + + nux::VLayout* layout = new nux::VLayout(); + + for (dash::Preview::InfoHintPtr info_hint : preview_model_->GetInfoHints()) + { + nux::HLayout* hint_layout = new nux::HLayout(); + hint_layout->SetSpaceBetweenChildren(16); + + int icon_width = 32; + + IconTexture* info_icon = new IconTexture(info_hint->icon_hint, icon_width); + info_icon->SetMinimumSize(icon_width, icon_width); + info_icon->SetVisible(true); + hint_layout->AddView(info_icon, 0); + + nux::StaticCairoText* info_name = new nux::StaticCairoText(info_hint->display_name, NUX_TRACKER_LOCATION); + info_name->SetFont(style.info_hint_font()); + nux::Layout* info_name_layout = new nux::HLayout(); + info_name_layout->AddView(info_name, 1, nux::MINOR_POSITION_CENTER); + info_name_layout->SetMaximumWidth(128 - (icon_width > 0 ? (icon_width + 16) : 0)); + + + nux::StaticCairoText* info_value = new nux::StaticCairoText(info_hint->value.GetString(), NUX_TRACKER_LOCATION); + info_value->SetFont(style.info_hint_font()); + nux::Layout* info_value_layout = new nux::HLayout(); + info_value_layout->AddView(info_value, 1, nux::MINOR_POSITION_CENTER); + + hint_layout->AddView(info_name_layout, 1); + hint_layout->AddView(info_value_layout, 1); + + layout->AddLayout(hint_layout, 0); + } + + SetLayout(layout); +} + +} // namespace previews +} // namespace dash +} // namespace unity diff --git a/dash/previews/PreviewInfoHintWidget.h b/dash/previews/PreviewInfoHintWidget.h new file mode 100644 index 000000000..db0f46a04 --- /dev/null +++ b/dash/previews/PreviewInfoHintWidget.h @@ -0,0 +1,73 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Nick Dedekind <nick.dedekind@canonical.com> + * + */ + +#ifndef PREVIEWINFOHINTWIDGET_H +#define PREVIEWINFOHINTWIDGET_H + +#include <Nux/Nux.h> +#include <Nux/View.h> +#include <UnityCore/Preview.h> +#include "unity-shared/Introspectable.h" + + +namespace unity +{ +namespace dash +{ +namespace previews +{ + +class PreviewInfoHintWidget : public nux::View, public debug::Introspectable +{ +public: + typedef nux::ObjectPtr<PreviewInfoHintWidget> Ptr; + NUX_DECLARE_OBJECT_TYPE(PreviewInfoHintWidget, nux::View); + + PreviewInfoHintWidget(dash::Preview::Ptr preview_model); + virtual ~PreviewInfoHintWidget(); + + // From debug::Introspectable + std::string GetName() const; + void AddProperties(GVariantBuilder* builder); + +protected: + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + + void SetupBackground(); + void SetupViews(); + + void IconLoaded(std::string const& texid, + unsigned size, + glib::Object<GdkPixbuf> const& pixbuf, + std::string icon_name); + +protected: + dash::Preview::Ptr preview_model_; + typedef nux::ObjectPtr<nux::BaseTexture> BaseTexturePtr; +}; + +} // napespace prviews +} // namespace dash +} // namespace unity + +#endif //PREVIEWINFOHINTWIDGET_H diff --git a/dash/previews/PreviewNavigator.cpp b/dash/previews/PreviewNavigator.cpp index 20fc4fb67..c2f45e068 100644 --- a/dash/previews/PreviewNavigator.cpp +++ b/dash/previews/PreviewNavigator.cpp @@ -59,10 +59,6 @@ void PreviewNavigator::AddProperties(GVariantBuilder* builder) void PreviewNavigator::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) { - // just for debugging, draw a vertical gradient - gPainter.Paint2DQuadVGradient(gfx_engine, GetGeometry(), - nux::Color(0x54, 0xD9, 0x11), nux::Color(0x96, 0x11, 0xDA)); - } void PreviewNavigator::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) diff --git a/dash/previews/PreviewRatingsWidget.cpp b/dash/previews/PreviewRatingsWidget.cpp new file mode 100644 index 000000000..5951abc38 --- /dev/null +++ b/dash/previews/PreviewRatingsWidget.cpp @@ -0,0 +1,100 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include <Nux/Nux.h> +#include <Nux/VLayout.h> +#include <glib.h> +#include <glib/gi18n-lib.h> + +#include "unity-shared/RatingsButton.h" +#include "unity-shared/StaticCairoText.h" +#include "unity-shared/PreviewStyle.h" +#include "PreviewRatingsWidget.h" + +namespace unity +{ +namespace dash +{ +namespace previews +{ + +NUX_IMPLEMENT_OBJECT_TYPE(PreviewRatingsWidget); + +PreviewRatingsWidget::PreviewRatingsWidget(NUX_FILE_LINE_DECL) + : View(NUX_FILE_LINE_PARAM) +{ + nux::VLayout* layout = new nux::VLayout(); + + previews::Style& style = previews::Style::Instance(); + + ratings_ = new RatingsButton(18,2); + ratings_->SetEditable(false); + layout->AddView(ratings_); + + + reviews_ = new nux::StaticCairoText(""); + reviews_->SetFont(style.user_rating_font()); + layout->AddView(reviews_); + + SetLayout(layout); +} + +PreviewRatingsWidget::~PreviewRatingsWidget() +{ +} + +void PreviewRatingsWidget::SetRating(float rating) +{ + ratings_->SetRating(rating); +} + +void PreviewRatingsWidget::SetReviews(int count) +{ + std::stringstream out; + out << count; + out << " reviews"; + + reviews_->SetText(out.str()); +} + + + +void PreviewRatingsWidget::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ +} + +void PreviewRatingsWidget::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ + nux::Geometry const& base = GetGeometry(); + gfx_engine.PushClippingRectangle(base); + + if (GetCompositionLayout()) + GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); + + gfx_engine.PopClippingRectangle(); +} + + + +} // namespace previews +} // namespace dash +} // namespace unity diff --git a/dash/previews/PreviewRatingsWidget.h b/dash/previews/PreviewRatingsWidget.h new file mode 100644 index 000000000..15abb00a2 --- /dev/null +++ b/dash/previews/PreviewRatingsWidget.h @@ -0,0 +1,65 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Gordon Allott <gord.allott@canonical.com> + * + */ + +#ifndef UNITYSHELL_PREVIEWRATINGSWIDGET_H +#define UNITYSHELL_PREVIEWRATINGSWIDGET_H + +#include <Nux/Nux.h> +#include <Nux/View.h> + +namespace nux +{ +class StaticCairoText; +} + +namespace unity +{ +class RatingsButton; +namespace dash +{ +namespace previews +{ + +class PreviewRatingsWidget : public nux::View +{ + NUX_DECLARE_OBJECT_TYPE(PreviewRatingsWidget, nux::View); +public: + PreviewRatingsWidget(NUX_FILE_LINE_PROTO); + virtual ~PreviewRatingsWidget(); + + void SetRating(float rating); + void SetReviews(int count); + +protected: + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + virtual void DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw); + +private: + RatingsButton* ratings_; + nux::StaticCairoText* reviews_; +}; + +} // namespace previews +} // namespace dash +} // namespace unity + +#endif // UNITYSHELL_PREVIEWRATINGSWIDGET_H diff --git a/dash/previews/Skype.png b/dash/previews/Skype.png Binary files differnew file mode 100755 index 000000000..cb86ca8eb --- /dev/null +++ b/dash/previews/Skype.png diff --git a/dash/previews/Standalone.cpp b/dash/previews/Standalone.cpp index 7b52a5218..e1f218679 100644 --- a/dash/previews/Standalone.cpp +++ b/dash/previews/Standalone.cpp @@ -23,6 +23,7 @@ #include "Nux/VLayout.h" #include "Nux/WindowThread.h" #include "NuxGraphics/GraphicsEngine.h" +#include <Nux/Layout.h> #include <NuxCore/Logger.h> #include <UnityCore/Variant.h> #include <UnityCore/Preview.h> @@ -42,12 +43,71 @@ #include "PreviewContainer.h" -#define WIDTH 940 -#define HEIGHT 420 +#define WIDTH 972 +#define HEIGHT 452 using namespace unity; using namespace unity::dash; +class DummyView : public nux::View +{ +public: + DummyView(nux::View* view) + : View(NUX_TRACKER_LOCATION) + { + nux::ROPConfig rop; + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + bg_layer_.reset(new nux::ColorLayer(nux::Color(81, 26, 48), true, rop)); + + nux::Layout* layout = new nux::VLayout(); + layout->SetPadding(16); + layout->AddView(view, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + SetLayout(layout); + } + +protected: + virtual void Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) + { + nux::Geometry const& base = GetGeometry(); + + gfx_engine.PushClippingRectangle(base); + nux::GetPainter().PaintBackground(gfx_engine, base); + + 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); + + bg_layer_->SetGeometry(GetGeometry()); + nux::GetPainter().RenderSinglePaintLayer(gfx_engine, GetGeometry(), bg_layer_.get()); + + gfx_engine.GetRenderStates().SetBlend(alpha, src, dest); + + gfx_engine.PopClippingRectangle(); + } + + virtual void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) + { + nux::Geometry const& base = GetGeometry(); + gfx_engine.PushClippingRectangle(base); + + if (!IsFullRedraw()) + nux::GetPainter().PushLayer(gfx_engine, GetGeometry(), bg_layer_.get()); + + if (GetCompositionLayout()) + GetCompositionLayout()->ProcessDraw(gfx_engine, force_draw); + + if (!IsFullRedraw()) + nux::GetPainter().PopBackground(); + + gfx_engine.PopClippingRectangle(); + } + + typedef std::unique_ptr<nux::AbstractPaintLayer> LayerPtr; + LayerPtr bg_layer_; +}; + class TestRunner { public: @@ -61,10 +121,12 @@ public: previews::PreviewContainer::Ptr container_; nux::Layout *layout_; + int nav_iter; }; TestRunner::TestRunner () { + nav_iter = 0; } TestRunner::~TestRunner () @@ -73,49 +135,88 @@ TestRunner::~TestRunner () void TestRunner::Init () { - container_ = new previews::PreviewContainer(NUX_TRACKER_LOCATION); - container_->SetMinMaxSize(WIDTH, HEIGHT); container_->navigate_right.connect(sigc::mem_fun(this, &TestRunner::NavRight)); container_->navigate_left.connect(sigc::mem_fun(this, &TestRunner::NavLeft)); + DummyView* dummyView = new DummyView(container_.GetPointer()); layout_ = new nux::VLayout(NUX_TRACKER_LOCATION); - layout_->AddView(container_.GetPointer(), 1, nux::MINOR_POSITION_CENTER); - layout_->SetMinMaxSize(WIDTH, HEIGHT); - - // creates a generic preview object + layout_->AddView(dummyView, 1, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + nux::GetWindowThread()->SetLayout (layout_); + + + std::stringstream app_name; + app_name << "Title " << nav_iter; + + const char* subtitle = "Version 3.2, Size 32 MB"; + const char* description = "Skype is a proprietary voice-over-Internet Protocol service and software application originally created by Niklas Zennström and Janus Friis in 2003, and owned by Microsoft since 2011. \ +The service allows users to communicate with peers by voice, video, and instant messaging over the Internet. Phone calls may be placed to recipients on the traditional telephone networks. Calls to other users within the Skype service are free of charge, while calls to landline telephones and mobile phones are charged via a debit-based user account system."; + + // creates a generic preview object glib::Object<GIcon> icon(g_icon_new_for_string("accessories", NULL)); + glib::Object<GIcon> iconHint1(g_icon_new_for_string("/usr/share/unity/5/lens-nav-music.svg", NULL)); + glib::Object<GIcon> iconHint2(g_icon_new_for_string("/usr/share/unity/5/lens-nav-home.svg", NULL)); + glib::Object<GIcon> iconHint3(g_icon_new_for_string("/usr/share/unity/5/lens-nav-people.svg", NULL)); + glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_application_preview_new())); - unity_protocol_preview_set_title(proto_obj, "Title"); - unity_protocol_preview_set_subtitle(proto_obj, "Subtitle"); - unity_protocol_preview_set_description(proto_obj, "Description"); + + unity_protocol_application_preview_set_app_icon(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), g_icon_new_for_string("/home/nick/Work/unity/preview-infrastructure/build/dash/previews/SkypeIcon.png", NULL)); + unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "Proprietary"); + unity_protocol_application_preview_set_copyright(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "(c) Skype 2012"); + unity_protocol_application_preview_set_last_update(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "11th Apr 2012"); + + + unity_protocol_preview_set_title(proto_obj, app_name.str().c_str()); + unity_protocol_preview_set_subtitle(proto_obj, subtitle); + unity_protocol_preview_set_description(proto_obj, description); unity_protocol_preview_set_thumbnail(proto_obj, icon); - unity_protocol_preview_add_action(proto_obj, "action1", "Action #1", NULL, 0); - unity_protocol_preview_add_action(proto_obj, "action2", "Action #2", NULL, 0); - unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("i", 34)); - unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint")); + unity_protocol_preview_add_action(proto_obj, "uninstall", "Uninstall", NULL, 0); + unity_protocol_preview_add_action(proto_obj, "launch", "Launch", NULL, 0); + unity_protocol_preview_add_info_hint(proto_obj, "time", "Total time", iconHint1, g_variant_new("s", "16 h 34miin 45sec")); + unity_protocol_preview_add_info_hint(proto_obj, "energy", "Energy", iconHint2, g_variant_new("s", "58.07 mWh")); + unity_protocol_preview_add_info_hint(proto_obj, "load", "CPU Load", iconHint3, g_variant_new("i", 12)); + glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef()); container_->preview(v, previews::RIGHT); - nux::GetWindowThread()->SetLayout (layout_); } void TestRunner::NavRight() { - // creates a generic preview object + std::stringstream app_name; + app_name << "Title " << ++nav_iter; + + const char* subtitle = "Version 3.2, Size 32 MB"; + const char* description = "Skype is a proprietary voice-over-Internet Protocol service and software application originally created by Niklas Zennström and Janus Friis in 2003, and owned by Microsoft since 2011. \ +The service allows users to communicate with peers by voice, video, and instant messaging over the Internet. Phone calls may be placed to recipients on the traditional telephone networks. Calls to other users within the Skype service are free of charge, while calls to landline telephones and mobile phones are charged via a debit-based user account system."; + + // creates a generic preview object glib::Object<GIcon> icon(g_icon_new_for_string("accessories", NULL)); + glib::Object<GIcon> iconHint1(g_icon_new_for_string("/usr/share/unity/5/lens-nav-music.svg", NULL)); + glib::Object<GIcon> iconHint2(g_icon_new_for_string("/usr/share/unity/5/lens-nav-home.svg", NULL)); + glib::Object<GIcon> iconHint3(g_icon_new_for_string("/usr/share/unity/5/lens-nav-people.svg", NULL)); + glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_application_preview_new())); - unity_protocol_preview_set_title(proto_obj, "Title"); - unity_protocol_preview_set_subtitle(proto_obj, "Subtitle"); - unity_protocol_preview_set_description(proto_obj, "Description"); + + + unity_protocol_application_preview_set_app_icon(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), g_icon_new_for_string("/home/nick/Work/unity/preview-infrastructure/build/dash/previews/SkypeIcon.png", NULL)); + unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "Proprietary"); + unity_protocol_application_preview_set_copyright(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "(c) Skype 2012"); + unity_protocol_application_preview_set_last_update(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "11th Apr 2012"); + + unity_protocol_preview_set_title(proto_obj, app_name.str().c_str()); + unity_protocol_preview_set_subtitle(proto_obj, subtitle); + unity_protocol_preview_set_description(proto_obj, description); unity_protocol_preview_set_thumbnail(proto_obj, icon); - unity_protocol_preview_add_action(proto_obj, "action1", "Action #1", NULL, 0); - unity_protocol_preview_add_action(proto_obj, "action2", "Action #2", NULL, 0); - unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("i", 34)); - unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint")); + unity_protocol_preview_add_action(proto_obj, "uninstall", "Uninstall", NULL, 0); + unity_protocol_preview_add_action(proto_obj, "launch", "Launch", NULL, 0); + unity_protocol_preview_add_info_hint(proto_obj, "time", "Total time", iconHint1, g_variant_new("s", "16 h 34miin 45sec")); + unity_protocol_preview_add_info_hint(proto_obj, "energy", "Energy", iconHint2, g_variant_new("s", "58.07 mWh")); + unity_protocol_preview_add_info_hint(proto_obj, "load", "CPU Load", iconHint3, g_variant_new("i", 12)); + glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef()); @@ -125,17 +226,36 @@ void TestRunner::NavRight() void TestRunner::NavLeft() { - // creates a generic preview object + std::stringstream app_name; + app_name << "Title " << --nav_iter; + + const char* subtitle = "Version 3.2, Size 32 MB"; + const char* description = "Skype is a proprietary voice-over-Internet Protocol service and software application originally created by Niklas Zennström and Janus Friis in 2003, and owned by Microsoft since 2011. \ +The service allows users to communicate with peers by voice, video, and instant messaging over the Internet. Phone calls may be placed to recipients on the traditional telephone networks. Calls to other users within the Skype service are free of charge, while calls to landline telephones and mobile phones are charged via a debit-based user account system."; + + // creates a generic preview object glib::Object<GIcon> icon(g_icon_new_for_string("accessories", NULL)); + glib::Object<GIcon> iconHint1(g_icon_new_for_string("/usr/share/unity/5/lens-nav-music.svg", NULL)); + glib::Object<GIcon> iconHint2(g_icon_new_for_string("/usr/share/unity/5/lens-nav-home.svg", NULL)); + glib::Object<GIcon> iconHint3(g_icon_new_for_string("/usr/share/unity/5/lens-nav-people.svg", NULL)); + glib::Object<UnityProtocolPreview> proto_obj(UNITY_PROTOCOL_PREVIEW(unity_protocol_application_preview_new())); - unity_protocol_preview_set_title(proto_obj, "Title"); - unity_protocol_preview_set_subtitle(proto_obj, "Subtitle"); - unity_protocol_preview_set_description(proto_obj, "Description"); + + + unity_protocol_application_preview_set_app_icon(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), g_icon_new_for_string("/home/nick/Work/unity/preview-infrastructure/build/dash/previews/SkypeIcon.png", NULL)); + unity_protocol_application_preview_set_license(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "Proprietary"); + unity_protocol_application_preview_set_copyright(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "(c) Skype 2012"); + unity_protocol_application_preview_set_last_update(UNITY_PROTOCOL_APPLICATION_PREVIEW(proto_obj.RawPtr()), "11th Apr 2012"); + + unity_protocol_preview_set_title(proto_obj, app_name.str().c_str()); + unity_protocol_preview_set_subtitle(proto_obj, subtitle); + unity_protocol_preview_set_description(proto_obj, description); unity_protocol_preview_set_thumbnail(proto_obj, icon); - unity_protocol_preview_add_action(proto_obj, "action1", "Action #1", NULL, 0); - unity_protocol_preview_add_action(proto_obj, "action2", "Action #2", NULL, 0); - unity_protocol_preview_add_info_hint(proto_obj, "hint1", "Hint 1", NULL, g_variant_new("i", 34)); - unity_protocol_preview_add_info_hint(proto_obj, "hint2", "Hint 2", NULL, g_variant_new("s", "string hint")); + unity_protocol_preview_add_action(proto_obj, "uninstall", "Uninstall", NULL, 0); + unity_protocol_preview_add_action(proto_obj, "launch", "Launch", NULL, 0); + unity_protocol_preview_add_info_hint(proto_obj, "time", "Total time", iconHint1, g_variant_new("s", "16 h 34miin 45sec")); + unity_protocol_preview_add_info_hint(proto_obj, "energy", "Energy", iconHint2, g_variant_new("s", "58.07 mWh")); + unity_protocol_preview_add_info_hint(proto_obj, "load", "CPU Load", iconHint3, g_variant_new("i", 12)); glib::Variant v(dee_serializable_serialize(DEE_SERIALIZABLE(proto_obj.RawPtr())), glib::StealRef()); diff --git a/unity-shared/ApplicationScreenshot.cpp b/unity-shared/ApplicationScreenshot.cpp new file mode 100644 index 000000000..da87210b2 --- /dev/null +++ b/unity-shared/ApplicationScreenshot.cpp @@ -0,0 +1,125 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Andrea Cimitan <andrea.cimitan@canonical.com> + * + */ + +#include "ApplicationScreenshot.h" +#include "unity-shared/IntrospectableWrappers.h" +#include <NuxCore/Logger.h> + +namespace unity +{ +namespace dash +{ +namespace previews +{ + +namespace +{ +nux::logging::Logger logger("unity.dash.previews.applicationscreenshot"); +} + +NUX_IMPLEMENT_OBJECT_TYPE(ApplicationScreenshot); + +ApplicationScreenshot::ApplicationScreenshot(std::string const& image_hint) + : View(NUX_TRACKER_LOCATION) +{ + texture_screenshot_.Adopt(nux::CreateTexture2DFromFile(image_hint.c_str(), -1, true)); + SetupViews(); +} + +ApplicationScreenshot::~ApplicationScreenshot() +{ +} + +void ApplicationScreenshot::Draw(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ + nux::Geometry const& base = GetGeometry(); + + gfx_engine.PushClippingRectangle(base); + nux::GetPainter().PaintBackground(gfx_engine, base); + + gfx_engine.PopClippingRectangle(); +} + +void ApplicationScreenshot::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw) +{ + nux::Geometry const& base = GetGeometry(); + gfx_engine.PushClippingRectangle(base); + + if (texture_screenshot_) + { + nux::Geometry imageDest = base; + nux::TexCoordXForm texxform; + + float base_apsect = float(base.GetWidth()) / base.GetHeight(); + float image_aspect = float(texture_screenshot_->GetWidth()) / texture_screenshot_->GetHeight(); + + if (image_aspect > base_apsect) + { + imageDest.SetHeight(float(imageDest.GetWidth())/image_aspect); + } + if (image_aspect < base_apsect) + { + imageDest.SetWidth(image_aspect*imageDest.GetHeight()); + } + + int border_width = 1; + + //DrawBorder(gfx_engine, imageDest, 0, nux::Color(0.15f, 0.15f, 0.15f)); + gfx_engine.QRP_Color(imageDest.x + (float(base.GetWidth() - imageDest.GetWidth()) / 2), + imageDest.y + (float(base.GetHeight() - imageDest.GetHeight()) / 2), + imageDest.GetWidth(), + imageDest.GetHeight(), + nux::Color(0.15f, 0.15f, 0.15f)); + + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_SCALE_COORD); + texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER); + texxform.SetFilter(nux::TEXFILTER_LINEAR, nux::TEXFILTER_LINEAR); + + texxform.u0 = 0; + texxform.v0 = 0; + texxform.u1 = imageDest.width; + texxform.v1 = imageDest.height; + + gfx_engine.QRP_1Tex(imageDest.x + (float(base.GetWidth() - imageDest.GetWidth()) / 2) + border_width, + imageDest.y + (float(base.GetHeight() - imageDest.GetHeight()) / 2) + border_width, + imageDest.width - (border_width * 2), + imageDest.height - (border_width * 2), + texture_screenshot_.GetPointer()->GetDeviceTexture(), + texxform, + nux::color::White); + } + + gfx_engine.PopClippingRectangle(); +} + +std::string ApplicationScreenshot::GetName() const +{ + return "ApplicationScreenshot"; +} + +void ApplicationScreenshot::SetupViews() +{ +} + +} +} +} \ No newline at end of file diff --git a/unity-shared/ApplicationScreenshot.h b/unity-shared/ApplicationScreenshot.h new file mode 100644 index 000000000..e61e551e5 --- /dev/null +++ b/unity-shared/ApplicationScreenshot.h @@ -0,0 +1,67 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright 2011 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: Andrea Cimitan <andrea.cimitan@canonical.com> + * + */ + +#ifndef APPLICATIONSCREENSHOT_H +#define APPLICATIONSCREENSHOT_H + +#include <Nux/Nux.h> +#include <Nux/View.h> +#include <UnityCore/ApplicationPreview.h> +#include "unity-shared/StaticCairoText.h" +#include <Nux/StaticText.h> +#include <NuxCore/ObjectPtr.h> + +namespace unity +{ +namespace dash +{ +namespace previews +{ + +class ApplicationScreenshot : public nux::View +{ +public: + typedef nux::ObjectPtr<ApplicationScreenshot> Ptr; + NUX_DECLARE_OBJECT_TYPE(ApplicationScreenshot, nux::View); + + ApplicationScreenshot(std::string const& image_hint); + virtual ~ApplicationScreenshot(); + + // From debug::Introspectable + std::string GetName() const; + +protected: + virtual void Draw(nux::GraphicsEngine& gfx_engine, bool force_draw); + virtual void DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw); + + void SetupViews(); + +private: + nux::ObjectPtr<nux::BaseTexture> texture_screenshot_; + +}; + +} +} +} + +#endif // APPLICATIONSCREENSHOT_H \ No newline at end of file diff --git a/unity-shared/CMakeLists.txt b/unity-shared/CMakeLists.txt index 49193fafa..4a0c11471 100644 --- a/unity-shared/CMakeLists.txt +++ b/unity-shared/CMakeLists.txt @@ -30,6 +30,7 @@ include_directories (. .. ../services ../UnityCore ${UNITY_SRC} ${CMAKE_BINARY_D set (UNITY_SHARED_SOURCES AbstractSeparator.cpp Animator.cpp + ApplicationScreenshot.cpp BGHash.cpp BackgroundEffectHelper.cpp DashStyle.cpp @@ -46,6 +47,7 @@ set (UNITY_SHARED_SOURCES OverlayRenderer.cpp PanelStyle.cpp PreviewStyle.cpp + RatingsButton.cpp SearchBar.cpp SearchBarSpinner.cpp StaticCairoText.cpp diff --git a/unity-shared/IconTexture.cpp b/unity-shared/IconTexture.cpp index f97e5eb43..45c4a06a8 100644 --- a/unity-shared/IconTexture.cpp +++ b/unity-shared/IconTexture.cpp @@ -181,7 +181,7 @@ void IconTexture::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) GfxContext.PushClippingRectangle(geo); - nux::GetPainter().PaintBackground(GfxContext, geo); + //nux::GetPainter().PaintBackground(GfxContext, geo); if (_texture_cached) { diff --git a/unity-shared/IdleAnimator.cpp b/unity-shared/IdleAnimator.cpp new file mode 100644 index 000000000..b134c11c4 --- /dev/null +++ b/unity-shared/IdleAnimator.cpp @@ -0,0 +1,104 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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: Marco Trevisan (Treviño) <mail@3v1n0.net> + */ + +#include "IdleAnimator.h" + +namespace unity +{ + +IdleAnimator::IdleAnimator(unsigned int duration_) + : duration_(0) +{ + SetDuration(duration_); +} + +IdleAnimator::~IdleAnimator() +{ + Stop(); +} + + +void IdleAnimator::SetDuration(unsigned int duration) +{ + duration_ = duration * 1000; +} + +unsigned int IdleAnimator::GetRate() const +{ + if (rate_ != 0) + return 1000 / rate_; + + return rate_; +} + +unsigned int IdleAnimator::GetDuration() const +{ + return (one_time_duration_ > 0 ? one_time_duration_ : duration_) / 1000; +} + +bool IdleAnimator::IsRunning() const +{ + // short circuit to avoid unneeded calculations + struct timespec current; + clock_gettime(CLOCK_MONOTONIC, ¤t); + + // hover in animation + if (unity::TimeUtil::TimeDelta(¤t, &_times) < ANIM_DURATION_LONG) + return true; + + return false; +} + +void IdleAnimator::Start(unsigned int one_time_duration, double start_progress) +{ + DoStep(); +} + +void IdleAnimator::Start(double start_progress) +{ + Start(0, start_progress); +} + +void IdleAnimator::Stop() +{ + if (timeout_) + { + timeout_.reset(); + animation_updated.emit(progress_); + animation_ended.emit(); + animation_stopped.emit(progress_); + one_time_duration_ = 0; + } +} + +bool IdleAnimator::DoStep() +{ + // rely on the compiz event loop to come back to us in a nice throttling + if (IsRunning()) + { + auto idle = std::make_shared<glib::Idle>(glib::Source::Priority::DEFAULT); + sources_.Add(idle, ANIMATION_IDLE); + idle->Run([&]() { + EnsureAnimation(); + return false; + }); + } +} + +} //namespace diff --git a/unity-shared/IdleAnimator.h b/unity-shared/IdleAnimator.h new file mode 100644 index 000000000..fc230f6df --- /dev/null +++ b/unity-shared/IdleAnimator.h @@ -0,0 +1,59 @@ +// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- +/* + * Copyright (C) 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: Marco Trevisan (Treviño) <mail@3v1n0.net> + */ + +#ifndef UNITY_ANIMATOR_H_ +#define UNITY_ANIMATOR_H_ + +#include <cstdint> +#include <UnityCore/GLibSource.h> + +namespace unity +{ +class IdleAnimator : boost::noncopyable +{ +public: + IdleAnimator(unsigned int duration); + ~IdleAnimator(); + + void SetDuration(unsigned int duration); + + unsigned int GetRate() const; + unsigned int GetDuration() const; + double GetProgress() const; + bool IsRunning() const; + + void Start(int source, int destination); + + sigc::signal<void> animation_started; + sigc::signal<void> animation_ended; + + sigc::signal<void, double> animation_updated; + sigc::signal<void, double> animation_stopped; + +private: + bool DoStep(); + unsigned int duration_; + + // Animation + struct timespec times; + glib::SourceManager sources_; +}; + +} +#endif diff --git a/unity-shared/PreviewStyle.cpp b/unity-shared/PreviewStyle.cpp index fc2e97b00..63b4ba1f3 100644 --- a/unity-shared/PreviewStyle.cpp +++ b/unity-shared/PreviewStyle.cpp @@ -82,6 +82,10 @@ std::string Style::version_size_font() const { return "Ubuntu 12"; } +std::string Style::app_license_font() const +{ + return "Ubuntu Light 9.5"; +} std::string Style::app_last_update_font() const { return "Ubuntu Light 10"; @@ -95,6 +99,15 @@ std::string Style::app_description_font() const return "Ubuntu Light 10"; } +std::string Style::info_hint_font() const +{ + return "Ubuntu Light 10"; +} +std::string Style::user_rating_font() const +{ + return "Ubuntu Light 10"; +} + } } } diff --git a/unity-shared/PreviewStyle.h b/unity-shared/PreviewStyle.h index 1626d9040..b0482ee8d 100644 --- a/unity-shared/PreviewStyle.h +++ b/unity-shared/PreviewStyle.h @@ -54,9 +54,12 @@ public: // Application Preview std::string app_name_font() const; std::string version_size_font() const; + std::string app_license_font() const; std::string app_last_update_font() const; std::string app_copywrite_font() const; std::string app_description_font() const; + std::string info_hint_font() const; + std::string user_rating_font() const; //////////////////////////////// protected: diff --git a/unity-shared/RatingsButton.cpp b/unity-shared/RatingsButton.cpp new file mode 100644 index 000000000..112985394 --- /dev/null +++ b/unity-shared/RatingsButton.cpp @@ -0,0 +1,273 @@ +/* + * Copyright 2011 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: Gordon Allott <gord.allott@canonical.com> + * + */ + +#include <math.h> + +#include <Nux/Nux.h> +#include <NuxCore/Logger.h> + +#include "RatingsButton.h" +#include "DashStyle.h" + +namespace +{ +const int num_stars = 5; +} + +namespace unity +{ +RatingsButton::RatingsButton(int star_size, int star_gap, NUX_FILE_LINE_DECL) + : nux::ToggleButton(NUX_FILE_LINE_PARAM) + , editable_(true) + , focused_star_(-1) + , star_size_(star_size) + , star_gap_(star_gap) +{ + SetAcceptKeyNavFocusOnMouseDown(false); + SetAcceptKeyNavFocusOnMouseEnter(true); + + mouse_up.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseUp)); + mouse_move.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseMove)); + mouse_drag.connect(sigc::mem_fun(this, &RatingsButton::RecvMouseDrag)); + + key_nav_focus_change.connect([&](nux::Area* area, bool has_focus, nux::KeyNavDirection direction) + { + if (has_focus && direction != nux::KEY_NAV_NONE) + focused_star_ = 0; + else if (!has_focus) + focused_star_ = -1; + + QueueDraw(); + }); + key_nav_focus_activate.connect([&](nux::Area*) { SetRating(static_cast<float>(focused_star_+1)/num_stars); }); + key_down.connect(sigc::mem_fun(this, &RatingsButton::OnKeyDown)); +} + +RatingsButton::~RatingsButton() +{ +} + +void RatingsButton::SetEditable(bool editable) +{ + editable_ = editable; + if (!editable_) + focused_star_ = -1; + QueueDraw(); +} + +void RatingsButton::SetRating(float rating) +{ + rating_ = rating; + QueueDraw(); +} + +void RatingsButton::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) +{ + int rating = static_cast<int>(rating_ * num_stars); + // 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 + // (Bug #839759) shouldn't. So for now just force rounding. + // int total_half_stars = rating % 2; + // int total_full_stars = rating / 2; + int total_full_stars = rating; + + nux::Geometry const& geo = GetGeometry(); + nux::Geometry geo_star(geo); + geo_star.width = star_size_; + + gPainter.PaintBackground(GfxContext, geo); + // set up our texture mode + nux::TexCoordXForm texxform; + texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER); + texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_SCALE_COORD); + texxform.SetFilter(nux::TEXFILTER_LINEAR, nux::TEXFILTER_LINEAR); + + // clear what is behind us + unsigned int alpha = 0, src = 0, dest = 0; + + GfxContext.GetRenderStates().GetBlend(alpha, src, dest); + GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + + nux::Color col = nux::color::Black; + col.alpha = 0; + GfxContext.QRP_Color(geo.x, + geo.y, + geo.width, + geo.height, + col); + + for (int index = 0; index < num_stars; ++index) + { + dash::Style& style = dash::Style::Instance(); + nux::BaseTexture* texture = style.GetStarSelectedIcon(); + if (index < total_full_stars) + { + if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_NORMAL) + texture = style.GetStarSelectedIcon(); + else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT) + texture = style.GetStarSelectedIcon(); + else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED) + texture = style.GetStarSelectedIcon(); + } + else + { + if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_NORMAL) + texture = style.GetStarDeselectedIcon(); + else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRELIGHT) + texture = style.GetStarDeselectedIcon(); + else if (GetVisualState() == nux::ButtonVisualState::VISUAL_STATE_PRESSED) + texture = style.GetStarDeselectedIcon(); + } + + GfxContext.QRP_1Tex(geo_star.x, + geo_star.y, + geo_star.width, + geo_star.height, + texture->GetDeviceTexture(), + texxform, + nux::Color(1.0f, 1.0f, 1.0f, 1.0f)); + + if (focused_star_ == index) + { + GfxContext.QRP_1Tex(geo_star.x, + geo_star.y, + geo_star.width, + geo_star.height, + style.GetStarHighlightIcon()->GetDeviceTexture(), + texxform, + nux::Color(1.0f, 1.0f, 1.0f, 0.5f)); + } + + geo_star.x += geo_star.width + star_gap_; + + } + + GfxContext.GetRenderStates().SetBlend(alpha, src, dest); + +} + +void RatingsButton::UpdateRatingToMouse(int x) +{ + int width = num_stars*star_size_ + (num_stars-1)*star_gap_; + float new_rating = (static_cast<float>(x) / width); + + // FIXME: change to * 2 once we decide to support also half-stars + new_rating = ceil((num_stars * 1) * new_rating) / (num_stars * 1); + new_rating = (new_rating > 1) ? 1 : ((new_rating < 0) ? 0 : new_rating); + + UpdateRating(new_rating); +} + +void RatingsButton::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags) +{ + if (!editable_) + return; + + UpdateRatingToMouse(x); +} + +void RatingsButton::RecvMouseDrag(int x, int y, int dx, int dy, + unsigned long button_flags, + unsigned long key_flags) +{ + if (!editable_) + return; + + UpdateRatingToMouse(x); +} + +void RatingsButton::RecvMouseMove(int x, int y, int dx, int dy, + unsigned long button_flags, + unsigned long key_flags) +{ + if (!editable_) + return; + + int width = num_stars*star_size_+ (num_stars-1)*star_gap_; + focused_star_ = std::max(0, std::min(static_cast<int>(ceil((static_cast<float>(x) / width) * num_stars) - 1), num_stars - 1)); + + if (!HasKeyFocus()) + nux::GetWindowCompositor().SetKeyFocusArea(this); + + QueueDraw(); +} + + +bool RatingsButton::InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character) +{ + nux::KeyNavDirection direction = nux::KEY_NAV_NONE; + + switch (keysym) + { + case NUX_VK_LEFT: + direction = nux::KeyNavDirection::KEY_NAV_LEFT; + break; + case NUX_VK_RIGHT: + direction = nux::KeyNavDirection::KEY_NAV_RIGHT; + break; + default: + direction = nux::KeyNavDirection::KEY_NAV_NONE; + break; + } + + if (direction == nux::KeyNavDirection::KEY_NAV_NONE) + return false; + else if (direction == nux::KEY_NAV_LEFT && (focused_star_ <= 0)) + return false; + else if (direction == nux::KEY_NAV_RIGHT && (focused_star_ >= num_stars - 1)) + return false; + else + return true; +} + + +void RatingsButton::OnKeyDown(unsigned long event_type, unsigned long event_keysym, + unsigned long event_state, const TCHAR* character, + unsigned short key_repeat_count) +{ + switch (event_keysym) + { + case NUX_VK_LEFT: + --focused_star_; + break; + case NUX_VK_RIGHT: + ++focused_star_; + break; + default: + return; + } + + QueueDraw(); +} + +bool RatingsButton::AcceptKeyNavFocus() +{ + return true; +} + +void RatingsButton::UpdateRating(float rating) +{ + +} + +} // namespace unity diff --git a/unity-shared/RatingsButton.h b/unity-shared/RatingsButton.h new file mode 100644 index 000000000..b162bc0a9 --- /dev/null +++ b/unity-shared/RatingsButton.h @@ -0,0 +1,74 @@ +/* + * Copyright 2011 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: Gordon Allott <gord.allott@canonical.com> + * Nick Dedekind <nick.dedelomd@canonical.com> + * + */ + +#ifndef UNITYSHELL_RATINGSBUTTONWIDGET_H +#define UNITYSHELL_RATINGSBUTTONWIDGET_H + +#include <memory> + +#include <Nux/Nux.h> +#include <Nux/ToggleButton.h> + +namespace unity +{ + +class RatingsButton : public nux::ToggleButton +{ +public: + RatingsButton(int star_size, int star_gap, NUX_FILE_LINE_PROTO); + virtual ~RatingsButton(); + + void SetEditable(bool editable); + virtual void SetRating(float rating); + +protected: + virtual void Draw(nux::GraphicsEngine& GfxContext, bool force_draw); + + // Key-nav + virtual bool AcceptKeyNavFocus(); + virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character); + + virtual void UpdateRating(float rating); + +private: + void OnKeyDown(unsigned long event_type, unsigned long event_keysym, + unsigned long event_state, const TCHAR* character, + unsigned short key_repeat_count); + + void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); + void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); + void UpdateRatingToMouse(int x); + + +protected: + bool editable_; + float rating_; + int focused_star_; + int star_size_; + int star_gap_; +}; + +} // namespace unity + +#endif // UNITYSHELL_RATINGSBUTTONWIDGET_H + |
