summaryrefslogtreecommitdiff
path: root/unity-shared
diff options
authorNick Dedekind <nicholas.dedekind@gmail.com>2012-08-22 11:03:52 +0100
committerNick Dedekind <nicholas.dedekind@gmail.com>2012-08-22 11:03:52 +0100
commit642a1de32bc551c1d76be7ec2769b951b43b04e1 (patch)
tree03f239833bf55c0aa507ad9799dc6051ff1355b5 /unity-shared
parent3f3b2209db2ce4151cd848ced4949b0e9bb1ccb9 (diff)
parent23bb038d712302bbd87400ed39530c31fd5cd016 (diff)
Merge with trunk
(bzr r2588.1.4)
Diffstat (limited to 'unity-shared')
-rw-r--r--unity-shared/CoverArt.cpp56
-rw-r--r--unity-shared/CoverArt.h13
-rwxr-xr-x[-rw-r--r--]unity-shared/DashStyle.cpp0
-rwxr-xr-x[-rw-r--r--]unity-shared/DashStyle.h0
-rw-r--r--unity-shared/IconLoader.cpp264
-rw-r--r--unity-shared/IconRenderer.cpp8
-rw-r--r--unity-shared/Introspectable.cpp17
-rw-r--r--unity-shared/Introspectable.h5
-rw-r--r--unity-shared/IntrospectableWrappers.cpp8
-rw-r--r--unity-shared/IntrospectableWrappers.h4
-rw-r--r--unity-shared/RatingsButton.cpp15
-rw-r--r--unity-shared/RatingsButton.h7
-rw-r--r--unity-shared/ThumbnailGenerator.cpp3
13 files changed, 359 insertions, 41 deletions
diff --git a/unity-shared/CoverArt.cpp b/unity-shared/CoverArt.cpp
index c6949d499..f05666461 100644
--- a/unity-shared/CoverArt.cpp
+++ b/unity-shared/CoverArt.cpp
@@ -72,6 +72,19 @@ CoverArt::~CoverArt()
notifier_->Cancel();
}
+std::string CoverArt::GetName() const
+{
+ return "CoverArt";
+}
+
+void CoverArt::AddProperties(GVariantBuilder* builder)
+{
+ variant::BuilderWrapper(builder)
+ .add(GetAbsoluteGeometry())
+ .add("image-hint", image_hint_)
+ .add("waiting", waiting_);
+}
+
void CoverArt::SetImage(std::string const& image_hint)
{
spinner_timeout_.reset();
@@ -126,11 +139,18 @@ void CoverArt::SetImage(std::string const& image_hint)
void CoverArt::GenerateImage(std::string const& uri)
{
- StartWaiting();
notifier_ = ThumbnailGenerator::Instance().GetThumbnail(uri, 512);
-
- notifier_->ready.connect(sigc::mem_fun(this, &CoverArt::OnThumbnailGenerated));
- notifier_->error.connect(sigc::mem_fun(this, &CoverArt::OnThumbnailError));
+ if (notifier_)
+ {
+ StartWaiting();
+ notifier_->ready.connect(sigc::mem_fun(this, &CoverArt::OnThumbnailGenerated));
+ notifier_->error.connect(sigc::mem_fun(this, &CoverArt::OnThumbnailError));
+ }
+ else
+ {
+ StopWaiting();
+ SetNoImageAvailable();
+ }
}
void CoverArt::StartWaiting()
@@ -145,9 +165,9 @@ void CoverArt::StartWaiting()
spinner_timeout_.reset(new glib::TimeoutSeconds(5, [&]
{
- texture_screenshot_.Release();
- waiting_ = false;
+ StopWaiting();
+ texture_screenshot_.Release();
SetNoImageAvailable();
return false;
}));
@@ -155,6 +175,13 @@ void CoverArt::StartWaiting()
QueueDraw();
}
+void CoverArt::StopWaiting()
+{
+ spinner_timeout_.reset();
+ frame_timeout_.reset();
+ waiting_ = false;
+}
+
void CoverArt::SetNoImageAvailable()
{
if (GetLayout())
@@ -170,9 +197,7 @@ void CoverArt::SetNoImageAvailable()
void CoverArt::IconLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf)
{
// Finished waiting
- spinner_timeout_.reset();
- frame_timeout_.reset();
- waiting_ = false;
+ StopWaiting();
stretch_image_ = false;
if (!pixbuf)
@@ -251,9 +276,7 @@ void CoverArt::IconLoaded(std::string const& texid, unsigned size, glib::Object<
void CoverArt::TextureLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf)
{
// Finished waiting
- spinner_timeout_.reset();
- frame_timeout_.reset();
- waiting_ = false;
+ StopWaiting();
stretch_image_ = true;
if (!pixbuf)
@@ -384,11 +407,6 @@ void CoverArt::DrawContent(nux::GraphicsEngine& gfx_engine, bool force_draw)
gfx_engine.PopClippingRectangle();
}
-std::string CoverArt::GetName() const
-{
- return "CoverArt";
-}
-
void CoverArt::SetupViews()
{
nux::VLayout* layout = new nux::VLayout();
@@ -425,9 +443,7 @@ void CoverArt::OnThumbnailGenerated(std::string const& uri)
void CoverArt::OnThumbnailError(std::string const& error_hint)
{
LOG_WARNING(logger) << "Failed to generate thumbnail: " << error_hint;
- spinner_timeout_.reset();
- frame_timeout_.reset();
- waiting_ = false;
+ StopWaiting();
texture_screenshot_.Release();
if (GetLayout())
diff --git a/unity-shared/CoverArt.h b/unity-shared/CoverArt.h
index 52c2a7f86..12215fe0b 100644
--- a/unity-shared/CoverArt.h
+++ b/unity-shared/CoverArt.h
@@ -30,6 +30,7 @@
#include <UnityCore/GLibSource.h>
#include <NuxCore/ObjectPtr.h>
#include "unity-shared/StaticCairoText.h"
+#include "unity-shared/Introspectable.h"
#include "ThumbnailGenerator.h"
namespace unity
@@ -39,7 +40,7 @@ namespace dash
namespace previews
{
-class CoverArt : public nux::View
+class CoverArt : public nux::View, public unity::debug::Introspectable
{
public:
typedef nux::ObjectPtr<CoverArt> Ptr;
@@ -52,9 +53,8 @@ public:
void SetImage(std::string const& image_hint);
// Use for generating an image for a uri which is not necessarily an image.
void GenerateImage(std::string const& uri);
-
- // From debug::Introspectable
- std::string GetName() const;
+
+ void SetNoImageAvailable();
void SetFont(std::string const& font);
@@ -74,7 +74,10 @@ protected:
void TextureLoaded(std::string const& texid, unsigned size, glib::Object<GdkPixbuf> const& pixbuf);
void StartWaiting();
- void SetNoImageAvailable();
+ void StopWaiting();
+
+ virtual std::string GetName() const;
+ virtual void AddProperties(GVariantBuilder* builder);
private:
nux::ObjectPtr<nux::BaseTexture> texture_screenshot_;
diff --git a/unity-shared/DashStyle.cpp b/unity-shared/DashStyle.cpp
index 8ac12c7d7..8ac12c7d7 100644..100755
--- a/unity-shared/DashStyle.cpp
+++ b/unity-shared/DashStyle.cpp
diff --git a/unity-shared/DashStyle.h b/unity-shared/DashStyle.h
index 440914d7d..440914d7d 100644..100755
--- a/unity-shared/DashStyle.h
+++ b/unity-shared/DashStyle.h
diff --git a/unity-shared/IconLoader.cpp b/unity-shared/IconLoader.cpp
index 78c9e9ea9..7d236cb19 100644
--- a/unity-shared/IconLoader.cpp
+++ b/unity-shared/IconLoader.cpp
@@ -22,8 +22,13 @@
#include <queue>
#include <sstream>
#include <boost/algorithm/string.hpp>
+#include <unity-protocol.h>
+#include <pango/pango.h>
+#include <pango/pangocairo.h>
+#include <Nux/Nux.h>
#include <NuxCore/Logger.h>
+#include <NuxGraphics/CairoGraphics.h>
#include <UnityCore/GLibSource.h>
#include <UnityCore/GLibSignal.h>
@@ -43,6 +48,8 @@ public:
// The Handle typedef is used to explicitly indicate which integers are
// infact our opaque handles.
typedef int Handle;
+ static const int FONT_SIZE = 10;
+ static const int MIN_FONT_SIZE = 6;
Impl();
@@ -64,6 +71,8 @@ public:
void DisconnectHandle(Handle handle);
+ static void CalculateTextHeight(int* width, int* height);
+
private:
enum IconLoaderRequestType
@@ -85,9 +94,12 @@ private:
Handle handle;
Impl* impl;
GtkIconInfo* icon_info;
+ bool no_cache;
+ int helper_handle;
glib::Object<GdkPixbuf> result;
glib::Error error;
std::list<IconLoaderTask::Ptr> shadow_tasks;
+ unsigned idle_id;
IconLoaderTask(IconLoaderRequestType type_,
std::string const& data_,
@@ -98,13 +110,17 @@ private:
Impl* self_)
: type(type_), data(data_), size(size_), key(key_)
, slot(slot_), handle(handle_), impl(self_)
- , icon_info(nullptr)
+ , icon_info(nullptr), no_cache(false), helper_handle(0), idle_id(0)
{}
~IconLoaderTask()
{
if (icon_info)
::gtk_icon_info_free(icon_info);
+ if (helper_handle != 0)
+ impl->DisconnectHandle(helper_handle);
+ if (idle_id != 0)
+ g_source_remove(idle_id);
}
void InvokeSlot()
@@ -180,7 +196,21 @@ private:
glib::Error error;
glib::Object<GIcon> icon(::g_icon_new_for_string(data.c_str(), &error));
- if (G_IS_FILE_ICON(icon.RawPtr()))
+ if (icon.IsType(UNITY_PROTOCOL_TYPE_ANNOTATED_ICON))
+ {
+ UnityProtocolAnnotatedIcon *anno;
+ anno = UNITY_PROTOCOL_ANNOTATED_ICON(icon.RawPtr());
+ GIcon* base_icon = unity_protocol_annotated_icon_get_icon(anno);
+ glib::String gicon_string(g_icon_to_string(base_icon));
+
+ no_cache = true;
+ auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::BaseIconLoaded), glib::object_cast<UnityProtocolAnnotatedIcon>(icon));
+ helper_handle = impl->LoadFromGIconString(gicon_string.Str(),
+ size, helper_slot);
+
+ return false;
+ }
+ else if (icon.IsType(G_TYPE_FILE_ICON))
{
// [trasfer none]
GFile* file = ::g_file_icon_get_file(G_FILE_ICON(icon.RawPtr()));
@@ -191,7 +221,7 @@ private:
return ProcessURITask();
}
- else if (G_IS_ICON(icon.RawPtr()))
+ else if (icon.IsType(G_TYPE_ICON))
{
GtkIconInfo* info = ::gtk_icon_theme_lookup_by_gicon(impl->theme_, icon, size,
static_cast<GtkIconLookupFlags>(0));
@@ -241,6 +271,177 @@ private:
return false;
}
+ void CategoryIconLoaded(std::string const& base_icon_string, unsigned size,
+ glib::Object<GdkPixbuf> const& category_pixbuf,
+ glib::Object<UnityProtocolAnnotatedIcon> const& anno_icon)
+ {
+ helper_handle = 0;
+ if (category_pixbuf)
+ {
+ // assuming the category pixbuf is smaller than result
+ gdk_pixbuf_composite(category_pixbuf, result, // src, dest
+ 0, 0, // dest_x, dest_y
+ gdk_pixbuf_get_width(category_pixbuf), // dest_w
+ gdk_pixbuf_get_height(category_pixbuf), // dest_h
+ 0.0, 0.0, // offset_x, offset_y
+ 1.0, 1.0, // scale_x, scale_y
+ GDK_INTERP_NEAREST, // interpolation
+ 255); // src_alpha
+ }
+
+ const gchar* detail_text = unity_protocol_annotated_icon_get_ribbon(anno_icon);
+ if (detail_text)
+ {
+ int icon_w = gdk_pixbuf_get_width(result);
+ int icon_h = gdk_pixbuf_get_height(result);
+
+ int max_font_height;
+ CalculateTextHeight(nullptr, &max_font_height);
+
+ max_font_height = max_font_height * 9 / 8; // let's have some padding on the stripe
+ int pixbuf_size = static_cast<int>(
+ sqrt(max_font_height*max_font_height*8));
+ if (pixbuf_size > icon_w) pixbuf_size = icon_w;
+
+ nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32,
+ pixbuf_size, pixbuf_size);
+ std::shared_ptr<cairo_t> cr(cairo_graphics.GetContext(), cairo_destroy);
+
+ glib::Object<PangoLayout> layout;
+ PangoContext* pango_context = NULL;
+ GdkScreen* screen = gdk_screen_get_default(); // not ref'ed
+ glib::String font;
+ int dpi = -1;
+
+ g_object_get(gtk_settings_get_default(), "gtk-font-name", &font, NULL);
+ g_object_get(gtk_settings_get_default(), "gtk-xft-dpi", &dpi, NULL);
+ cairo_set_font_options(cr.get(), gdk_screen_get_font_options(screen));
+ layout = pango_cairo_create_layout(cr.get());
+ std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font), pango_font_description_free);
+ pango_font_description_set_weight(desc.get(), PANGO_WEIGHT_BOLD);
+ int font_size = FONT_SIZE;
+ pango_font_description_set_size (desc.get(), font_size * PANGO_SCALE);
+
+ pango_layout_set_font_description(layout, desc.get());
+ pango_layout_set_alignment(layout, PANGO_ALIGN_CENTER);
+
+ double size_dbl = static_cast<double>(pixbuf_size);
+ // we'll allow tiny bit of overflow since the text is rotated and there
+ // is some space left... FIXME: 10/9? / 11/10?
+ double max_text_width = sqrt(size_dbl*size_dbl / 2) * 9/8;
+
+ pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
+ pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
+
+ glib::String escaped_text(g_markup_escape_text(detail_text, -1));
+ pango_layout_set_markup(layout, escaped_text, -1);
+
+ pango_context = pango_layout_get_context(layout); // is not ref'ed
+ // FIXME: for reasons unknown, it looks better without this
+ //pango_cairo_context_set_font_options(pango_context,
+ // gdk_screen_get_font_options(screen));
+ pango_cairo_context_set_resolution(pango_context,
+ dpi == -1 ? 96.0f : dpi/(float) PANGO_SCALE);
+ pango_layout_context_changed(layout);
+
+ // find proper font size (can we do this before the rotation?)
+ int text_width, text_height;
+ pango_layout_get_pixel_size(layout, &text_width, nullptr);
+ while (text_width > max_text_width && font_size > MIN_FONT_SIZE)
+ {
+ font_size--;
+ pango_font_description_set_size (desc.get(), font_size * PANGO_SCALE);
+ pango_layout_set_font_description(layout, desc.get());
+ pango_layout_get_pixel_size(layout, &text_width, nullptr);
+ }
+ pango_layout_set_width(layout, static_cast<int>(max_text_width * PANGO_SCALE));
+
+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_CLEAR);
+ cairo_paint(cr.get());
+
+ cairo_set_operator(cr.get(), CAIRO_OPERATOR_OVER);
+
+ // draw the trapezoid
+ cairo_move_to(cr.get(), 0.0, size_dbl);
+ cairo_line_to(cr.get(), size_dbl, 0.0);
+ cairo_line_to(cr.get(), size_dbl, size_dbl / 2.0);
+ cairo_line_to(cr.get(), size_dbl / 2.0, size_dbl);
+ cairo_close_path(cr.get());
+
+ // this should be #dd4814
+ cairo_set_source_rgba(cr.get(), 0.86666f, 0.28235f, 0.07843f, 1.0f);
+ cairo_fill(cr.get());
+
+ // draw the text (rotated!)
+ cairo_set_source_rgba(cr.get(), 1.0f, 1.0f, 1.0f, 1.0f);
+ cairo_move_to(cr.get(), size_dbl * 0.25, size_dbl);
+ cairo_rotate(cr.get(), -G_PI_4); // rotate by -45 degrees
+
+ pango_cairo_update_layout(cr.get(), layout);
+ pango_layout_get_pixel_size(layout, nullptr, &text_height);
+ // current point is now in the middle of the stripe, need to translate
+ // it, so that the text is centered
+ cairo_rel_move_to(cr.get(), 0.0, text_height / -2.0);
+ double diagonal = sqrt(size_dbl*size_dbl*2);
+ // x coordinate also needs to be shifted
+ cairo_rel_move_to(cr.get(), (diagonal - max_text_width) / 4, 0.0);
+ pango_cairo_show_layout(cr.get(), layout);
+
+ // FIXME: going from image_surface to pixbuf, and then to texture :(
+ glib::Object<GdkPixbuf> detail_pb(
+ gdk_pixbuf_get_from_surface(cairo_graphics.GetSurface(),
+ 0, 0,
+ cairo_graphics.GetWidth(),
+ cairo_graphics.GetHeight()));
+
+ gdk_pixbuf_composite(detail_pb, result, // src, dest
+ icon_w - pixbuf_size, // dest_x
+ icon_h - pixbuf_size, // dest_y
+ pixbuf_size, // dest_w
+ pixbuf_size, // dest_h
+ icon_w - pixbuf_size, // offset_x
+ icon_h - pixbuf_size, // offset_y
+ 1.0, 1.0, // scale_x, scale_y
+ GDK_INTERP_NEAREST, // interpolation
+ 255); // src_alpha
+ }
+
+ idle_id = g_idle_add(LoadIconComplete, this);
+ }
+
+ void BaseIconLoaded(std::string const& base_icon_string, unsigned size,
+ glib::Object<GdkPixbuf> const& base_pixbuf,
+ glib::Object<UnityProtocolAnnotatedIcon> const& anno_icon)
+ {
+ helper_handle = 0;
+ if (base_pixbuf)
+ {
+ result = gdk_pixbuf_copy(base_pixbuf);
+ // FIXME: can we composite the pixbuf in helper thread?
+ UnityProtocolCategoryType category = unity_protocol_annotated_icon_get_category(anno_icon);
+ auto helper_slot = sigc::bind(sigc::mem_fun(this, &IconLoaderTask::CategoryIconLoaded), anno_icon);
+ unsigned cat_size = size / 4;
+ // FIXME: we still don't have the category assets
+ switch (category)
+ {
+ case UNITY_PROTOCOL_CATEGORY_TYPE_MUSIC:
+ helper_handle =
+ impl->LoadFromIconName("emblem-favorite", cat_size, helper_slot);
+ break;
+ default:
+ // rest of the processing is the CategoryIconLoaded, lets invoke it
+ glib::Object<GdkPixbuf> null_pixbuf;
+ helper_slot("", cat_size, null_pixbuf);
+ break;
+ }
+ }
+ else
+ {
+ result = nullptr;
+ idle_id = g_idle_add(LoadIconComplete, this);
+ }
+ }
+
void PushSchedulerJob()
{
::g_io_scheduler_push_job (LoaderJobFunc, this, nullptr, G_PRIORITY_HIGH_IDLE, nullptr);
@@ -298,9 +499,9 @@ private:
auto task = static_cast<IconLoaderTask*>(data);
auto impl = task->impl;
- if (GDK_IS_PIXBUF(task->result.RawPtr()))
+ if (task->result.IsType(GDK_TYPE_PIXBUF))
{
- impl->cache_[task->key] = task->result;
+ if (!task->no_cache) impl->cache_[task->key] = task->result;
}
else
{
@@ -350,6 +551,13 @@ private:
private:
std::map<std::string, glib::Object<GdkPixbuf>> cache_;
+ /* FIXME: the reference counting of IconLoaderTasks with shared pointers
+ * is currently somewhat broken, and the queued_tasks_ member is what keeps
+ * it from crashing randomly.
+ * The IconLoader instance is assuming that it is the only owner of the loader
+ * tasks, but when they are being completed in a worker thread, the thread
+ * should own them as well (yet it doesn't), this could cause trouble
+ * in the future... You've been warned! */
std::map<std::string, IconLoaderTask::Ptr> queued_tasks_;
std::queue<IconLoaderTask::Ptr> tasks_;
std::map<Handle, IconLoaderTask::Ptr> task_map_;
@@ -379,6 +587,16 @@ IconLoader::Impl::Impl()
* apply immediately. */
cache_.clear();
});
+
+ // make sure the AnnotatedIcon type is registered, so we can deserialize it
+#if GLIB_CHECK_VERSION(2, 34, 0)
+ g_type_ensure(unity_protocol_annotated_icon_get_type());
+#else
+ // we need to fool the compiler cause get_type is marked as G_GNUC_CONST,
+ // which isn't exactly true
+ volatile GType proto_icon = unity_protocol_annotated_icon_get_type();
+ g_type_name(proto_icon);
+#endif
}
int IconLoader::Impl::LoadFromIconName(std::string const& icon_name,
@@ -440,6 +658,42 @@ void IconLoader::Impl::DisconnectHandle(Handle handle)
}
}
+void IconLoader::Impl::CalculateTextHeight(int* width, int* height)
+{
+ // FIXME: what about CJK?
+ const char* const SAMPLE_MAX_TEXT = "Chromium Web Browser";
+ GtkSettings* settings = gtk_settings_get_default();
+
+ nux::CairoGraphics util_cg(CAIRO_FORMAT_ARGB32, 1, 1);
+ cairo_t* cr = util_cg.GetInternalContext();
+
+ glib::String font;
+ int dpi = 0;
+ g_object_get(settings,
+ "gtk-font-name", &font,
+ "gtk-xft-dpi", &dpi,
+ NULL);
+ std::shared_ptr<PangoFontDescription> desc(pango_font_description_from_string(font), pango_font_description_free);
+ pango_font_description_set_weight(desc.get(), PANGO_WEIGHT_BOLD);
+ pango_font_description_set_size(desc.get(), FONT_SIZE * PANGO_SCALE);
+
+ glib::Object<PangoLayout> layout(pango_cairo_create_layout(cr));
+ pango_layout_set_font_description(layout, desc.get());
+ pango_layout_set_text(layout, SAMPLE_MAX_TEXT, -1);
+
+ PangoContext* cxt = pango_layout_get_context(layout);
+ GdkScreen* screen = gdk_screen_get_default();
+ pango_cairo_context_set_font_options(cxt, gdk_screen_get_font_options(screen));
+ pango_cairo_context_set_resolution(cxt, dpi / (double) PANGO_SCALE);
+ pango_layout_context_changed(layout);
+
+ PangoRectangle log_rect;
+ pango_layout_get_extents(layout, NULL, &log_rect);
+
+ if (width) *width = log_rect.width / PANGO_SCALE;
+ if (height) *height = log_rect.height / PANGO_SCALE;
+}
+
//
// Private Methods
//
diff --git a/unity-shared/IconRenderer.cpp b/unity-shared/IconRenderer.cpp
index 2c37cc89c..aa3a9ccd5 100644
--- a/unity-shared/IconRenderer.cpp
+++ b/unity-shared/IconRenderer.cpp
@@ -745,7 +745,7 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
// Perspective correct
v0.x, v0.y, 0.0f, 1.0f, s0 / v0.w, t0 / v0.w, 0.0f, 1.0f / v0.w,
v1.x, v1.y, 0.0f, 1.0f, s1 / v1.w, t1 / v1.w, 0.0f, 1.0f / v1.w,
-#ifdef USE_MODERN_COMPIZ_GL
+#ifdef USE_GLES
v3.x, v3.y, 0.0f, 1.0f, s3 / v3.w, t3 / v3.w, 0.0f, 1.0f / v3.w,
v2.x, v2.y, 0.0f, 1.0f, s2 / v2.w, t2 / v2.w, 0.0f, 1.0f / v2.w,
#else
@@ -783,7 +783,7 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
local::shader_program_uv_persp_correction->SetUniformLocMatrix4fv((GLint)VPMatrixLocation, 1, false, (GLfloat*) & (_stored_projection_matrix.m));
}
}
-#ifndef USE_MODERN_COMPIZ_GL
+#ifndef USE_GLES
else
{
local::asm_shader->Begin();
@@ -821,13 +821,13 @@ void IconRenderer::RenderElement(nux::GraphicsEngine& GfxContext,
CHECKGL(glUniform4fARB(DesatFactor, arg.saturation, arg.saturation, arg.saturation, arg.saturation));
nux::GetWindowThread()->GetGraphicsEngine().SetTexture(GL_TEXTURE0, icon);
-#ifdef USE_MODERN_COMPIZ_GL
+#ifdef USE_GLES
CHECKGL(glDrawArrays(GL_TRIANGLE_STRIP, 0, 4));
#else
CHECKGL(glDrawArrays(GL_QUADS, 0, 4));
#endif
}
-#ifndef USE_MODERN_COMPIZ_GL
+#ifndef USE_GLES
else
{
CHECKGL(glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, bg_color.red, bg_color.green, bg_color.blue, bg_color.alpha));
diff --git a/unity-shared/Introspectable.cpp b/unity-shared/Introspectable.cpp
index 4ecd0fc18..bfd024c1e 100644
--- a/unity-shared/Introspectable.cpp
+++ b/unity-shared/Introspectable.cpp
@@ -82,10 +82,13 @@ Introspectable::AddChild(Introspectable* child)
}
void
-Introspectable::RemoveChild(Introspectable* child)
+Introspectable::RemoveChild(Introspectable* child, child_destructor destr)
{
_children.remove(child);
child->_parents.remove(this);
+
+ if (destr)
+ (*destr)(child);
}
std::string
@@ -99,6 +102,18 @@ guint64 Introspectable::GetIntrospectionId() const
return _id;
}
+void
+Introspectable::RemoveAllChildren(child_destructor destr)
+{
+ for (auto child : _children)
+ {
+ child->_parents.remove(this);
+ if (destr)
+ (*destr)(child);
+ }
+ _children.clear();
+}
+
}
}
diff --git a/unity-shared/Introspectable.h b/unity-shared/Introspectable.h
index 7814ca281..aab473cd5 100644
--- a/unity-shared/Introspectable.h
+++ b/unity-shared/Introspectable.h
@@ -32,13 +32,14 @@ class Introspectable
{
public:
typedef std::list<Introspectable*> IntrospectableList;
+ typedef void(*child_destructor)(Introspectable*);
Introspectable();
virtual ~Introspectable();
GVariant* Introspect();
virtual std::string GetName() const = 0;
void AddChild(Introspectable* child);
- void RemoveChild(Introspectable* child);
+ void RemoveChild(Introspectable* child, child_destructor = NULL);
virtual void AddProperties(GVariantBuilder* builder) = 0;
virtual IntrospectableList GetIntrospectableChildren();
guint64 GetIntrospectionId() const;
@@ -48,6 +49,8 @@ protected:
/// is if you have a property that simply *must* be called 'Children'.
virtual std::string GetChildsName() const;
+ void RemoveAllChildren(child_destructor = NULL);
+
/*
* AddProperties should be implemented as such ...
* void ClassFoo::AddProperties (GVariantBuilder *builder)
diff --git a/unity-shared/IntrospectableWrappers.cpp b/unity-shared/IntrospectableWrappers.cpp
index dbf5b0de0..910628df4 100644
--- a/unity-shared/IntrospectableWrappers.cpp
+++ b/unity-shared/IntrospectableWrappers.cpp
@@ -25,11 +25,12 @@ namespace unity
{
namespace debug
{
- ResultWrapper::ResultWrapper(const dash::Result& result)
+ ResultWrapper::ResultWrapper(dash::Result const& result, nux::Geometry const& geo)
: uri_(result.uri),
name_(result.name),
icon_hint_(result.icon_hint),
- mime_type_(result.mimetype)
+ mime_type_(result.mimetype),
+ geo_(geo)
{
}
@@ -44,7 +45,8 @@ namespace debug
.add("uri", uri_)
.add("name", name_)
.add("icon_hint", icon_hint_)
- .add("mimetype", mime_type_);
+ .add("mimetype", mime_type_)
+ .add(geo_);
}
}
}
diff --git a/unity-shared/IntrospectableWrappers.h b/unity-shared/IntrospectableWrappers.h
index a999e52bb..5fae901ef 100644
--- a/unity-shared/IntrospectableWrappers.h
+++ b/unity-shared/IntrospectableWrappers.h
@@ -21,6 +21,7 @@
#define _INTROSPECTABLE_WRAPPERS_H
#include <UnityCore/Result.h>
+#include <Nux/Nux.h>
#include "Introspectable.h"
@@ -35,7 +36,7 @@ namespace debug
class ResultWrapper: public Introspectable
{
public:
- ResultWrapper(const dash::Result& result);
+ ResultWrapper(const dash::Result& result, nux::Geometry const& geo = nux::Geometry());
std::string GetName() const;
void AddProperties(GVariantBuilder* builder);
private:
@@ -43,6 +44,7 @@ private:
std::string name_;
std::string icon_hint_;
std::string mime_type_;
+ nux::Geometry geo_;
};
}
diff --git a/unity-shared/RatingsButton.cpp b/unity-shared/RatingsButton.cpp
index b43ad9ba9..a4f44c639 100644
--- a/unity-shared/RatingsButton.cpp
+++ b/unity-shared/RatingsButton.cpp
@@ -23,6 +23,7 @@
#include <Nux/Nux.h>
#include <NuxCore/Logger.h>
+#include <UnityCore/Variant.h>
#include "RatingsButton.h"
#include "DashStyle.h"
@@ -274,4 +275,18 @@ bool RatingsButton::AcceptKeyNavFocus()
return editable_;
}
+std::string RatingsButton::GetName() const
+{
+ return "RatingsButton";
+}
+
+void RatingsButton::AddProperties(GVariantBuilder* builder)
+{
+ variant::BuilderWrapper(builder)
+ .add(GetAbsoluteGeometry())
+ .add("rating", rating_)
+ .add("focused-star", focused_star_)
+ .add("editable", editable_);
+}
+
} // namespace unity
diff --git a/unity-shared/RatingsButton.h b/unity-shared/RatingsButton.h
index 03fbb0f8d..7a8b57c62 100644
--- a/unity-shared/RatingsButton.h
+++ b/unity-shared/RatingsButton.h
@@ -26,11 +26,12 @@
#include <Nux/Nux.h>
#include <Nux/ToggleButton.h>
+#include "unity-shared/Introspectable.h"
namespace unity
{
-class RatingsButton : public nux::ToggleButton
+class RatingsButton : public unity::debug::Introspectable, public nux::ToggleButton
{
public:
RatingsButton(int star_size, int star_gap, NUX_FILE_LINE_PROTO);
@@ -47,6 +48,10 @@ protected:
virtual bool AcceptKeyNavFocus();
virtual bool InspectKeyEvent(unsigned int eventType, unsigned int keysym, const char* character);
+ // Introspectable methods
+ std::string GetName() const;
+ void AddProperties(GVariantBuilder* builder);
+
private:
void OnKeyDown(unsigned long event_type, unsigned long event_keysym,
unsigned long event_state, const TCHAR* character,
diff --git a/unity-shared/ThumbnailGenerator.cpp b/unity-shared/ThumbnailGenerator.cpp
index c65f99ea0..a214afa07 100644
--- a/unity-shared/ThumbnailGenerator.cpp
+++ b/unity-shared/ThumbnailGenerator.cpp
@@ -457,6 +457,9 @@ ThumbnailGenerator& ThumbnailGenerator::Instance()
ThumbnailNotifier::Ptr ThumbnailGenerator::GetThumbnail(std::string const& uri, int size)
{
+ if (uri.empty())
+ return ThumbnailNotifier::Ptr();
+
return pimpl->GetThumbnail(uri, size);
}