~om26er/ubuntu/oneiric/unity/sru-778256

« back to all changes in this revision

Viewing changes to plugins/unityshell/src/Tooltip.cpp

  • Committer: Didier Roche
  • Date: 2011-07-21 16:17:59 UTC
  • mfrom: (55.813.3 upstream)
  • Revision ID: didier.roche@canonical.com-20110721161759-osmh94x428t2bf2b
* New upstream release.
* debian/control:
  - build-dep on libnotify-dev
  - bump libnux-1.0-dev dep for ABI break

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
 
38
38
namespace nux
39
39
{
40
 
  NUX_IMPLEMENT_OBJECT_TYPE (Tooltip);
41
 
  
42
 
  Tooltip::Tooltip ()
43
 
  {
44
 
    _name = g_strdup ("Tooltip");
45
 
    _texture_bg = 0;
46
 
    _texture_mask = 0;
47
 
    _texture_outline = 0;
48
 
    _cairo_text_has_changed = true;
49
 
 
50
 
    _anchorX   = 0;
51
 
    _anchorY   = 0;
52
 
    _labelText = TEXT ("Unity");
53
 
 
54
 
    _anchor_width   = 10;
55
 
    _anchor_height  = 18;
56
 
    _corner_radius  = 4;
57
 
    _padding        = 15;
58
 
    _top_size       = 4;
59
 
 
60
 
    _hlayout         = new nux::HLayout (TEXT(""), NUX_TRACKER_LOCATION);
61
 
    _vlayout         = new nux::VLayout (TEXT(""), NUX_TRACKER_LOCATION);
62
 
 
63
 
    _left_space = new nux::SpaceLayout (_padding + _anchor_width + _corner_radius, _padding + _anchor_width + _corner_radius, 1, 1000);
64
 
    _right_space = new nux::SpaceLayout (_padding + _corner_radius, _padding + _corner_radius, 1, 1000);
65
 
 
66
 
    _top_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
67
 
    _bottom_space = new nux::SpaceLayout (1, 1000, _padding + _corner_radius, _padding + _corner_radius);
68
 
 
69
 
    _vlayout->AddLayout(_top_space, 0);
70
 
 
71
 
    _tooltip_text = new nux::StaticCairoText (_labelText.GetTCharPtr (), NUX_TRACKER_LOCATION);
72
 
    _on_text_changed_connection = (sigc::connection) _tooltip_text->sigTextChanged.connect (sigc::mem_fun (this, &Tooltip::RecvCairoTextChanged));
73
 
    _on_font_changed_connection = (sigc::connection) _tooltip_text->sigFontChanged.connect (sigc::mem_fun (this, &Tooltip::RecvCairoTextChanged));
74
 
    _tooltip_text->Reference();
75
 
    
76
 
    _vlayout->AddView(_tooltip_text, 1, eCenter, eFull);
77
 
 
78
 
    _vlayout->AddLayout(_bottom_space, 0);
79
 
 
80
 
    _hlayout->AddLayout(_left_space, 0);
81
 
    _hlayout->AddLayout(_vlayout, 1, eCenter, eFull);
82
 
    _hlayout->AddLayout(_right_space, 0);
83
 
 
84
 
    SetWindowSizeMatchLayout (true);
85
 
    SetLayout (_hlayout);
86
 
  
87
 
  }
88
 
 
89
 
  Tooltip::~Tooltip ()
90
 
  {
91
 
    if (_name)
92
 
      g_free (_name);
93
 
    
94
 
    if (_texture_bg)
95
 
      _texture_bg->UnReference ();
96
 
 
97
 
    if (_on_text_changed_connection.connected ())
98
 
      _on_text_changed_connection.disconnect ();
99
 
 
100
 
    if (_on_font_changed_connection.connected ())
101
 
      _on_font_changed_connection.disconnect ();
102
 
 
103
 
    _tooltip_text->UnReference();
104
 
  }
105
 
 
106
 
  long Tooltip::ProcessEvent (IEvent& ievent, long TraverseInfo, long ProcessEventInfo)
107
 
  {
108
 
    long ret = TraverseInfo;
109
 
 
110
 
    _tooltip_text->ProcessEvent(ievent, ret, ProcessEventInfo);
111
 
    
112
 
    return ret;
113
 
  }
114
 
  
115
 
  void Tooltip::ShowTooltipWithTipAt (int anchor_tip_x, int anchor_tip_y)
116
 
  {
117
 
    _anchorX = anchor_tip_x;
118
 
    _anchorY = anchor_tip_y;
119
 
 
120
 
    int x = _anchorX - _padding;
121
 
    int y = anchor_tip_y - _anchor_height/2 - _top_size - _corner_radius - _padding;
122
 
 
123
 
    SetBaseX (x);
124
 
    SetBaseY (y);
125
 
 
126
 
    PushToFront ();
127
 
 
128
 
    ShowWindow (true);
129
 
    UBusServer *ubus = ubus_server_get_default ();
130
 
    ubus_server_send_message (ubus, UBUS_TOOLTIP_SHOWN, NULL);
131
 
  }
132
 
 
133
 
  void Tooltip::Draw (GraphicsEngine& gfxContext, bool forceDraw)
134
 
  {
135
 
    Geometry base = GetGeometry();
136
 
 
137
 
    // the elements position inside the window are referenced to top-left window
138
 
    // corner. So bring base to (0, 0).
139
 
    base.SetX (0);
140
 
    base.SetY (0);
141
 
    gfxContext.PushClippingRectangle (base);
142
 
 
143
 
    GetGraphicsEngine().GetRenderStates().SetBlend (false);
144
 
 
145
 
    TexCoordXForm texxform_bg;
146
 
    texxform_bg.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
147
 
    texxform_bg.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
148
 
 
149
 
    TexCoordXForm texxform_mask;
150
 
    texxform_mask.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
151
 
    texxform_mask.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
152
 
 
153
 
 
154
 
    gfxContext.QRP_2TexMod (base.x,
155
 
      base.y,
156
 
      base.width,
157
 
      base.height,
158
 
      _texture_bg->GetDeviceTexture(),
159
 
      texxform_bg,
160
 
      Color(1.0f, 1.0f, 1.0f, 1.0f),
161
 
      _texture_mask->GetDeviceTexture(),
162
 
      texxform_mask,
163
 
      Color(1.0f, 1.0f, 1.0f, 1.0f));
164
 
 
165
 
 
166
 
    TexCoordXForm texxform;
167
 
    texxform.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
168
 
    texxform.SetTexCoordType (TexCoordXForm::OFFSET_COORD);
169
 
 
170
 
    GetGraphicsEngine ().GetRenderStates ().SetBlend (true);
171
 
    GetGraphicsEngine ().GetRenderStates ().SetPremultipliedBlend (nux::SRC_OVER);
172
 
    gfxContext.QRP_1Tex (base.x,
173
 
      base.y,
174
 
      base.width,
175
 
      base.height,
176
 
      _texture_outline->GetDeviceTexture(),
177
 
      texxform,
178
 
      Color(1.0f, 1.0f, 1.0f, 1.0f));
179
 
 
180
 
    GetGraphicsEngine().GetRenderStates().SetBlend (false);
181
 
 
182
 
    _tooltip_text->ProcessDraw(gfxContext, forceDraw);
183
 
    
184
 
    gfxContext.PopClippingRectangle ();
185
 
  }
186
 
 
187
 
  void Tooltip::DrawContent (GraphicsEngine& GfxContext, bool force_draw)
188
 
  {
189
 
 
190
 
  }
191
 
 
192
 
  void Tooltip::PreLayoutManagement ()
193
 
  {
194
 
    int MaxItemWidth = 0;
195
 
    int TotalItemHeight = 0;
196
 
    int  textWidth  = 0;
197
 
    int  textHeight = 0;
198
 
    
199
 
    _tooltip_text->GetTextExtents(textWidth, textHeight);
200
 
    
201
 
    if (textWidth > MaxItemWidth)
202
 
      MaxItemWidth = textWidth;
203
 
    TotalItemHeight += textHeight;
204
 
 
205
 
 
206
 
    if(TotalItemHeight < _anchor_height)
207
 
    {
208
 
      _top_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 + _padding + _corner_radius);
209
 
      _bottom_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight)/2 +1 + _padding + _corner_radius);
