Back to index

unity  6.0.0
IconTexture.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright (C) 2010 Canonical Ltd
00004  *
00005  * This program is free software: you can redistribute it and/or modify
00006  * it under the terms of the GNU General Public License version 3 as
00007  * published by the Free Software Foundation.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  *
00017  * Authored by: Gordon Allott <gord.allott@canonical.com>
00018  */
00019 
00020 #include "config.h"
00021 
00022 #include <glib.h>
00023 #include <gtk/gtk.h>
00024 #include <pango/pangocairo.h>
00025 
00026 #include <Nux/Nux.h>
00027 #include <NuxCore/Logger.h>
00028 #include <NuxGraphics/GLThread.h>
00029 #include <UnityCore/GLibWrapper.h>
00030 #include <UnityCore/Variant.h>
00031 
00032 #include "IconLoader.h"
00033 #include "IconTexture.h"
00034 #include "TextureCache.h"
00035 
00036 namespace unity
00037 {
00038 namespace
00039 {
00040 const char* const DEFAULT_ICON = "text-x-preview";
00041 nux::logging::Logger logger("unity.icontexture");
00042 }
00043 
00044 using namespace unity;
00045 
00046 IconTexture::IconTexture(nux::BaseTexture* texture, guint width, guint height)
00047   : TextureArea(NUX_TRACKER_LOCATION),
00048     _accept_key_nav_focus(false),
00049     _size(height),
00050     _texture_cached(texture),
00051     _texture_size(width, height),
00052     _loading(false),
00053     _opacity(1.0f),
00054     _handle(0)
00055 {
00056   SetMinMaxSize(width, height);
00057 }
00058 
00059 IconTexture::IconTexture(std::string const& icon_name, unsigned int size, bool defer_icon_loading)
00060   : TextureArea(NUX_TRACKER_LOCATION),
00061     _accept_key_nav_focus(false),
00062     _icon_name(!icon_name.empty() ? icon_name : DEFAULT_ICON),
00063     _size(size),
00064     _loading(false),
00065     _opacity(1.0f),
00066     _handle(0)
00067 {
00068   if (!icon_name.empty () && !defer_icon_loading)
00069     LoadIcon();
00070 }
00071 
00072 IconTexture::~IconTexture()
00073 {
00074   IconLoader::GetDefault().DisconnectHandle(_handle);
00075 }
00076 
00077 void IconTexture::SetByIconName(std::string const& icon_name, unsigned int size)
00078 {
00079   if (_icon_name == icon_name && _size == size)
00080     return;
00081 
00082   _icon_name = icon_name;
00083   _size = size;
00084 
00085   if (_size == 0)
00086   {
00087     _texture_cached = nullptr;
00088     return;
00089   }
00090 
00091   LoadIcon();
00092 }
00093 
00094 
00095 void IconTexture::SetByFilePath(std::string const& file_path, unsigned int size)
00096 {
00097   SetByIconName(file_path, size);
00098 }
00099 
00100 void IconTexture::LoadIcon()
00101 {
00102   LOG_DEBUG(logger) << "LoadIcon called (" << _icon_name << ") - loading: " << _loading;
00103   static const char* const DEFAULT_GICON = ". GThemedIcon text-x-preview";
00104 
00105   if (_loading || _size == 0 || _handle)
00106     return;
00107 
00108   _loading = true;
00109 
00110   glib::Object<GIcon> icon(g_icon_new_for_string(_icon_name.empty() ?  DEFAULT_GICON : _icon_name.c_str(), NULL));
00111 
00112   if (G_IS_ICON(icon.RawPtr()))
00113   {
00114     _handle = IconLoader::GetDefault().LoadFromGIconString(_icon_name.empty() ? DEFAULT_GICON : _icon_name.c_str(),
00115                                                            _size,
00116                                                            sigc::mem_fun(this, &IconTexture::IconLoaded));
00117   }
00118   else if (_icon_name.find("http://") == 0)
00119   {
00120     _handle = IconLoader::GetDefault().LoadFromURI(_icon_name,
00121                                                    _size, sigc::mem_fun(this, &IconTexture::IconLoaded));
00122   }
00123   else
00124   {
00125     _handle = IconLoader::GetDefault().LoadFromIconName(_icon_name,
00126                                                         _size,
00127                                                         sigc::mem_fun(this, &IconTexture::IconLoaded));
00128   }
00129 }
00130 
00131 nux::BaseTexture* IconTexture::CreateTextureCallback(std::string const& texid, int width, int height)
00132 {
00133   return nux::CreateTexture2DFromPixbuf(_pixbuf_cached, true);
00134 }
00135 
00136 void IconTexture::Refresh(glib::Object<GdkPixbuf> const& pixbuf)
00137 {
00138   TextureCache& cache = TextureCache::GetDefault();
00139   _pixbuf_cached = pixbuf;
00140 
00141   // Cache the pixbuf dimensions so we scale correctly
00142   _texture_size.width = gdk_pixbuf_get_width(pixbuf);
00143   _texture_size.height = gdk_pixbuf_get_height(pixbuf);
00144 
00145   // Try and get a texture from the texture cache
00146   std::string id("IconTexture.");
00147   id += _icon_name.empty() ? DEFAULT_ICON : _icon_name;
00148   _texture_cached = cache.FindTexture(id, _texture_size.width, _texture_size.height,
00149                                       sigc::mem_fun(this, &IconTexture::CreateTextureCallback));
00150   QueueDraw();
00151   _loading = false;
00152 }
00153 
00154 void IconTexture::IconLoaded(std::string const& icon_name, unsigned size,
00155                              glib::Object<GdkPixbuf> const& pixbuf)
00156 {
00157   _handle = 0;
00158 
00159   if (GDK_IS_PIXBUF(pixbuf.RawPtr()))
00160   {
00161     Refresh(pixbuf);
00162   }
00163   else
00164   {
00165     _pixbuf_cached = nullptr;
00166     _loading = false;
00167 
00168     // Protects against a missing default icon, we only request it if icon_name
00169     // doesn't match.
00170     if (icon_name != DEFAULT_ICON)
00171       SetByIconName(DEFAULT_ICON, _size);
00172   }
00173 
00174   texture_updated.emit(_texture_cached.GetPointer());
00175   QueueDraw();
00176 }
00177 
00178 void IconTexture::Draw(nux::GraphicsEngine& GfxContext, bool force_draw)
00179 {
00180   nux::Geometry geo = GetGeometry();
00181 
00182   GfxContext.PushClippingRectangle(geo);
00183 
00184   nux::GetPainter().PaintBackground(GfxContext, geo);
00185 
00186   if (_texture_cached)
00187   {
00188     nux::Color col(1.0f * _opacity, 1.0f * _opacity, 1.0f * _opacity, _opacity);
00189     nux::TexCoordXForm texxform;
00190     texxform.SetTexCoordType(nux::TexCoordXForm::OFFSET_COORD);
00191     texxform.SetWrap(nux::TEXWRAP_CLAMP_TO_BORDER, nux::TEXWRAP_CLAMP_TO_BORDER);
00192 
00193     GfxContext.QRP_1Tex(geo.x + ((geo.width - _texture_size.width) / 2),
00194                         geo.y + ((geo.height - _texture_size.height) / 2),
00195                         _texture_size.width,
00196                         _texture_size.height,
00197                         _texture_cached->GetDeviceTexture(),
00198                         texxform,
00199                         col);
00200   }
00201 
00202   GfxContext.PopClippingRectangle();
00203 }
00204 
00205 void IconTexture::GetTextureSize(int* width, int* height)
00206 {
00207   if (width)
00208     *width = _texture_size.width;
00209   if (height)
00210     *height = _texture_size.height;
00211 }
00212 
00213 void IconTexture::SetOpacity(float opacity)
00214 {
00215   _opacity = opacity;
00216 
00217   QueueDraw();
00218 }
00219 
00220 void IconTexture::SetTexture(nux::BaseTexture* texture)
00221 {
00222   _texture_cached = texture;
00223 }
00224 
00225 nux::BaseTexture* IconTexture::texture()
00226 {
00227   return _texture_cached.GetPointer();
00228 }
00229 
00230 bool IconTexture::DoCanFocus()
00231 {
00232   return false;
00233 }
00234 
00235 std::string IconTexture::GetName() const
00236 {
00237   return "IconTexture";
00238 }
00239 
00240 
00241 void IconTexture::AddProperties(GVariantBuilder* builder)
00242 {
00243   unity::variant::BuilderWrapper(builder)
00244   .add(GetGeometry())
00245   .add("icon_name", _icon_name);
00246 }
00247 
00248 //
00249 // Key navigation
00250 //
00251 
00252 void IconTexture::SetAcceptKeyNavFocus(bool accept)
00253 {
00254   _accept_key_nav_focus = accept;
00255 }
00256 
00257 bool IconTexture::AcceptKeyNavFocus()
00258 {
00259   return _accept_key_nav_focus;
00260 }
00261 
00262 }