nux-1.16.0
|
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