210
 
    }
211
 
 
212
 
    BaseWindow::PreLayoutManagement ();
213
 
  }
214
 
 
215
 
  long Tooltip::PostLayoutManagement (long LayoutResult)
216
 
  {
217
 
    long result = BaseWindow::PostLayoutManagement (LayoutResult);
218
 
    UpdateTexture ();
219
 
 
220
 
    return result;
221
 
  }
222
 
 
223
 
  void Tooltip::RecvCairoTextChanged (StaticCairoText* cairo_text)
224
 
  {
225
 
    _cairo_text_has_changed = true;
226
 
  }
227
 
 
228
 
/////////////////////////////////////////////////////////////////////////////////////////////////
229
 
/////////////////////////////////////////////////////////////////////////////////////////////////
230
 
/////////////////////////////////////////////////////////////////////////////////////////////////
231
 
    
232
 
  void tint_dot_hl (cairo_t* cr,
233
 
    gint    width,
234
 
    gint    height,
235
 
    gfloat  hl_x,
236
 
    gfloat  hl_y,
237
 
    gfloat  hl_size,
238
 
    gfloat* rgba_tint,
239
 
    gfloat* rgba_hl,
240
 
    gfloat* rgba_dot)
241
 
  {
242
 
    // clear normal context
243
 
    cairo_scale (cr, 1.0f, 1.0f);
244
 
    cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
245
 
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
246
 
    cairo_paint (cr);
247
 
 
248
 
    // prepare drawing for normal context
249
 
    cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
250
 
 
251
 
    // create path in normal context
252
 
    cairo_rectangle (cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);  
253
 
 
254
 
    // fill path of normal context with tint
255
 
    cairo_set_source_rgba (cr,
256
 
      rgba_tint[0],
257
 
      rgba_tint[1],
258
 
      rgba_tint[2],
259
 
      rgba_tint[3]);
260
 
    cairo_fill (cr);
261
 
  }
262
 
 
263
 
  void _setup (cairo_surface_t** surf,
264
 
    cairo_t**         cr,
265
 
    gboolean          outline,
266
 
    gint              width,
267
 
    gint              height,
268
 
    gboolean          negative)
269
 
  {
270
 
    // clear context
271
 
    cairo_scale (*cr, 1.0f, 1.0f);
272
 
    if (outline)
273
 
    {
274
 
      cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
275
 
      cairo_set_operator (*cr, CAIRO_OPERATOR_CLEAR);
276
 
    }  
277
 
    else
278
 
    {
279
 
      cairo_set_operator (*cr, CAIRO_OPERATOR_OVER);
280
 
      if (negative)
281
 
        cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
282
 
      else
283
 
        cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
284
 
    }
285
 
    cairo_paint (*cr);
286
 
  }
287
 
 
288
 
  void _compute_full_mask_path (cairo_t* cr,
289
 
    gfloat   anchor_width,
290
 
    gfloat   anchor_height,
291
 
    gint     width,
292
 
    gint     height,
293
 
    gint     upper_size,
294
 
    gfloat   radius,
295
 
    guint    pad)
