nux-1.14.0
tooltip.cpp
00001 /*
00002  * Copyright 2010 Inalogic Inc.
00003  *
00004  * This program is free software: you can redistribute it and/or modify it
00005  * under the terms of the GNU General Public License version 3, as published
00006  * by the  Free Software Foundation.
00007  *
00008  * This program is distributed in the hope that it will be useful, but
00009  * WITHOUT ANY WARRANTY; without even the implied warranties of
00010  * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
00011  * PURPOSE.  See the GNU General Public License for more details.
00012  *
00013  * You should have received a copy of the GNU General Public License
00014  * version 3 along with this program.  If not, see
00015  * <http://www.gnu.org/licenses/>
00016  *
00017  * Authored by: Jay Taoko <jaytaoko@inalogic.com>
00018  *
00019  */
00020 
00021 #include "Nux/Nux.h"
00022 #include "Nux/VLayout.h"
00023 #include "Nux/HLayout.h"
00024 #include "Nux/WindowThread.h"
00025 #include "Nux/WindowCompositor.h"
00026 #include "Nux/BaseWindow.h"
00027 #include "Nux/Button.h"
00028 #include "NuxGraphics/GraphicsEngine.h"
00029 #include "NuxGraphics/Events.h"
00030 #include "Nux/TextureArea.h"
00031 #include "NuxImage/CairoGraphics.h"
00032 
00033 #include <pango/pango.h>
00034 #include <pango/pangocairo.h>
00035 
00036 #if defined(NUX_OS_LINUX)
00037 #include <X11/Xlib.h>
00038 #endif
00039 
00040 #define ANCHOR_WIDTH   10.0f
00041 #define ANCHOR_HEIGHT  18.0f
00042 #define RADIUS         5.0f
00043 #define BLUR_INTENSITY 8
00044 #define LINE_WIDTH     1.0f
00045 #define PADDING_SIZE   1
00046 #define H_MARGIN       30
00047 #define V_MARGIN       4
00048 #define FONT_FACE      "Ubuntu 13"
00049 
00050 namespace nux
00051 {
00052   class Tooltip : public BaseWindow
00053   {
00054       NUX_DECLARE_OBJECT_TYPE(Tooltip, BaseWindow);
00055     public:
00056       Tooltip (int     x,
00057                int     y,
00058                NString text);
00059       ~Tooltip ();
00060 
00061       long ProcessEvent (IEvent& iEvent,
00062                          long    traverseInfo,
00063                          long    processEventInfo);
00064 
00065       void Draw (GraphicsEngine& gfxContext,
00066                  bool             forceDraw);
00067 
00068       void DrawContent (GraphicsEngine& gfxContext,
00069                         bool             forceDraw);
00070 
00071     protected:
00072       void PreLayoutManagement ();
00073 
00074       long PostLayoutManagement (long layoutResult);
00075 
00076       void PositionChildLayout (float offsetX,
00077                                 float offsetY);
00078 
00079       void LayoutWindowElements ();
00080 
00081       void NotifyConfigurationChange (int width,
00082                                       int height);
00083 
00084       ObjectPtr<BaseTexture>  _texture2D;
00085       int                   _anchorX;
00086       int                   _anchorY;
00087       nux::NString          _labelText;
00088       int                   _dpiX;
00089       int                   _dpiY;
00090       cairo_font_options_t* _fontOpts;
00091 
00092     private:
00093       void ComputeFullMaskPath (cairo_t* cr,
00094                                 gfloat   anchor_width,
00095                                 gfloat   anchor_height,
00096                                 gint     width,
00097                                 gint     height,
00098                                 gint     upper_size,
00099                                 gfloat   radius,
00100                                 guint    pad);
00101 
00102       void DrawDraw (cairo_t* cr,
00103                      gboolean outline,
00104                      gfloat   line_width,
00105                      gfloat*  rgba,
00106                      gboolean negative,
00107                      gboolean stroke);
00108 
00109       void DrawTintDotHighlight (cairo_t* cr,
00110                                  gint     width,
00111                                  gint     height,
00112                                  gfloat   hl_x,
00113                                  gfloat   hl_y,
00114                                  gfloat   hl_size,
00115                                  gfloat*  rgba_tint,
00116                                  gfloat*  rgba_hl);
00117 
00118       void DrawOutlineShadow (cairo_t* cr,
00119                               gint     width,
00120                               gint     height,
00121                               gfloat   anchor_width,
00122                               gfloat   anchor_height,
00123                               gint     upper_size,
00124                               gfloat   corner_radius,
00125                               guint    blur_coeff,
00126                               gfloat*  rgba_shadow,
00127                               gfloat   line_width,
00128                               gint     padding_size,
00129                               gfloat*  rgba_line);
00130 
00131       void ComputeOutline (cairo_t* cr,
00132                            gfloat   line_width,
00133                            gfloat*  rgba_line,
00134                            gint     width,
00135                            gfloat   anchor_width,
00136                            gfloat   corner_radius,
00137                            gint     padding_size);
00138 
00139       void DrawMask (cairo_t* cr,
00140                      gint     width,
00141                      gint     height,
00142                      gfloat   radius,
00143                      guint    shadow_radius,
00144                      gfloat   anchor_width,
00145                      gfloat   anchor_height,
00146                      gint     upper_size,
00147                      gboolean negative,
00148                      gboolean outline,
00149                      gfloat   line_width,
00150                      gint     padding_size,
00151                      gfloat*  rgba);
00152 
00153       void GetDPI ();
00154 
00155       void GetTextExtents (char* font,
00156                            int*  width,
00157                            int*  height);
00158 
00159       void DrawLabel (cairo_t* cr,
00160                       gint     width,
00161                       gint     height,
00162                       gfloat*  rgba);
00163   };
00164 
00165   NUX_IMPLEMENT_OBJECT_TYPE(Tooltip);
00166 
00167   void
00168   DrawCairo (cairo_t* cr,
00169              gboolean outline,
00170              gfloat   line_width,
00171              gfloat*  rgba,
00172              gboolean negative,
00173              gboolean stroke)
00174   {
00175     // prepare drawing
00176     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
00177 
00178     // actually draw the mask
00179     if (outline)
00180       {
00181         cairo_set_line_width (cr, line_width);
00182         cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
00183       }
00184     else
00185       {
00186         if (negative)
00187           cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
00188         else
00189           cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
00190       }
00191 
00192     // stroke or fill?
00193     if (stroke)
00194       cairo_stroke_preserve (cr);
00195     else
00196       cairo_fill_preserve (cr);
00197   }
00198 
00199   void
00200   Tooltip::ComputeFullMaskPath (cairo_t* cr,
00201                                 gfloat   anchor_width,
00202                                 gfloat   anchor_height,
00203                                 gint     width,
00204                                 gint     height,
00205                                 gint     upper_size,
00206                                 gfloat   radius,
00207                                 guint    pad)
00208   {
00209     //     0  1        2  3
00210     //     +--+--------+--+
00211     //     |              |
00212     //     + 14           + 4
00213     //     |              |
00214     //     |              |
00215     //     |              |
00216     //     + 13           |
00217     //    /               |
00218     //   /                |
00219     //  + 12              |
00220     //   \                |
00221     //    \               |
00222     //  11 +              |
00223     //     |              |
00224     //     |              |
00225     //     |              |
00226     //  10 +              + 5
00227     //     |              |
00228     //     +--+--------+--+ 6
00229     //     9  8        7
00230 
00231     gfloat padding    = pad;
00232     float  ZEROPOINT5 = 0.5f;
00233   
00234     gfloat HeightToAnchor = 0.0f;
00235     HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
00236     if (HeightToAnchor < 0.0f)
00237     {
00238       g_warning ("Anchor-height and corner-radius a higher than whole texture!");
00239       return;
00240     }
00241 
00242     //gint dynamic_size = height - 2*radius - 2*padding - anchor_height;
00243     //gint upper_dynamic_size = upper_size;
00244     //gint lower_dynamic_size = dynamic_size - upper_dynamic_size;
00245   
00246     if (upper_size >= 0)
00247       {
00248         if(upper_size > height - 2.0f * radius - anchor_height -2 * padding)
00249           {
00250             //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
00251             HeightToAnchor = 0;
00252           }
00253         else
00254           {
00255             HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size;
00256           }
00257       }
00258     else
00259       {
00260         HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
00261       }
00262 
00263     cairo_translate (cr, -0.5f, -0.5f);
00264     
00265     // create path
00266     cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1
00267     cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5);   // Point 2
00268     cairo_arc (cr,
00269                width  - padding - radius + ZEROPOINT5,
00270                padding + radius + ZEROPOINT5,
00271                radius,
00272                -90.0f * G_PI / 180.0f,
00273                0.0f * G_PI / 180.0f);   // Point 4
00274     cairo_line_to (cr,
00275                    (gdouble) width - padding + ZEROPOINT5,
00276                    (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
00277     cairo_arc (cr,
00278                (gdouble) width - padding - radius + ZEROPOINT5,
00279                (gdouble) height - padding - radius + ZEROPOINT5,
00280                radius,
00281                0.0f * G_PI / 180.0f,
00282                90.0f * G_PI / 180.0f);  // Point 7
00283     cairo_line_to (cr,
00284                    anchor_width + padding + radius + ZEROPOINT5,
00285                    (gdouble) height - padding + ZEROPOINT5); // Point 8
00286 
00287     cairo_arc (cr,
00288                anchor_width + padding + radius + ZEROPOINT5,
00289                (gdouble) height - padding - radius,
00290                radius,
00291                90.0f * G_PI / 180.0f,
00292                180.0f * G_PI / 180.0f); // Point 10
00293 
00294     cairo_line_to (cr,
00295                    padding + anchor_width + ZEROPOINT5,
00296                    (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 );  // Point 11
00297     cairo_line_to (cr,
00298                    padding + ZEROPOINT5,
00299                    (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
00300     cairo_line_to (cr,
00301                    padding + anchor_width + ZEROPOINT5,
00302                    (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5);  // Point 13
00303   
00304     cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, 
00305                    padding + radius  + ZEROPOINT5);  // Point 14
00306     cairo_arc (cr,
00307                padding + anchor_width + radius + ZEROPOINT5,
00308                padding + radius + ZEROPOINT5,
00309                radius,
00310                180.0f * G_PI / 180.0f,
00311                270.0f * G_PI / 180.0f);
00312 
00313     cairo_close_path (cr);
00314   }
00315 
00316   void
00317   ComputeMask (cairo_t* cr)
00318   {
00319     cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
00320     cairo_fill_preserve (cr);
00321   }
00322 
00323   void
00324   Tooltip::ComputeOutline (cairo_t* cr,
00325                            gfloat   line_width,
00326                            gfloat*  rgba_line,
00327                            gint     width,
00328                            gfloat   anchor_width,
00329                            gfloat   corner_radius,
00330                            gint     padding_size)
00331   {
00332     cairo_pattern_t* pattern = NULL;
00333     double           offset  = 0.0;
00334 
00335     if (width == 0)
00336     {
00337       g_warning ("%s(): passed in width is 0!", G_STRFUNC);
00338       return;
00339     }
00340 
00341     offset = ((double) padding_size + anchor_width + corner_radius) /
00342              (double) width;
00343 
00344     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
00345     cairo_set_line_width (cr, line_width);
00346 
00347     pattern = cairo_pattern_create_linear (0.0, 0.0, (double) width, 0.0);
00348     cairo_pattern_add_color_stop_rgba (pattern,
00349                                        0.0,
00350                                        rgba_line[0],
00351                                        rgba_line[1],
00352                                        rgba_line[2],
00353                                        0.7);
00354     cairo_pattern_add_color_stop_rgba (pattern,
00355                                        offset,
00356                                        rgba_line[0],
00357                                        rgba_line[1],
00358                                        rgba_line[2],
00359                                        0.7);
00360     cairo_pattern_add_color_stop_rgba (pattern,
00361                                        offset + 0.0125,
00362                                        rgba_line[0],
00363                                        rgba_line[1],
00364                                        rgba_line[2],
00365                                        0.4);
00366     cairo_pattern_add_color_stop_rgba (pattern,
00367                                        1.0,
00368                                        rgba_line[0],
00369                                        rgba_line[1],
00370                                        rgba_line[2],
00371                                        0.4);
00372 
00373     cairo_set_source (cr, pattern);
00374     cairo_stroke (cr);
00375     cairo_pattern_destroy (pattern);
00376   }
00377 
00378   void
00379   Tooltip::DrawTintDotHighlight (cairo_t* cr,
00380                                  gint     width,
00381                                  gint     height,
00382                                  gfloat   hl_x,
00383                                  gfloat   hl_y,
00384                                  gfloat   hl_size,
00385                                  gfloat*  rgba_tint,
00386                                  gfloat*  rgba_hl)
00387   {
00388     cairo_surface_t* dots_surf    = NULL;
00389     cairo_t*         dots_cr      = NULL;
00390     cairo_pattern_t* dots_pattern = NULL;
00391     cairo_pattern_t* hl_pattern   = NULL;
00392 
00393     // create context for dot-pattern
00394     dots_surf = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 4, 4);
00395     dots_cr = cairo_create (dots_surf);
00396 
00397     // clear normal context
00398     cairo_scale (cr, 1.0f, 1.0f);
00399     cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
00400     cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
00401     cairo_paint (cr);
00402 
00403     // prepare drawing for normal context
00404     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
00405 
00406     // create path in normal context
00407     ComputeFullMaskPath (cr,
00408                          ANCHOR_WIDTH,
00409                          ANCHOR_HEIGHT,
00410                          width,
00411                          height,
00412                          -1,
00413                          RADIUS,
00414                          PADDING_SIZE);
00415     //cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);  
00416 
00417     // fill path of normal context with tint
00418     cairo_set_source_rgba (cr,
00419                            rgba_tint[0],
00420                            rgba_tint[1],
00421                            rgba_tint[2],
00422                            rgba_tint[3]);
00423     cairo_fill_preserve (cr);
00424 
00425     // create pattern in dot-context
00426     cairo_set_operator (dots_cr, CAIRO_OPERATOR_CLEAR);
00427     cairo_paint (dots_cr);
00428     cairo_scale (dots_cr, 1.0f, 1.0f);
00429     cairo_set_operator (dots_cr, CAIRO_OPERATOR_OVER);
00430     cairo_set_source_rgba (dots_cr,
00431                            rgba_hl[0],
00432                            rgba_hl[1],
00433                            rgba_hl[2],
00434                            rgba_hl[3]);
00435     cairo_rectangle (dots_cr, 0.0f, 0.0f, 1.0f, 1.0f);
00436     cairo_fill (dots_cr);
00437     cairo_rectangle (dots_cr, 2.0f, 2.0f, 1.0f, 1.0f);
00438     cairo_fill (dots_cr);
00439 
00440     dots_pattern = cairo_pattern_create_for_surface (dots_surf);
00441 
00442     // fill path of normal context with dot-pattern
00443     // FIXME: using the path from ComputeFullMaskPath() and not a plain rect.
00444     // path triggers a bug in cairo (yet to be filed), so repeating of the dot-
00445     // pattern produces wrong pattern in the end, a viable work-around still
00446     // needs to be thought up
00447     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
00448     cairo_set_source (cr, dots_pattern);
00449     cairo_pattern_set_extend (dots_pattern, CAIRO_EXTEND_REPEAT);
00450     cairo_fill_preserve (cr);
00451     cairo_pattern_destroy (dots_pattern);
00452     cairo_surface_destroy (dots_surf);
00453     cairo_destroy (dots_cr);
00454 
00455     // draw highlight
00456     cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
00457     hl_pattern = cairo_pattern_create_radial (hl_x,
00458                                               hl_y,
00459                                               0.0f,
00460                                               hl_x,
00461                                               hl_y,
00462                                               hl_size);
00463     cairo_pattern_add_color_stop_rgba (hl_pattern,
00464                                        0.0f,
00465                                        1.0f,
00466                                        1.0f,
00467                                        1.0f,
00468                                        0.65f);
00469     cairo_pattern_add_color_stop_rgba (hl_pattern,
00470                                        1.0f,
00471                                        1.0f,
00472                                        1.0f,
00473                                        1.0f,
00474                                        0.0f);
00475     cairo_set_source (cr, hl_pattern);
00476     cairo_fill (cr);
00477     cairo_pattern_destroy (hl_pattern);
00478   }
00479 
00480   void
00481   Tooltip::DrawMask (cairo_t* cr,
00482                      gint     width,
00483                      gint     height,
00484                      gfloat   radius,
00485                      guint    shadow_radius,
00486                      gfloat   anchor_width,
00487                      gfloat   anchor_height,
00488                      gint     upper_size,
00489                      gboolean negative,
00490                      gboolean outline,
00491                      gfloat   line_width,
00492                      gint     padding_size,
00493                      gfloat*  rgba)
00494   {
00495     ComputeFullMaskPath (cr,
00496                          anchor_width,
00497                          anchor_height,
00498                          width,
00499                          height,
00500                          upper_size,
00501                          radius,
00502                          padding_size);
00503   }
00504 
00505   void
00506   Tooltip::GetDPI ()
00507   {
00508 #if defined(NUX_OS_LINUX)
00509     Display* display     = NULL;
00510     int      screen      = 0;
00511     double   dpyWidth    = 0.0;
00512     double   dpyHeight   = 0.0;
00513     double   dpyWidthMM  = 0.0;
00514     double   dpyHeightMM = 0.0;
00515     double   dpiX        = 0.0;
00516     double   dpiY        = 0.0;
00517 
00518     display = XOpenDisplay (NULL);
00519     screen = DefaultScreen (display);
00520 
00521     dpyWidth    = (double) DisplayWidth (display, screen);
00522     dpyHeight   = (double) DisplayHeight (display, screen);
00523     dpyWidthMM  = (double) DisplayWidthMM (display, screen);
00524     dpyHeightMM = (double) DisplayHeightMM (display, screen);
00525 
00526     dpiX = dpyWidth * 25.4 / dpyWidthMM;
00527     dpiY = dpyHeight * 25.4 / dpyHeightMM;
00528 
00529     _dpiX = (int) (dpiX + 0.5);
00530     _dpiY = (int) (dpiY + 0.5);
00531 
00532     XCloseDisplay (display);
00533 #elif defined(NUX_OS_WINDOWS)
00534     _dpiX = 72;
00535     _dpiY = 72;
00536 #endif
00537   }
00538 
00539   void
00540   Tooltip::GetTextExtents (char* font,
00541                            int*  width,
00542                            int*  height)
00543   {
00544     cairo_surface_t*      surface  = NULL;
00545     cairo_t*              cr       = NULL;
00546     PangoLayout*          layout   = NULL;
00547     PangoFontDescription* desc     = NULL;
00548     PangoContext*         pangoCtx = NULL;
00549     PangoRectangle        logRect  = {0, 0, 0, 0};
00550 
00551     // sanity check
00552     if (!font || !width || !height)
00553       return;
00554 
00555     surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1);
00556     cr = cairo_create (surface);
00557     layout = pango_cairo_create_layout (cr);
00558     desc = pango_font_description_from_string (font);
00559     pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
00560     pango_layout_set_font_description (layout, desc);
00561     pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
00562     pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
00563     pango_layout_set_text (layout, _labelText.GetTCharPtr(), -1);
00564     pangoCtx = pango_layout_get_context (layout); // is not ref'ed
00565     pango_cairo_context_set_font_options (pangoCtx, _fontOpts);
00566     pango_cairo_context_set_resolution (pangoCtx, _dpiX);
00567     pango_layout_context_changed (layout);
00568     pango_layout_get_extents (layout, NULL, &logRect);
00569 
00570     *width  = logRect.width / PANGO_SCALE;
00571     *height = logRect.height / PANGO_SCALE;
00572 
00573     // clean up
00574     pango_font_description_free (desc);
00575     g_object_unref (layout);
00576     cairo_destroy (cr);
00577     cairo_surface_destroy (surface);
00578   }
00579 
00580   void
00581   Tooltip::DrawLabel (cairo_t* cr,
00582                       gint     width,
00583                       gint     height,
00584                       gfloat*  rgba)
00585   {
00586     int                   textWidth  = 0;
00587     int                   textHeight = 0;
00588     PangoLayout*          layout     = NULL;
00589     PangoFontDescription* desc       = NULL;
00590     PangoContext*         pangoCtx   = NULL;
00591 
00592     GetTextExtents ((char*) FONT_FACE,
00593                     &textWidth,
00594                     &textHeight);
00595 
00596     cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
00597 
00598     cairo_set_font_options (cr, _fontOpts);
00599     layout = pango_cairo_create_layout (cr);
00600     desc = pango_font_description_from_string ((char*) FONT_FACE);
00601     pango_font_description_set_weight (desc, PANGO_WEIGHT_NORMAL);
00602     pango_layout_set_font_description (layout, desc);
00603     pango_layout_set_wrap (layout, PANGO_WRAP_WORD_CHAR);
00604     pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
00605     pango_layout_set_text (layout, _labelText.GetTCharPtr(), -1);
00606     pangoCtx = pango_layout_get_context (layout); // is not ref'ed
00607     pango_cairo_context_set_font_options (pangoCtx, _fontOpts);
00608     pango_cairo_context_set_resolution (pangoCtx, (double) _dpiX);
00609     pango_layout_context_changed (layout);
00610 
00611     cairo_move_to (cr,
00612                    ANCHOR_WIDTH + (float) ((width - ANCHOR_WIDTH) - textWidth) / 2.0f,
00613                    (float) (height - textHeight) / 2.0f);
00614     pango_cairo_show_layout (cr, layout);
00615     cairo_fill (cr);
00616 
00617     // clean up
00618     pango_font_description_free (desc);
00619     g_object_unref (layout);
00620   }
00621 
00622   void
00623   Tooltip::DrawOutlineShadow (cairo_t* cr,
00624                               gint     width,
00625                               gint     height,
00626                               gfloat   anchor_width,
00627                               gfloat   anchor_height,
00628                               gint     upper_size,
00629                               gfloat   corner_radius,
00630                               guint    blur_coeff,
00631                               gfloat*  rgba_shadow,
00632                               gfloat   line_width,
00633                               gint     padding_size,
00634                               gfloat*  rgba_line)
00635   {
00636     ComputeFullMaskPath (cr,
00637                          anchor_width,
00638                          anchor_height,
00639                          width,
00640                          height,
00641                          upper_size,
00642                          corner_radius,
00643                          padding_size);
00644     //DrawCairo (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
00645     //ctk_surface_blur (surf, blur_coeff);
00646     //ComputeMask (cr);
00647     ComputeOutline (cr,
00648                     line_width,
00649                     rgba_line,
00650                     width,
00651                     anchor_width,
00652                     corner_radius,
00653                     padding_size);
00654   }
00655 
00656   Tooltip::Tooltip (int     x,
00657                     int     y,
00658                     NString text)
00659     : BaseWindow("", NUX_TRACKER_LOCATION)
00660   {
00661     _anchorX   = x;
00662     _anchorY   = y;
00663     _labelText = text;
00664     _fontOpts  = cairo_font_options_create ();
00665 
00666     // FIXME: hard-coding these for the moment, as we don't have
00667     // gsettings-support in place right now
00668     cairo_font_options_set_antialias (_fontOpts, CAIRO_ANTIALIAS_SUBPIXEL);
00669     cairo_font_options_set_hint_metrics (_fontOpts, CAIRO_HINT_METRICS_ON);
00670     cairo_font_options_set_hint_style (_fontOpts, CAIRO_HINT_STYLE_SLIGHT);
00671     cairo_font_options_set_subpixel_order (_fontOpts, CAIRO_SUBPIXEL_ORDER_RGB);
00672 
00673     // make sure _dpiX and _dpiY are initialized correctly
00674     GetDPI ();
00675   }
00676 
00677   Tooltip::~Tooltip ()
00678   {
00679     cairo_font_options_destroy(_fontOpts);
00680   }
00681 
00682   long
00683   Tooltip::ProcessEvent (IEvent& ievent,
00684                          long    TraverseInfo,
00685                          long    ProcessEventInfo)
00686   {
00687     return 0;
00688   }
00689 
00690   void Tooltip::Draw (GraphicsEngine& gfxContext,
00691                       bool             forceDraw)
00692   {
00693     Geometry base = GetGeometry();
00694 
00695     // the elements position inside the window are referenced to top-left window
00696     // corner. So bring base to (0, 0).
00697     base.SetX (0);
00698     base.SetY (0);
00699     gfxContext.PushClippingRectangle (base);
00700 
00701     gPainter.PushDrawShapeLayer (gfxContext,
00702                                  base,
00703                                  eSHAPE_CORNER_ROUND10,
00704                                  nux::Color(0xFF707070), eAllCorners, true);
00705 
00706     TexCoordXForm texxform;
00707     texxform.SetWrap(TEXWRAP_REPEAT, TEXWRAP_REPEAT);
00708     texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
00709 
00710     gfxContext.QRP_GLSL_1Tex (base.x,
00711                               base.y,
00712                               base.width,
00713                               base.height,
00714                               _texture2D->GetDeviceTexture(),
00715                               texxform,
00716                               Color(1.0f, 1.0f, 1.0f, 1.0f));
00717 
00718     gPainter.PopBackground ();
00719     gfxContext.PopClippingRectangle ();
00720   }
00721 
00722   void Tooltip::DrawContent (GraphicsEngine &GfxContext, bool force_draw)
00723   {
00724     /*Geometry base = GetGeometry();
00725     int x = base.x;
00726     int y = base.y;
00727     // The elements position inside the window are referenced to top-left window corner. So bring base to (0, 0).
00728     base.SetX (0);
00729     base.SetY (0);
00730 
00731     if (UseBlurredBackground() )
00732     {
00733       TexCoordXForm texxform;
00734       texxform.uoffset = (float) x / (float) GetThreadWindowCompositor().GetScreenBlurTexture()->GetWidth();
00735       texxform.voffset = (float) y / (float) GetThreadWindowCompositor().GetScreenBlurTexture()->GetHeight();
00736       texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
00737 
00738       gPainter.PushTextureLayer (GfxContext, base, GetThreadWindowCompositor().GetScreenBlurTexture(), texxform, Color::White, true);
00739     }
00740     else
00741     {
00742       //nuxDebugMsg(TEXT("[BaseWindow::DrawContent]"));
00743       gPainter.PushShapeLayer (GfxContext, base, eSHAPE_CORNER_ROUND10, m_background_color, eAllCorners, true);
00744       //GfxContext.QRP_GLSL_Color(base.x, base.y, base.width, base.height, Color(1.0f, 0.0f, 0.0f, 1.0f));
00745       //GfxContext.QRP_GLSL_Color(base.x, base.y, base.width, base.height, Color(1.0f / (float) (std::rand () % 100), 1.0f / (float) (std::rand () % 100), 1.0f / (float) (std::rand () % 100), 0.5f));
00746     }
00747 
00748     if (m_layout)
00749     {
00750       GfxContext.PushClippingRectangle (base);
00751       m_layout->ProcessDraw (GfxContext, force_draw);
00752       GfxContext.PopClippingRectangle();
00753     }
00754 
00755     gPainter.PopBackground();*/
00756   }
00757 
00758   void Tooltip::PreLayoutManagement ()
00759   {
00760   }
00761 
00762   long
00763   Tooltip::PostLayoutManagement (long LayoutResult)
00764   {
00765     long     result           = BaseWindow::PostLayoutManagement (LayoutResult);
00766     int      textWidth        = 0;
00767     int      textHeight       = 0;
00768     Geometry base;
00769     float    rgbaTint[4]      = {0.0f, 0.0f, 0.0f, 0.7f};
00770     float    rgbaHighlight[4] = {1.0f, 1.0f, 1.0f, 0.15f};
00771     float    rgbaLine[4]      = {1.0f, 1.0f, 1.0f, 0.75f};
00772     float    rgbaShadow[4]    = {0.0f, 0.0f, 0.0f, 0.48f};
00773     float    rgbaText[4]      = {1.0f, 1.0f, 1.0f, 1.0f};
00774 
00775     GetTextExtents ((char*) FONT_FACE,
00776                     &textWidth,
00777                     &textHeight);
00778 
00779     base.x = _anchorX;
00780     base.y = _anchorY;
00781     base.width = textWidth + 2 * H_MARGIN + ANCHOR_WIDTH + 2 * PADDING_SIZE;
00782     base.height = textHeight + 2 * V_MARGIN + 2 * PADDING_SIZE;
00783     SetGeometry (base);
00784 
00785     CairoGraphics* cairo_graphics = new CairoGraphics (CAIRO_FORMAT_ARGB32,
00786                                          base.GetWidth (),
00787                                          base.GetHeight ());
00788     cairo_t *cr = cairo_graphics->GetContext ();
00789 
00790     DrawTintDotHighlight (cr,
00791                           base.GetWidth (),
00792                           base.GetHeight (),
00793                           base.GetWidth () / 2.0f,
00794                           15.0f,
00795                           base.GetWidth () / 2.0f,
00796                           rgbaTint,
00797                           rgbaHighlight);
00798 
00799     DrawOutlineShadow (cr,
00800                        base.GetWidth (),
00801                        base.GetHeight (),
00802                        ANCHOR_WIDTH,
00803                        ANCHOR_HEIGHT,
00804                        -1,
00805                        RADIUS,
00806                        BLUR_INTENSITY,
00807                        rgbaShadow,
00808                        LINE_WIDTH,
00809                        PADDING_SIZE,
00810                        rgbaLine);
00811 
00812     DrawLabel (cr,
00813                base.GetWidth (),
00814                base.GetHeight (),
00815                rgbaText);
00816 
00817     nux::NBitmapData* bitmap =  cairo_graphics->GetBitmap();
00818 
00819     // Texture2D is the high level representation of an image that is backed by
00820     // an actual opengl texture.
00821     _texture2D = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture ();
00822     // It is initially owned, and now we have a pointer to it, so unref
00823     _texture2D->UnReference();
00824     _texture2D->Update(bitmap);
00825 
00826     delete bitmap;
00827     delete cairo_graphics;
00828 
00829     return result;
00830   }
00831 
00832   void
00833   Tooltip::PositionChildLayout (float offsetX,
00834                                 float offsetY)
00835   {
00836   }
00837 
00838   void
00839   Tooltip::LayoutWindowElements ()
00840   {
00841   }
00842 
00843   void
00844   Tooltip::NotifyConfigurationChange (int width,
00845                                       int height)
00846   {
00847   }
00848 }
00849 
00850 void
00851 initGUIThread (nux::NThread* thread,
00852                void*         data)
00853 {
00854   nux::VLayout* layout  = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
00855 
00856   nux::ColorLayer background(nux::Color(0xFF4D4D4D));
00857   static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background);
00858 
00859   nux::GetWindowThread ()->SetLayout (layout);
00860 }
00861 
00862 int main (int          argc,
00863           char const** argv)
00864 {
00865   nux::WindowThread* thread = NULL;
00866 
00867   nux::NuxInitialize (0);
00868 
00869   thread = nux::CreateGUIThread (TEXT ("NUX/Unity Tooltips"),
00870                                  600,
00871                                  400,
00872                                  0,
00873                                  &initGUIThread,
00874                                  0);
00875 
00876   nux::Tooltip* tooltip1 = new nux::Tooltip (64, 64, TEXT("GEdit"));
00877   nux::Tooltip* tooltip2 = new nux::Tooltip (64, 128, TEXT("Firefox"));
00878   nux::Tooltip* tooltip3 = new nux::Tooltip (64, 192, TEXT("Chromium"));
00879 
00880   tooltip1->ShowWindow(true);
00881   tooltip2->ShowWindow(true);
00882   tooltip3->ShowWindow(true);
00883 
00884   thread->Run (NULL);
00885 
00886   tooltip3->UnReference();
00887   tooltip2->UnReference();
00888   tooltip1->UnReference();
00889   delete thread;
00890 
00891   return 0;
00892 }
00893 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends