Back to index

unity  6.0.0
ResultRendererHorizontalTile.cpp
Go to the documentation of this file.
00001 // -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
00002 /*
00003  * Copyright 2011 Canonical Ltd.
00004  *
00005  * This program is free software: you can redistribute it and/or modify it
00006  * under the terms of the GNU Lesser 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, but
00010  * WITHOUT ANY WARRANTY; without even the implied warranties of
00011  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00012  * PURPOSE.  See the applicable version of the GNU Lesser General Public
00013  * License for more details.
00014  *
00015  * You should have received a copy of both the GNU Lesser General Public
00016  * License version 3 along with this program.  If not, see
00017  * <http://www.gnu.org/licenses/>
00018  *
00019  * Authored by: Gordon Allott <gord.allott@canonical.com>
00020  *
00021  */
00022 
00023 #include "ResultRendererHorizontalTile.h"
00024 
00025 #include <sstream>
00026 
00027 #include <pango/pango.h>
00028 #include <pango/pangocairo.h>
00029 #include <gdk/gdk.h>
00030 #include <gtk/gtk.h>
00031 
00032 #include <UnityCore/GLibWrapper.h>
00033 
00034 #include "unity-shared/CairoTexture.h"
00035 #include "unity-shared/DashStyle.h"
00036 #include "unity-shared/IconLoader.h"
00037 #include "unity-shared/IconTexture.h"
00038 #include "unity-shared/TextureCache.h"
00039 
00040 
00041 namespace unity
00042 {
00043 namespace
00044 {
00045 //~ nux::logging::Logger logger("unity.dash.ResultRendererHorizontalTile");
00046 const int   CARD_VIEW_PADDING              = 4;   // pixels
00047 const int   CARD_VIEW_ICON_SIZE            = 64;  // pixels
00048 const int   CARD_VIEW_ICON_TEXT_GAP        = 10;  // pixels
00049 //const int   CARD_VIEW_GAP_VERT             = 24;  // pixels
00050 //const int   CARD_VIEW_GAP_HORIZ            = 25;  // pixels
00051 const int   CARD_VIEW_WIDTH                = 277; // pixels
00052 const int   CARD_VIEW_HEIGHT               = 74;  // pixels
00053 const int   CARD_VIEW_HIGHLIGHT_CORNER_RADIUS = 2; // pixels
00054 //const char  CARD_VIEW_ICON_OUTLINE_COLOR   = "#000000";
00055 //const float CARD_VIEW_ICON_OUTLINE_OPACITY = 1.0; //float
00056 const int   CARD_VIEW_ICON_OUTLINE_WIDTH   = 1;   // pixels
00057 const int CARD_VIEW_TEXT_LINE_SPACING    = 0; // points
00058 //const char  CARD_VIEW_TEXT_TITLE_COLOR     = "#ffffff";
00059 //const float CARD_VIEW_TEXT_TITLE_OPACITY   = 1.0; // float
00060 //const float CARD_VIEW_TEXT_TITLE_SIZE      = 13.0; // points
00061 //const char  CARD_VIEW_TEXT_TITLE_WEIGHT    = "bold";
00062 //const char  CARD_VIEW_TEXT_BODY_COLOR      = "#ffffff";
00063 //const float CARD_VIEW_TEXT_BODY_OPACITY    = 1.0; // float
00064 //const float CARD_VIEW_TEXT_BODY_SIZE       = 13.0; // points
00065 //const int   CARD_VIEW_TEXT_BODY_WEIGHT     = "regular";
00066 }
00067 
00068 namespace dash
00069 {
00070 NUX_IMPLEMENT_OBJECT_TYPE(ResultRendererHorizontalTile);
00071 
00072 ResultRendererHorizontalTile::ResultRendererHorizontalTile(NUX_FILE_LINE_DECL)
00073   : ResultRendererTile(NUX_FILE_LINE_PARAM)
00074 {
00075   width = CARD_VIEW_WIDTH;
00076   height = CARD_VIEW_HEIGHT;
00077 
00078   // pre-load the highlight texture
00079   // try and get a texture from the texture cache
00080   TextureCache& cache = TextureCache::GetDefault();
00081   prelight_cache_ = cache.FindTexture("ResultRendererHorizontalTile.PreLightTexture",
00082                                       CARD_VIEW_WIDTH,
00083                                       CARD_VIEW_HEIGHT,
00084                                       sigc::mem_fun(this, &ResultRendererHorizontalTile::DrawHighlight));
00085   normal_cache_ = cache.FindTexture("ResultRendererHorizontalTile.NormalTexture",
00086                                       CARD_VIEW_WIDTH,
00087                                       CARD_VIEW_HEIGHT,
00088                                       sigc::mem_fun(this, &ResultRendererHorizontalTile::DrawNormal));
00089 
00090 }
00091 
00092 ResultRendererHorizontalTile::~ResultRendererHorizontalTile()
00093 {
00094 }
00095 
00096 void ResultRendererHorizontalTile::Render(nux::GraphicsEngine& GfxContext,
00097                                 Result& row,
00098                                 ResultRendererState state,
00099                                 nux::Geometry& geometry,
00100                                 int x_offset, int y_offset)
00101 {
00102   TextureContainer* container = row.renderer<TextureContainer*>();
00103   if (container == nullptr)
00104     return;
00105 
00106   // set up our texture mode
00107   nux::TexCoordXForm texxform;
00108 
00109   int icon_left_hand_side = geometry.x + padding;
00110   int icon_top_side = geometry.y + ((geometry.height - CARD_VIEW_ICON_SIZE) / 2);
00111 
00112   // render overall tile background "rectangle"
00113   if (state == ResultRendererState::RESULT_RENDERER_NORMAL)
00114   {
00115     int x = icon_left_hand_side;
00116     int y = icon_top_side;
00117     int w = CARD_VIEW_WIDTH;
00118     int h = CARD_VIEW_HEIGHT;
00119 
00120     unsigned int alpha = 0;
00121     unsigned int src   = 0;
00122     unsigned int dest  = 0;
00123     GfxContext.GetRenderStates().GetBlend(alpha, src, dest);
00124     GfxContext.GetRenderStates().SetBlend(true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
00125 
00126     GfxContext.QRP_1Tex(x,
00127                         y,
00128                         w,
00129                         h,
00130                         normal_cache_->GetDeviceTexture(),
00131                         texxform,
00132                         nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
00133 
00134     GfxContext.GetRenderStates().SetBlend(alpha, src, dest);
00135   }
00136 
00137   // render highlight if its needed
00138   if (state != ResultRendererState::RESULT_RENDERER_NORMAL)
00139   {
00140     int x = icon_left_hand_side;
00141     int y = icon_top_side;
00142     int w = CARD_VIEW_WIDTH;
00143     int h = CARD_VIEW_HEIGHT;
00144 
00145     GfxContext.QRP_1Tex(x,
00146                         y,
00147                         w,
00148                         h,
00149                         prelight_cache_->GetDeviceTexture(),
00150                         texxform,
00151                         nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
00152   }
00153 
00154   // draw the icon
00155   if (container->icon)
00156   {
00157     int x = icon_left_hand_side + CARD_VIEW_PADDING + CARD_VIEW_ICON_OUTLINE_WIDTH;
00158     int y = icon_top_side + CARD_VIEW_PADDING + CARD_VIEW_ICON_OUTLINE_WIDTH;
00159     int w = CARD_VIEW_ICON_SIZE;
00160     int h = CARD_VIEW_ICON_SIZE;
00161     gPainter.Paint2DQuadColor(GfxContext,
00162                               x - CARD_VIEW_ICON_OUTLINE_WIDTH,
00163                               y - CARD_VIEW_ICON_OUTLINE_WIDTH,
00164                               w + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH,
00165                               h + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH,
00166                               nux::color::Black);
00167     GfxContext.QRP_1Tex(x,
00168                         y,
00169                         w,
00170                         h,
00171                         container->icon->GetDeviceTexture(),
00172                         texxform,
00173                         nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
00174   }
00175 
00176   if (container->text)
00177   {
00178     int x = icon_left_hand_side + CARD_VIEW_PADDING + 2 * CARD_VIEW_ICON_OUTLINE_WIDTH + CARD_VIEW_ICON_SIZE + CARD_VIEW_ICON_TEXT_GAP;
00179     int y = icon_top_side + CARD_VIEW_PADDING;
00180     int w = container->text->GetWidth();
00181     int h = container->text->GetHeight();
00182 
00183     GfxContext.QRP_1Tex(x,
00184                         y,
00185                         w,
00186                         h,
00187                         container->text->GetDeviceTexture(),
00188                         texxform,
00189                         nux::Color(1.0f, 1.0f, 1.0f, 1.0f));
00190   }
00191 }
00192 
00193 nux::BaseTexture* ResultRendererHorizontalTile::DrawHighlight(std::string const& texid,
00194                                                               int width, int height)
00195 {
00196   nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);
00197   cairo_t* cr = cairo_graphics.GetInternalContext();
00198 
00199   cairo_scale(cr, 1.0f, 1.0f);
00200 
00201   cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
00202   cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
00203   cairo_paint(cr);
00204 
00205   // draw the highlight
00206   cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
00207   cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 0.2f);
00208   cairo_graphics.DrawRoundedRectangle(cr,
00209                                       1.0f,
00210                                       0.0f,
00211                                       0.0f,
00212                                       CARD_VIEW_HIGHLIGHT_CORNER_RADIUS,
00213                                       width,
00214                                       height,
00215                                       false);
00216   cairo_fill(cr);
00217 
00218   return texture_from_cairo_graphics(cairo_graphics);
00219 }
00220 
00221 nux::BaseTexture* ResultRendererHorizontalTile::DrawNormal(std::string const& texid,
00222                                                               int width, int height)
00223 {
00224   nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height);
00225   cairo_t* cr = cairo_graphics.GetInternalContext();
00226 
00227   cairo_scale(cr, 1.0f, 1.0f);
00228 
00229   cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 0.0);
00230   cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
00231   cairo_paint(cr);
00232 
00233   // draw the normal bg
00234   cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
00235   cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.075f);
00236   cairo_graphics.DrawRoundedRectangle(cr,
00237                                       1.0f,
00238                                       0.0f,
00239                                       0.0f,
00240                                       CARD_VIEW_HIGHLIGHT_CORNER_RADIUS,
00241                                       width,
00242                                       height,
00243                                       false);
00244   cairo_fill(cr);
00245 
00246   return texture_from_cairo_graphics(cairo_graphics);
00247 }
00248 
00249 void ResultRendererHorizontalTile::LoadText(Result& row)
00250 {
00251   std::stringstream final_text;
00252   char *name = g_markup_escape_text(row.name().c_str()  , -1);
00253   char *comment = g_markup_escape_text(row.comment().c_str()  , -1);
00254 
00255   if(row.comment().empty())
00256     final_text << "<b>" << name << "</b>";
00257   else
00258     final_text << "<b>" << name << "</b>" << "\n" << comment;
00259 
00260   g_free(name);
00261   g_free(comment);
00262 
00263   nux::CairoGraphics _cairoGraphics(CAIRO_FORMAT_ARGB32,
00264                                     CARD_VIEW_WIDTH - CARD_VIEW_ICON_SIZE - 2 * CARD_VIEW_ICON_OUTLINE_WIDTH - 2 * CARD_VIEW_PADDING - CARD_VIEW_ICON_TEXT_GAP,
00265                                     CARD_VIEW_HEIGHT - 2 * CARD_VIEW_PADDING);
00266 
00267   cairo_t* cr = _cairoGraphics.GetContext();
00268 
00269   PangoLayout*          layout     = NULL;
00270   PangoFontDescription* desc       = NULL;
00271   PangoContext*         pango_context   = NULL;
00272   GdkScreen*            screen     = gdk_screen_get_default();    // not ref'ed
00273   int                   dpi = -1;
00274 
00275   g_object_get(gtk_settings_get_default(), "gtk-xft-dpi", &dpi, NULL);
00276 
00277   cairo_set_font_options(cr, gdk_screen_get_font_options(screen));
00278   layout = pango_cairo_create_layout(cr);
00279   desc = pango_font_description_from_string("Ubuntu 10");
00280 
00281   pango_layout_set_font_description(layout, desc);
00282   pango_layout_set_alignment(layout, PANGO_ALIGN_LEFT);
00283 
00284   pango_layout_set_wrap(layout, PANGO_WRAP_WORD_CHAR);
00285   pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);
00286   pango_layout_set_spacing(layout, CARD_VIEW_TEXT_LINE_SPACING * PANGO_SCALE);
00287   pango_layout_set_width(layout, (CARD_VIEW_WIDTH - CARD_VIEW_ICON_SIZE - 2 * CARD_VIEW_ICON_OUTLINE_WIDTH - 2 * CARD_VIEW_PADDING - CARD_VIEW_ICON_TEXT_GAP) * PANGO_SCALE);
00288   pango_layout_set_height(layout, -4);
00289 
00290   pango_layout_set_markup(layout, final_text.str().c_str(), -1);
00291 
00292   pango_context = pango_layout_get_context(layout);  // is not ref'ed
00293   pango_cairo_context_set_font_options(pango_context,
00294                                        gdk_screen_get_font_options(screen));
00295   pango_cairo_context_set_resolution(pango_context,
00296                                      dpi == -1 ? 96.0f : dpi/(float) PANGO_SCALE);
00297   pango_layout_context_changed(layout);
00298 
00299   cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
00300   cairo_paint(cr);
00301 
00302   cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
00303   cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
00304 
00305   double offset = 0.0;
00306   PangoRectangle logRect = {0, 0, 0, 0};
00307   pango_layout_get_extents(layout, NULL, &logRect);
00308   if (pango_layout_get_line_count(layout) < 4)
00309     offset = ((CARD_VIEW_HEIGHT - 2 * CARD_VIEW_PADDING) - (logRect.height / PANGO_SCALE)) / 2.0;
00310   cairo_move_to(cr, 0.0f, offset);
00311   pango_cairo_show_layout(cr, layout);
00312 
00313   // clean up
00314   pango_font_description_free(desc);
00315   g_object_unref(layout);
00316 
00317   cairo_destroy(cr);
00318 
00319   TextureContainer *container = row.renderer<TextureContainer*>();
00320   if (container)
00321     container->text = texture_ptr_from_cairo_graphics(_cairoGraphics);
00322 }
00323 
00324 
00325 }
00326 }