296
 
  {
297
 
    //     0  1        2  3
298
 
    //     +--+--------+--+
299
 
    //     |              |
300
 
    //     + 14           + 4
301
 
    //     |              |
302
 
    //     |              |
303
 
    //     |              |
304
 
    //     + 13           |
305
 
    //    /               |
306
 
    //   /                |
307
 
    //  + 12              |
308
 
    //   \                |
309
 
    //    \               |
310
 
    //  11 +              |
311
 
    //     |              |
312
 
    //     |              |
313
 
    //     |              |
314
 
    //  10 +              + 5
315
 
    //     |              |
316
 
    //     +--+--------+--+ 6
317
 
    //     9  8        7
318
 
 
319
 
 
320
 
    gfloat padding  = pad;
321
 
    int ZEROPOINT5 = 0.0f;
322
 
 
323
 
    gfloat HeightToAnchor = 0.0f;
324
 
    HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
325
 
    if (HeightToAnchor < 0.0f)
326
 
    {
327
 
      g_warning ("Anchor-height and corner-radius a higher than whole texture!");
328
 
      return;
329
 
    }
330
 
 
331
 
    if(upper_size >= 0)
332
 
    {
333
 
      if(upper_size > height - 2.0f * radius - anchor_height -2 * padding)
334
 
      {
335
 
        //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
336
 
        HeightToAnchor = 0;
337
 
      }
338
 
      else
339
 
      {
340
 
        HeightToAnchor = height - 2.0f * radius - anchor_height -2 * padding - upper_size;
341
 
      }
342
 
    }
343
 
    else
344
 
    {
345
 
      HeightToAnchor = (height - 2.0f * radius - anchor_height -2*padding) / 2.0f;
346
 
    }
347
 
 
348
 
    cairo_translate (cr, -0.5f, -0.5f);
349
 
 
350
 
    // create path
351
 
    cairo_move_to (cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5); // Point 1
352
 
    cairo_line_to (cr, width - padding - radius, padding + ZEROPOINT5);   // Point 2
353
 
    cairo_arc (cr,
354
 
      width  - padding - radius + ZEROPOINT5,
355
 
      padding + radius + ZEROPOINT5,
356
 
      radius,
357
 
      -90.0f * G_PI / 180.0f,
358
 
      0.0f * G_PI / 180.0f);   // Point 4
359
 
    cairo_line_to (cr,
360
 
      (gdouble) width - padding + ZEROPOINT5,
361
 
      (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
362
 
    cairo_arc (cr,
363
 
      (gdouble) width - padding - radius + ZEROPOINT5,
364
 
      (gdouble) height - padding - radius + ZEROPOINT5,
365
 
      radius,
366
 
      0.0f * G_PI / 180.0f,
367
 
      90.0f * G_PI / 180.0f);  // Point 7
368
 
    cairo_line_to (cr,
369
 
      anchor_width + padding + radius + ZEROPOINT5,
370
 
      (gdouble) height - padding + ZEROPOINT5); // Point 8
371
 
 
372
 
    cairo_arc (cr,
373
 
      anchor_width + padding + radius + ZEROPOINT5,
374
 
      (gdouble) height - padding - radius,
375
 
      radius,
376
 
      90.0f * G_PI / 180.0f,
377
 
      180.0f * G_PI / 180.0f); // Point 10
378
 
 
379
 
    cairo_line_to (cr,
380
 
      padding + anchor_width + ZEROPOINT5,
381
 
      (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5 );  // Point 11
382
 
    cairo_line_to (cr,
383
 
      padding + ZEROPOINT5,
384
 
      (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
385
 
    cairo_line_to (cr,
386
 
      padding + anchor_width + ZEROPOINT5,
387
 
      (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5);  // Point 13
388
 
 
389
 
    cairo_line_to (cr, padding + anchor_width + ZEROPOINT5, padding + radius  + ZEROPOINT5);  // Point 14
390
 
    cairo_arc (cr,
391
 
      padding + anchor_width + radius + ZEROPOINT5,
392
 
      padding + radius + ZEROPOINT5,
393
 
      radius,
394
 
      180.0f * G_PI / 180.0f,
395
 
      270.0f * G_PI / 180.0f);
396
 
 
397
 
    cairo_close_path (cr);
398
 
  }
399
 
 
400
 
  void compute_mask (cairo_t* cr)
401
 
  {
402
 
    cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
403
 
    cairo_fill_preserve (cr);
404
 
  }
405
 
 
406
 
  void compute_outline (cairo_t* cr,
407
 
    gfloat   line_width,
408
 
    gfloat*  rgba_line)
409
 
  {
410
 
    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
411
 
    cairo_set_source_rgba (cr,
412
 
      rgba_line[0],
413
 
      rgba_line[1],
414
 
      rgba_line[2],
415
 
      rgba_line[3]);
416
 
    cairo_set_line_width (cr, line_width);
417
 
    cairo_stroke (cr);
418
 
  }
419
 
 
420
 
  void _draw (cairo_t* cr,
421
 
    gboolean outline,
422
 
    gfloat   line_width,
423
 
    gfloat*  rgba,
424
 
    gboolean negative,
425
 
    gboolean stroke)
426
 
  {
427
 
    // prepare drawing
428
 
    cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
429
 
 
430
 
    // actually draw the mask
431
 
    if (outline)
432
 
    {
433
 
      cairo_set_line_width (cr, line_width);
434
 
      cairo_set_source_rgba (cr, rgba[0], rgba[1], rgba[2], rgba[3]);
435
 
    }
436
 
    else
437
 
    {
438
 
      if (negative)
439
 
        cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
440
 
      else
441
 
        cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f);
442
 
    }
443
 
 
444
 
    // stroke or fill?
445
 
    if (stroke)
446
 
      cairo_stroke_preserve (cr);
447
 
    else
448
 
      cairo_fill_preserve (cr);
449
 
  }
450
 
 
451
 
  void _finalize (cairo_t** cr,
452
 
    gboolean  outline,
453
 
    gfloat    line_width,
454
 
    gfloat*   rgba,
455
 
    gboolean  negative,
456
 
    gboolean  stroke)
457
 
  {
458
 
    // prepare drawing
459
 
    cairo_set_operator (*cr, CAIRO_OPERATOR_SOURCE);
460
 
 
461
 
    // actually draw the mask
462
 
    if (outline)
463
 
    {
464
 
      cairo_set_line_width (*cr, line_width);
465
 
      cairo_set_source_rgba (*cr, rgba[0], rgba[1], rgba[2], rgba[3]);
466
 
    }
467
 
    else
468
 
    {
469
 
      if (negative)
470
 
        cairo_set_source_rgba (*cr, 1.0f, 1.0f, 1.0f, 1.0f);
471
 
      else
472
 
        cairo_set_source_rgba (*cr, 0.0f, 0.0f, 0.0f, 0.0f);
473
 
    }
474
 
 
475
 
    // stroke or fill?
476
 
    if (stroke)
477
 
      cairo_stroke (*cr);
478
 
    else
479
 
      cairo_fill (*cr);
480
 
  }
481
 
 
482
 
  void
483
 
    compute_full_outline_shadow (
484
 
    cairo_t* cr,
485
 
    cairo_surface_t* surf,
486
 
    gint    width,
487
 
    gint    height,
488
 
    gfloat  anchor_width,
489
 
    gfloat  anchor_height,
490
 
    gint    upper_size,
491
 
    gfloat  corner_radius,
492
 
    guint   blur_coeff,
493
 
    gfloat* rgba_shadow,
494
 
    gfloat  line_width,
495
 
    gint    padding_size,
496
 
    gfloat* rgba_line)
497
 
  {
498
 
    _setup (&surf, &cr, TRUE, width, height, FALSE);
499
 
    _compute_full_mask_path (cr,
500
 
      anchor_width,
501
 
      anchor_height,
502
 
      width,
503
 
      height,
504
 
      upper_size,
505
 
      corner_radius,
506
 
      padding_size);
507
 
 
508
 
    _draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
509
 
    CairoGraphics* dummy = new CairoGraphics (CAIRO_FORMAT_A1, 1, 1);
510
 
    dummy->BlurSurface (blur_coeff, surf);
511
 
    delete dummy;
512
 
    compute_mask (cr);
513
 
  }
514
 
 
515
 
  void compute_full_mask (
516
 
    cairo_t* cr,
517
 
    cairo_surface_t* surf,
518
 
    gint     width,
519
 
    gint     height,
520
 
    gfloat   radius,
521
 
    guint    shadow_radius,
522
 
    gfloat   anchor_width,
523
 
    gfloat   anchor_height,
524
 
    gint     upper_size,
525
 
    gboolean negative,
526
 
    gboolean outline,
527
 
    gfloat   line_width,
528
 
    gint     padding_size,
529
 
    gfloat*  rgba)
530
 
  {
531
 
    _setup (&surf, &cr, outline, width, height, negative);
532
 
    _compute_full_mask_path (cr,
533
 
      anchor_width,
534
 
      anchor_height,
535
 
      width,
536
 
      height,
537
 
      upper_size,
538
 
      radius,
539
 
      padding_size);
540
 
    _finalize (&cr, outline, line_width, rgba, negative, outline);
541
 
  }
542
 
 
543
 
  void Tooltip::UpdateTexture ()
544
 
  {
545
 
    if (_cairo_text_has_changed == false)
546
 
      return;
547
 
 
548
 
    int height = GetBaseHeight ();
549
 
    
550
 
    _top_size = 0;
551
 
    int x = _anchorX - _padding;
552
 
    int y = _anchorY - height/2;
553
 
 
554
 
    SetBaseX (x);
555
 
    SetBaseY (y);
556
 
 
557
 
    float blur_coef         = 6.0f;
558
 
 
559
 
    CairoGraphics* cairo_bg       = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
560
 
    CairoGraphics* cairo_mask     = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
561
 
    CairoGraphics* cairo_outline  = new CairoGraphics (CAIRO_FORMAT_ARGB32, GetBaseWidth (), GetBaseHeight ());
562
 
 
563
 
    cairo_t *cr_bg      = cairo_bg->GetContext ();
564
 
    cairo_t *cr_mask    = cairo_mask->GetContext ();
565
 
    cairo_t *cr_outline = cairo_outline->GetContext ();
566
 
 
567
 
    float   tint_color[4]    = {0.074f, 0.074f, 0.074f, 0.80f};
568
 
    float   hl_color[4]      = {1.0f, 1.0f, 1.0f, 0.15f};
569
 
    float   dot_color[4]     = {1.0f, 1.0f, 1.0f, 0.20f};
570
 
    float   shadow_color[4]  = {0.0f, 0.0f, 0.0f, 1.00f};
571
 
    float   outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
572
 
    float   mask_color[4]    = {1.0f, 1.0f, 1.0f, 1.00f};
573
 
 
574
 
    tint_dot_hl (cr_bg,
575
 
      GetBaseWidth (),
576
 
      GetBaseHeight (),
577
 
      GetBaseWidth () / 2.0f,
578
 
      0,
579
 
      Max<float>(GetBaseWidth () / 1.3f, GetBaseHeight () / 1.3f),
580
 
      tint_color,
581
 
      hl_color,
582
 
      dot_color);
583
 
 
584
 
    compute_full_outline_shadow
585
 
      (
586
 
      cr_outline,
587
 
      cairo_outline->GetSurface(),
588
 
      GetBaseWidth (),
589
 
      GetBaseHeight (),
590
 
      _anchor_width,
591
 
      _anchor_height,
592
 
      -1,
593
 
      _corner_radius,
594
 
      blur_coef,
595
 
      shadow_color,
596
 
      1.0f,
597
 
      _padding,
598
 
      outline_color);
599
 
 
600
 
    compute_full_mask (
601
 
      cr_mask,
602
 
      cairo_mask->GetSurface(),
603
 
      GetBaseWidth (),
604
 
      GetBaseHeight(),
605
 
      _corner_radius, // radius,
606
 
      16,             // shadow_radius,
607
 
      _anchor_width,  // anchor_width,
608
 
      _anchor_height, // anchor_height,
609
 
      -1,             // upper_size,
610
 
      true,           // negative,
611
 
      false,          // outline,
612
 
      1.0,            // line_width,
613
 
      _padding,       // padding_size,
614
 
      mask_color);
615
 
 
616
 
    cairo_destroy (cr_bg);
617
 
    cairo_destroy (cr_outline);
618
 
    cairo_destroy (cr_mask);
619
 
 
620
 
    NBitmapData* bitmap = cairo_bg->GetBitmap();
621
 
 
622
 
    if (_texture_bg)
623
 
      _texture_bg->UnReference ();
624
 
    _texture_bg = GetGraphicsDisplay ()->GetGpuDevice ()->CreateSystemCapableTexture ();
625
 
    _texture_bg->Update(bitmap);
626
 
    delete bitmap;
627
 
 
628
 
    bitmap = cairo_mask->GetBitmap();
629
 
    if (_texture_mask)
630
 
      _texture_mask->UnReference ();
631
 
    _texture_mask = GetGraphicsDisplay ()->GetGpuDevice ()->CreateSystemCapableTexture ();
632
 
    _texture_mask->Update(bitmap);
633
 
    delete bitmap;
634
 
 
635
 
    bitmap = cairo_outline->GetBitmap();
636
 
    if (_texture_outline)
637
 
      _texture_outline->UnReference ();
638
 
    _texture_outline = GetGraphicsDisplay ()->GetGpuDevice ()->CreateSystemCapableTexture ();
639
 
    _texture_outline->Update(bitmap);
640
 
    delete bitmap;
641
 
 
642
 
    delete cairo_bg;
643
 
    delete cairo_mask;
644
 
    delete cairo_outline;
645
 
    _cairo_text_has_changed = false;
646
 
  }
647
 
 
648
 
  void Tooltip::PositionChildLayout (float offsetX,
649
 
                                float offsetY)
650
 
  {
651
 
  }
652
 
 
653
 
  void Tooltip::LayoutWindowElements ()
654
 
  {
655
 
  }
656
 
 
657
 
  void Tooltip::NotifyConfigurationChange (int width,
658
 
                                      int height)
659
 
  {
660
 
  }
661
 
 
662
 
  void Tooltip::SetText (NString text)
663
 
  {
664
 
    if (_labelText == text)
665
 
      return;
666
 
 
667
 
    _labelText = text;
668
 
    _tooltip_text->SetText (_labelText);
669
 
    QueueRelayout ();
670
 
  }
671
 
 
672
 
  // Introspection
673
 
 
674
 
  const gchar* Tooltip::GetName ()
675
 
  {
676
 
    return g_strdup (_name);
677
 
  }
678
 
 
679
 
  void Tooltip::AddProperties (GVariantBuilder *builder)
680
 
  {
681
 
    g_variant_builder_add (builder, "{sv}", "text", g_variant_new_string (_labelText.GetTCharPtr ()));
682
 
    g_variant_builder_add (builder, "{sv}", "x", g_variant_new_int32  (GetBaseX ()));
683
 
    g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32  (GetBaseY ()));
684
 
    g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (GetBaseWidth ()));
685
 
    g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (GetBaseHeight ()));
686
 
    g_variant_builder_add (builder, "{sv}", "active", g_variant_new_boolean (IsVisible ()));
687
 
  }
 
40
NUX_IMPLEMENT_OBJECT_TYPE(Tooltip);
 
41
 
 
42
Tooltip::Tooltip()
 
43
{
 
44
  _name = g_strdup("Tooltip");
 
45
  _texture_bg = 0;
 
46
  _texture_mask = 0;
 
47
  _texture_outline = 0;
 
48
  _cairo_text_has_changed = true;
 
49
 
 
50
  _anchorX   = 0;
 
51
  _anchorY   = 0;
 
52
  _labelText = TEXT("Unity");
 
53
 
 
54
  _anchor_width   = 10;
 
55
  _anchor_height  = 18;
 
56
  _corner_radius  = 4;
 
57
  _padding        = 15;
 
58
  _top_size       = 4;
 
59
 
 
60
  _hlayout         = new nux::HLayout(TEXT(""), NUX_TRACKER_LOCATION);
 
61
  _vlayout         = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION);
 
62
 
 
63
  _left_space = new nux::SpaceLayout(_padding + _anchor_width + _corner_radius, _padding + _anchor_width + _corner_radius, 1, 1000);
 
64
  _right_space = new nux::SpaceLayout(_padding + _corner_radius, _padding + _corner_radius, 1, 1000);
 
65
 
 
66
  _top_space = new nux::SpaceLayout(1, 1000, _padding + _corner_radius, _padding + _corner_radius);
 
67
  _bottom_space = new nux::SpaceLayout(1, 1000, _padding + _corner_radius, _padding + _corner_radius);
 
68
 
 
69
  _vlayout->AddLayout(_top_space, 0);
 
70
 
 
71
  _tooltip_text = new nux::StaticCairoText(_labelText.GetTCharPtr(), NUX_TRACKER_LOCATION);
 
72
  _tooltip_text->sigTextChanged.connect(sigc::mem_fun(this, &Tooltip::RecvCairoTextChanged));
 
73
  _tooltip_text->sigFontChanged.connect(sigc::mem_fun(this, &Tooltip::RecvCairoTextChanged));
 
74
  _tooltip_text->Reference();
 
75
 
 
76
  _vlayout->AddView(_tooltip_text, 1, eCenter, eFull);
 
77
 
 
78
  _vlayout->AddLayout(_bottom_space, 0);
 
79
 
 
80
  _hlayout->AddLayout(_left_space, 0);
 
81
  _hlayout->AddLayout(_vlayout, 1, eCenter, eFull);
 
82
  _hlayout->AddLayout(_right_space, 0);
 
83
 
 
84
  SetWindowSizeMatchLayout(true);
 
85
  SetLayout(_hlayout);
 
86
 
 
87
}
 
88
 
 
89
Tooltip::~Tooltip()
 
90
{
 
91
  if (_name)
 
92
    g_free(_name);
 
93
 
 
94
  if (_texture_bg)
 
95
    _texture_bg->UnReference();
 
96
 
 
97
  _tooltip_text->UnReference();
 
98
}
 
99
 
 
100
long Tooltip::ProcessEvent(IEvent& ievent, long TraverseInfo, long ProcessEventInfo)
 
101
{
 
102
  long ret = TraverseInfo;
 
103
 
 
104
  _tooltip_text->ProcessEvent(ievent, ret, ProcessEventInfo);
 
105
 
 
106
  return ret;
 
107
}
 
108
 
 
109
void Tooltip::ShowTooltipWithTipAt(int anchor_tip_x, int anchor_tip_y)
 
110
{
 
111
  _anchorX = anchor_tip_x;
 
112
  _anchorY = anchor_tip_y;
 
113
 
 
114
  int x = _anchorX - _padding;
 
115
  int y = anchor_tip_y - _anchor_height / 2 - _top_size - _corner_radius - _padding;
 
116
 
 
117
  SetBaseX(x);
 
118
  SetBaseY(y);
 
119
 
 
120
  PushToFront();
 
121
 
 
122
  ShowWindow(true);
 
123
  UBusServer* ubus = ubus_server_get_default();
 
124
  ubus_server_send_message(ubus, UBUS_TOOLTIP_SHOWN, NULL);
 
125
}
 
126
 
 
127
void Tooltip::Draw(GraphicsEngine& gfxContext, bool forceDraw)
 
128
{
 
129
  Geometry base = GetGeometry();
 
130
 
 
131
  // the elements position inside the window are referenced to top-left window
 
132
  // corner. So bring base to (0, 0).
 
133
  base.SetX(0);
 
134
  base.SetY(0);
 
135
  gfxContext.PushClippingRectangle(base);
 
136
 
 
137
  GetGraphicsEngine().GetRenderStates().SetBlend(false);
 
138
 
 
139
  TexCoordXForm texxform_bg;
 
140
  texxform_bg.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
 
141
  texxform_bg.SetTexCoordType(TexCoordXForm::OFFSET_COORD);
 
142
 
 
143
  TexCoordXForm texxform_mask;
 
144
  texxform_mask.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
 
145
  texxform_mask.SetTexCoordType(TexCoordXForm::OFFSET_COORD);
 
146
 
 
147
 
 
148
  gfxContext.QRP_2TexMod(base.x,
 
149
                         base.y,
 
150
                         base.width,
 
151
                         base.height,
 
152
                         _texture_bg->GetDeviceTexture(),
 
153
                         texxform_bg,
 
154
                         Color(1.0f, 1.0f, 1.0f, 1.0f),
 
155
                         _texture_mask->GetDeviceTexture(),
 
156
                         texxform_mask,
 
157
                         Color(1.0f, 1.0f, 1.0f, 1.0f));
 
158
 
 
159
 
 
160
  TexCoordXForm texxform;
 
161
  texxform.SetWrap(TEXWRAP_CLAMP, TEXWRAP_CLAMP);
 
162
  texxform.SetTexCoordType(TexCoordXForm::OFFSET_COORD);
 
163
 
 
164
  GetGraphicsEngine().GetRenderStates().SetBlend(true);
 
165
  GetGraphicsEngine().GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
 
166
  gfxContext.QRP_1Tex(base.x,
 
167
                      base.y,
 
168
                      base.width,
 
169
                      base.height,
 
170
                      _texture_outline->GetDeviceTexture(),
 
171
                      texxform,
 
172
                      Color(1.0f, 1.0f, 1.0f, 1.0f));
 
173
 
 
174
  GetGraphicsEngine().GetRenderStates().SetBlend(false);
 
175
 
 
176
  _tooltip_text->ProcessDraw(gfxContext, forceDraw);
 
177
 
 
178
  gfxContext.PopClippingRectangle();
 
179
}
 
180
 
 
181
void Tooltip::DrawContent(GraphicsEngine& GfxContext, bool force_draw)
 
182
{
 
183
 
 
184
}
 
185
 
 
186
void Tooltip::PreLayoutManagement()
 
187
{
 
188
  int MaxItemWidth = 0;
 
189
  int TotalItemHeight = 0;
 
190
  int  textWidth  = 0;
 
191
  int  textHeight = 0;
 
192
 
 
193
  _tooltip_text->GetTextExtents(textWidth, textHeight);
 
194
 
 
195
  if (textWidth > MaxItemWidth)
 
196
    MaxItemWidth = textWidth;
 
197
  TotalItemHeight += textHeight;
 
198
 
 
199
 
 
200
  if (TotalItemHeight < _anchor_height)
 
201
  {
 
202
    _top_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight) / 2 + _padding + _corner_radius);
 
203
    _bottom_space->SetMinMaxSize(1, (_anchor_height - TotalItemHeight) / 2 + 1 + _padding + _corner_radius);
 
204
  }
 
205
 
 
206
  BaseWindow::PreLayoutManagement();
 
207
}
 
208
 
 
209
long Tooltip::PostLayoutManagement(long LayoutResult)
 
210
{
 
211
  long result = BaseWindow::PostLayoutManagement(LayoutResult);
 
212
  UpdateTexture();
 
213
 
 
214
  return result;
 
215
}
 
216
 
 
217
void Tooltip::RecvCairoTextChanged(StaticCairoText* cairo_text)
 
218
{
 
219
  _cairo_text_has_changed = true;
 
220
}
 
221
 
 
222
/////////////////////////////////////////////////////////////////////////////////////////////////
 
223
/////////////////////////////////////////////////////////////////////////////////////////////////
 
224
/////////////////////////////////////////////////////////////////////////////////////////////////
 
225
 
 
226
void tint_dot_hl(cairo_t* cr,
 
227
                 gint    width,
 
228
                 gint    height,
 
229
                 gfloat  hl_x,
 
230
                 gfloat  hl_y,
 
231
                 gfloat  hl_size,
 
232
                 gfloat* rgba_tint,
 
233
                 gfloat* rgba_hl,
 
234
                 gfloat* rgba_dot)
 
235
{
 
236
  // clear normal context
 
237
  cairo_scale(cr, 1.0f, 1.0f);
 
238
  cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
239
  cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
 
240
  cairo_paint(cr);
 
241
 
 
242
  // prepare drawing for normal context
 
243
  cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
 
244
 
 
245
  // create path in normal context
 
246
  cairo_rectangle(cr, 0.0f, 0.0f, (gdouble) width, (gdouble) height);
 
247
 
 
248
  // fill path of normal context with tint
 
249
  cairo_set_source_rgba(cr,
 
250
                        rgba_tint[0],
 
251
                        rgba_tint[1],
 
252
                        rgba_tint[2],
 
253
                        rgba_tint[3]);
 
254
  cairo_fill(cr);
 
255
}
 
256
 
 
257
void _setup(cairo_surface_t** surf,
 
258
            cairo_t**         cr,
 
259
            gboolean          outline,
 
260
            gint              width,
 
261
            gint              height,
 
262
            gboolean          negative)
 
263
{
 
264
  // clear context
 
265
  cairo_scale(*cr, 1.0f, 1.0f);
 
266
  if (outline)
 
267
  {
 
268
    cairo_set_source_rgba(*cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
269
    cairo_set_operator(*cr, CAIRO_OPERATOR_CLEAR);
 
270
  }
 
271
  else
 
272
  {
 
273
    cairo_set_operator(*cr, CAIRO_OPERATOR_OVER);
 
274
    if (negative)
 
275
      cairo_set_source_rgba(*cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
276
    else
 
277
      cairo_set_source_rgba(*cr, 1.0f, 1.0f, 1.0f, 1.0f);
 
278
  }
 
279
  cairo_paint(*cr);
 
280
}
 
281
 
 
282
void _compute_full_mask_path(cairo_t* cr,
 
283
                             gfloat   anchor_width,
 
284
                             gfloat   anchor_height,
 
285
                             gint     width,
 
286
                             gint     height,
 
287
                             gint     upper_size,
 
288
                             gfloat   radius,
 
289
                             guint    pad)
 
290
{
 
291
  //     0  1        2  3
 
292
  //     +--+--------+--+
 
293
  //     |              |
 
294
  //     + 14           + 4
 
295
  //     |              |
 
296
  //     |              |
 
297
  //     |              |
 
298
  //     + 13           |
 
299
  //    /               |
 
300
  //   /                |
 
301
  //  + 12              |
 
302
  //   \                |
 
303
  //    \               |
 
304
  //  11 +              |
 
305
  //     |              |
 
306
  //     |              |
 
307
  //     |              |
 
308
  //  10 +              + 5
 
309
  //     |              |
 
310
  //     +--+--------+--+ 6
 
311
  //     9  8        7
 
312
 
 
313
 
 
314
  gfloat padding  = pad;
 
315
  int ZEROPOINT5 = 0.0f;
 
316
 
 
317
  gfloat HeightToAnchor = 0.0f;
 
318
  HeightToAnchor = ((gfloat) height - 2.0f * radius - anchor_height - 2 * padding) / 2.0f;
 
319
  if (HeightToAnchor < 0.0f)
 
320
  {
 
321
    g_warning("Anchor-height and corner-radius a higher than whole texture!");
 
322
    return;
 
323
  }
 
324
 
 
325
  if (upper_size >= 0)
 
326
  {
 
327
    if (upper_size > height - 2.0f * radius - anchor_height - 2 * padding)
 
328
    {
 
329
      //g_warning ("[_compute_full_mask_path] incorrect upper_size value");
 
330
      HeightToAnchor = 0;
 
331
    }
 
332
    else
 
333
    {
 
334
      HeightToAnchor = height - 2.0f * radius - anchor_height - 2 * padding - upper_size;
 
335
    }
 
336
  }
 
337
  else
 
338
  {
 
339
    HeightToAnchor = (height - 2.0f * radius - anchor_height - 2 * padding) / 2.0f;
 
340
  }
 
341
 
 
342
  cairo_translate(cr, -0.5f, -0.5f);
 
343
 
 
344
  // create path
 
345
  cairo_move_to(cr, padding + anchor_width + radius + ZEROPOINT5, padding + ZEROPOINT5);  // Point 1
 
346
  cairo_line_to(cr, width - padding - radius, padding + ZEROPOINT5);    // Point 2
 
347
  cairo_arc(cr,
 
348
            width  - padding - radius + ZEROPOINT5,
 
349
            padding + radius + ZEROPOINT5,
 
350
            radius,
 
351
            -90.0f * G_PI / 180.0f,
 
352
            0.0f * G_PI / 180.0f);   // Point 4
 
353
  cairo_line_to(cr,
 
354
                (gdouble) width - padding + ZEROPOINT5,
 
355
                (gdouble) height - radius - padding + ZEROPOINT5); // Point 5
 
356
  cairo_arc(cr,
 
357
            (gdouble) width - padding - radius + ZEROPOINT5,
 
358
            (gdouble) height - padding - radius + ZEROPOINT5,
 
359
            radius,
 
360
            0.0f * G_PI / 180.0f,
 
361
            90.0f * G_PI / 180.0f);  // Point 7
 
362
  cairo_line_to(cr,
 
363
                anchor_width + padding + radius + ZEROPOINT5,
 
364
                (gdouble) height - padding + ZEROPOINT5); // Point 8
 
365
 
 
366
  cairo_arc(cr,
 
367
            anchor_width + padding + radius + ZEROPOINT5,
 
368
            (gdouble) height - padding - radius,
 
369
            radius,
 
370
            90.0f * G_PI / 180.0f,
 
371
            180.0f * G_PI / 180.0f); // Point 10
 
372
 
 
373
  cairo_line_to(cr,
 
374
                padding + anchor_width + ZEROPOINT5,
 
375
                (gdouble) height - padding - radius - HeightToAnchor + ZEROPOINT5);   // Point 11
 
376
  cairo_line_to(cr,
 
377
                padding + ZEROPOINT5,
 
378
                (gdouble) height - padding - radius - HeightToAnchor - anchor_height / 2.0f + ZEROPOINT5); // Point 12
 
379
  cairo_line_to(cr,
 
380
                padding + anchor_width + ZEROPOINT5,
 
381
                (gdouble) height - padding - radius - HeightToAnchor - anchor_height + ZEROPOINT5);  // Point 13
 
382
 
 
383
  cairo_line_to(cr, padding + anchor_width + ZEROPOINT5, padding + radius  + ZEROPOINT5);   // Point 14
 
384
  cairo_arc(cr,
 
385
            padding + anchor_width + radius + ZEROPOINT5,
 
386
            padding + radius + ZEROPOINT5,
 
387
            radius,
 
388
            180.0f * G_PI / 180.0f,
 
389
            270.0f * G_PI / 180.0f);
 
390
 
 
391
  cairo_close_path(cr);
 
392
}
 
393
 
 
394
void compute_mask(cairo_t* cr)
 
395
{
 
396
  cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
 
397
  cairo_fill_preserve(cr);
 
398
}
 
399
 
 
400
void compute_outline(cairo_t* cr,
 
401
                     gfloat   line_width,
 
402
                     gfloat*  rgba_line)
 
403
{
 
404
  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
 
405
  cairo_set_source_rgba(cr,
 
406
                        rgba_line[0],
 
407
                        rgba_line[1],
 
408
                        rgba_line[2],
 
409
                        rgba_line[3]);
 
410
  cairo_set_line_width(cr, line_width);
 
411
  cairo_stroke(cr);
 
412
}
 
413
 
 
414
void _draw(cairo_t* cr,
 
415
           gboolean outline,
 
416
           gfloat   line_width,
 
417
           gfloat*  rgba,
 
418
           gboolean negative,
 
419
           gboolean stroke)
 
420
{
 
421
  // prepare drawing
 
422
  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
 
423
 
 
424
  // actually draw the mask
 
425
  if (outline)
 
426
  {
 
427
    cairo_set_line_width(cr, line_width);
 
428
    cairo_set_source_rgba(cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
429
  }
 
430
  else
 
431
  {
 
432
    if (negative)
 
433
      cairo_set_source_rgba(cr, 1.0f, 1.0f, 1.0f, 1.0f);
 
434
    else
 
435
      cairo_set_source_rgba(cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
436
  }
 
437
 
 
438
  // stroke or fill?
 
439
  if (stroke)
 
440
    cairo_stroke_preserve(cr);
 
441
  else
 
442
    cairo_fill_preserve(cr);
 
443
}
 
444
 
 
445
void _finalize(cairo_t** cr,
 
446
               gboolean  outline,
 
447
               gfloat    line_width,
 
448
               gfloat*   rgba,
 
449
               gboolean  negative,
 
450
               gboolean  stroke)
 
451
{
 
452
  // prepare drawing
 
453
  cairo_set_operator(*cr, CAIRO_OPERATOR_SOURCE);
 
454
 
 
455
  // actually draw the mask
 
456
  if (outline)
 
457
  {
 
458
    cairo_set_line_width(*cr, line_width);
 
459
    cairo_set_source_rgba(*cr, rgba[0], rgba[1], rgba[2], rgba[3]);
 
460
  }
 
461
  else
 
462
  {
 
463
    if (negative)
 
464
      cairo_set_source_rgba(*cr, 1.0f, 1.0f, 1.0f, 1.0f);
 
465
    else
 
466
      cairo_set_source_rgba(*cr, 0.0f, 0.0f, 0.0f, 0.0f);
 
467
  }
 
468
 
 
469
  // stroke or fill?
 
470
  if (stroke)
 
471
    cairo_stroke(*cr);
 
472
  else
 
473
    cairo_fill(*cr);
 
474
}
 
475
 
 
476
void
 
477
compute_full_outline_shadow(
 
478
  cairo_t* cr,
 
479
  cairo_surface_t* surf,
 
480
  gint    width,
 
481
  gint    height,
 
482
  gfloat  anchor_width,
 
483
  gfloat  anchor_height,
 
484
  gint    upper_size,
 
485
  gfloat  corner_radius,
 
486
  guint   blur_coeff,
 
487
  gfloat* rgba_shadow,
 
488
  gfloat  line_width,
 
489
  gint    padding_size,
 
490
  gfloat* rgba_line)
 
491
{
 
492
  _setup(&surf, &cr, TRUE, width, height, FALSE);
 
493
  _compute_full_mask_path(cr,
 
494
                          anchor_width,
 
495
                          anchor_height,
 
496
                          width,
 
497
                          height,
 
498
                          upper_size,
 
499
                          corner_radius,
 
500
                          padding_size);
 
501
 
 
502
  _draw(cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
 
503
  CairoGraphics* dummy = new CairoGraphics(CAIRO_FORMAT_A1, 1, 1);
 
504
  dummy->BlurSurface(blur_coeff, surf);
 
505
  delete dummy;
 
506
  compute_mask(cr);
 
507
}
 
508
 
 
509
void compute_full_mask(
 
510
  cairo_t* cr,
 
511
  cairo_surface_t* surf,
 
512
  gint     width,
 
513
  gint     height,
 
514
  gfloat   radius,
 
515
  guint    shadow_radius,
 
516
  gfloat   anchor_width,
 
517
  gfloat   anchor_height,
 
518
  gint     upper_size,
 
519
  gboolean negative,
 
520
  gboolean outline,
 
521
  gfloat   line_width,
 
522
  gint     padding_size,
 
523
  gfloat*  rgba)
 
524
{
 
525
  _setup(&surf, &cr, outline, width, height, negative);
 
526
  _compute_full_mask_path(cr,
 
527
                          anchor_width,
 
528
                          anchor_height,
 
529
                          width,
 
530
                          height,
 
531
                          upper_size,
 
532
                          radius,
 
533
                          padding_size);
 
534
  _finalize(&cr, outline, line_width, rgba, negative, outline);
 
535
}
 
536
 
 
537
void Tooltip::UpdateTexture()
 
538
{
 
539
  if (_cairo_text_has_changed == false)
 
540
    return;
 
541
 
 
542
  int height = GetBaseHeight();
 
543
 
 
544
  _top_size = 0;
 
545
  int x = _anchorX - _padding;
 
546
  int y = _anchorY - height / 2;
 
547
 
 
548
  SetBaseX(x);
 
549
  SetBaseY(y);
 
550
 
 
551
  float blur_coef         = 6.0f;
 
552
 
 
553
  CairoGraphics* cairo_bg       = new CairoGraphics(CAIRO_FORMAT_ARGB32, GetBaseWidth(), GetBaseHeight());
 
554
  CairoGraphics* cairo_mask     = new CairoGraphics(CAIRO_FORMAT_ARGB32, GetBaseWidth(), GetBaseHeight());
 
555
  CairoGraphics* cairo_outline  = new CairoGraphics(CAIRO_FORMAT_ARGB32, GetBaseWidth(), GetBaseHeight());
 
556
 
 
557
  cairo_t* cr_bg      = cairo_bg->GetContext();
 
558
  cairo_t* cr_mask    = cairo_mask->GetContext();
 
559
  cairo_t* cr_outline = cairo_outline->GetContext();
 
560
 
 
561
  float   tint_color[4]    = {0.074f, 0.074f, 0.074f, 0.80f};
 
562
  float   hl_color[4]      = {1.0f, 1.0f, 1.0f, 0.15f};
 
563
  float   dot_color[4]     = {1.0f, 1.0f, 1.0f, 0.20f};
 
564
  float   shadow_color[4]  = {0.0f, 0.0f, 0.0f, 1.00f};
 
565
  float   outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
 
566
  float   mask_color[4]    = {1.0f, 1.0f, 1.0f, 1.00f};
 
567
 
 
568
  tint_dot_hl(cr_bg,
 
569
              GetBaseWidth(),
 
570
              GetBaseHeight(),
 
571
              GetBaseWidth() / 2.0f,
 
572
              0,
 
573
              Max<float>(GetBaseWidth() / 1.3f, GetBaseHeight() / 1.3f),
 
574
              tint_color,
 
575
              hl_color,
 
576
              dot_color);
 
577
 
 
578
  compute_full_outline_shadow
 
579
  (
 
580
    cr_outline,
 
581
    cairo_outline->GetSurface(),
 
582
    GetBaseWidth(),
 
583
    GetBaseHeight(),
 
584
    _anchor_width,
 
585
    _anchor_height,
 
586
    -1,
 
587
    _corner_radius,
 
588
    blur_coef,
 
589
    shadow_color,
 
590
    1.0f,
 
591
    _padding,
 
592
    outline_color);
 
593
 
 
594
  compute_full_mask(
 
595
    cr_mask,
 
596
    cairo_mask->GetSurface(),
 
597
    GetBaseWidth(),
 
598
    GetBaseHeight(),
 
599
    _corner_radius, // radius,
 
600
    16,             // shadow_radius,
 
601
    _anchor_width,  // anchor_width,
 
602
    _anchor_height, // anchor_height,
 
603
    -1,             // upper_size,
 
604
    true,           // negative,
 
605
    false,          // outline,
 
606
    1.0,            // line_width,
 
607
    _padding,       // padding_size,
 
608
    mask_color);
 
609
 
 
610
  cairo_destroy(cr_bg);
 
611
  cairo_destroy(cr_outline);
 
612
  cairo_destroy(cr_mask);
 
613
 
 
614
  NBitmapData* bitmap = cairo_bg->GetBitmap();
 
615
 
 
616
  if (_texture_bg)
 
617
    _texture_bg->UnReference();
 
618
  _texture_bg = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
 
619
  _texture_bg->Update(bitmap);
 
620
  delete bitmap;
 
621
 
 
622
  bitmap = cairo_mask->GetBitmap();
 
623
  if (_texture_mask)
 
624
    _texture_mask->UnReference();
 
625
  _texture_mask = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
 
626
  _texture_mask->Update(bitmap);
 
627
  delete bitmap;
 
628
 
 
629
  bitmap = cairo_outline->GetBitmap();
 
630
  if (_texture_outline)
 
631
    _texture_outline->UnReference();
 
632
  _texture_outline = GetGraphicsDisplay()->GetGpuDevice()->CreateSystemCapableTexture();
 
633
  _texture_outline->Update(bitmap);
 
634
  delete bitmap;
 
635
 
 
636
  delete cairo_bg;
 
637
  delete cairo_mask;
 
638
  delete cairo_outline;
 
639
  _cairo_text_has_changed = false;
 
640
}
 
641
 
 
642
void Tooltip::PositionChildLayout(float offsetX,
 
643
                                  float offsetY)
 
644
{
 
645
}
 
646
 
 
647
void Tooltip::LayoutWindowElements()
 
648
{
 
649
}
 
650
 
 
651
void Tooltip::NotifyConfigurationChange(int width,
 
652
                                        int height)
 
653
{
 
654
}
 
655
 
 
656
void Tooltip::SetText(NString text)
 
657
{
 
658
  if (_labelText == text)
 
659
    return;
 
660
 
 
661
  _labelText = text;
 
662
  _tooltip_text->SetText(_labelText);
 
663
  QueueRelayout();
 
664
}
 
665
 
 
666
// Introspection
 
667
 
 
668
const gchar* Tooltip::GetName()
 
669
{
 
670
  return g_strdup(_name);
 
671
}
 
672
 
 
673
void Tooltip::AddProperties(GVariantBuilder* builder)
 
674
{
 
675
  g_variant_builder_add(builder, "{sv}", "text", g_variant_new_string(_labelText.GetTCharPtr()));
 
676
  g_variant_builder_add(builder, "{sv}", "x", g_variant_new_int32(GetBaseX()));
 
677
  g_variant_builder_add(builder, "{sv}", "y", g_variant_new_int32(GetBaseY()));
 
678
  g_variant_builder_add(builder, "{sv}", "width", g_variant_new_int32(GetBaseWidth()));
 
679
  g_variant_builder_add(builder, "{sv}", "height", g_variant_new_int32(GetBaseHeight()));
 
680
  g_variant_builder_add(builder, "{sv}", "active", g_variant_new_boolean(IsVisible()));
 
681
}
688
682
 
689
683
} // namespace nux