~azzar1/unity/fix-trash-li-blocking

« back to all changes in this revision

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

  • Committer: Daniel van Vugt
  • Date: 2012-03-14 06:24:18 UTC
  • mfrom: (2108 unity)
  • mto: This revision was merged to the branch mainline in revision 2146.
  • Revision ID: daniel.van.vugt@canonical.com-20120314062418-nprucpbr0m7qky5e
MergedĀ latestĀ lp:unity

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
 
30
30
#include "StaticCairoText.h"
31
31
 
32
 
#include "Introspectable.h"
33
 
 
34
32
#include <sigc++/trackable.h>
35
33
#include <sigc++/signal.h>
36
34
#include <sigc++/functors/ptr_fun.h>
41
39
#include <glib/gi18n-lib.h>
42
40
 
43
41
#include <Nux/Utils.h>
44
 
 
 
42
#include <UnityCore/Variant.h>
45
43
#include "DashStyle.h"
46
 
 
47
 
static const nux::Color kExpandDefaultTextColor(1.0f, 1.0f, 1.0f, 0.5f);
48
 
static const nux::Color kExpandHoverTextColor(1.0f, 1.0f, 1.0f, 1.0f);
49
 
static const float kExpandDefaultIconOpacity = 0.5f;
50
 
static const float kExpandHoverIconOpacity = 1.0f;
 
44
#include "ubus-server.h"
 
45
#include "UBusMessages.h"
 
46
 #include "Introspectable.h"
51
47
 
52
48
namespace unity
53
49
{
 
50
namespace
 
51
{
 
52
 
 
53
const nux::Color kExpandDefaultTextColor(1.0f, 1.0f, 1.0f, 0.5f);
 
54
const float kExpandDefaultIconOpacity = 0.5f;
 
55
 
 
56
// Category  highlight
 
57
const int kHighlightHeight = 24;
 
58
const int kHighlightWidthSubtractor = 16;
 
59
const int kHighlightLeftPadding = 11;
 
60
 
 
61
// Line Separator
 
62
const int kSeparatorLeftPadding = 16;
 
63
const int kSeparatorWidthSubtractor = 10;
 
64
 
 
65
// Font
 
66
const char* const NAME_LABEL_FONT = "Ubuntu 13"; // 17px = 13
 
67
const char* const EXPANDER_LABEL_FONT = "Ubuntu 10"; // 13px = 10
 
68
 
 
69
class HeaderView : public nux::View
 
70
{
 
71
public:
 
72
  HeaderView(NUX_FILE_LINE_DECL)
 
73
   : nux::View(NUX_FILE_LINE_PARAM)
 
74
  {
 
75
    SetAcceptKeyNavFocusOnMouseDown(false);
 
76
    SetAcceptKeyNavFocusOnMouseEnter(true);
 
77
  }
 
78
 
 
79
protected:
 
80
  void Draw(nux::GraphicsEngine& graphics_engine, bool force_draw)
 
81
  {
 
82
  };
 
83
 
 
84
  void DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
 
85
  {
 
86
    if (GetLayout())
 
87
      GetLayout()->ProcessDraw(graphics_engine, force_draw);
 
88
  }
 
89
 
 
90
  bool AcceptKeyNavFocus()
 
91
  {
 
92
    return true;
 
93
  }
 
94
 
 
95
  nux::Area* FindAreaUnderMouse(const nux::Point& mouse_position, nux::NuxEventType event_type)
 
96
  {
 
97
    bool mouse_inside = TestMousePointerInclusionFilterMouseWheel(mouse_position, event_type);
 
98
 
 
99
    if (mouse_inside == false)
 
100
      return nullptr;
 
101
 
 
102
    return this;
 
103
  }
 
104
};
 
105
 
 
106
}
 
107
 
54
108
NUX_IMPLEMENT_OBJECT_TYPE(PlacesGroup);
55
109
 
56
110
PlacesGroup::PlacesGroup()
57
 
  : View(NUX_TRACKER_LOCATION),
58
 
    _child_view(NULL),
 
111
  : AbstractPlacesGroup(),
 
112
    _child_view(nullptr),
 
113
    _focus_layer(nullptr),
59
114
    _idle_id(0),
60
115
    _is_expanded(true),
61
116
    _n_visible_items_in_unexpand_mode(0),
62
 
    _n_total_items(0),
63
 
    _draw_sep(true)
 
117
    _n_total_items(0)
64
118
{
 
119
  SetAcceptKeyNavFocusOnMouseDown(false);
 
120
  SetAcceptKeyNavFocusOnMouseEnter(false);
 
121
 
65
122
  nux::BaseTexture* arrow = dash::Style::Instance().GetGroupUnexpandIcon();
66
123
 
67
124
  _cached_name = NULL;
68
125
  _group_layout = new nux::VLayout("", NUX_TRACKER_LOCATION);
69
 
  _group_layout->SetHorizontalExternalMargin(12);
 
126
  _group_layout->SetHorizontalExternalMargin(20);
70
127
  _group_layout->SetVerticalExternalMargin(1);
71
128
 
72
129
  _group_layout->AddLayout(new nux::SpaceLayout(15,15,15,15), 0);
73
130
 
 
131
  _header_view = new HeaderView(NUX_TRACKER_LOCATION);
 
132
  _group_layout->AddView(_header_view, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FIX);
 
133
 
74
134
  _header_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
75
135
  _header_layout->SetHorizontalInternalMargin(10);
76
 
  _group_layout->AddLayout(_header_layout, 0, nux::MINOR_POSITION_TOP, nux::MINOR_SIZE_FIX);
 
136
  _header_view->SetLayout(_header_layout);
77
137
 
78
138
  _icon = new IconTexture("", 24);
79
139
  _icon->SetMinMaxSize(24, 24);
82
142
  _text_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
83
143
  _text_layout->SetHorizontalInternalMargin(15);
84
144
  _header_layout->AddLayout(_text_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
85
 
  
 
145
 
86
146
  _name = new nux::StaticCairoText("", NUX_TRACKER_LOCATION);
 
147
  _name->SetFont(NAME_LABEL_FONT);
87
148
  _name->SetTextEllipsize(nux::StaticCairoText::NUX_ELLIPSIZE_END);
88
149
  _name->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT);
89
150
  _text_layout->AddView(_name, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
92
153
  _expand_layout->SetHorizontalInternalMargin(8);
93
154
  _text_layout->AddLayout(_expand_layout, 0, nux::MINOR_POSITION_END, nux::MINOR_SIZE_MATCHCONTENT);
94
155
 
 
156
  _expand_label_layout = new nux::HLayout(NUX_TRACKER_LOCATION);
 
157
  _expand_layout->AddLayout(_expand_label_layout, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_MATCHCONTENT);
 
158
 
95
159
  _expand_label = new nux::StaticCairoText("", NUX_TRACKER_LOCATION);
 
160
  _expand_label->SetFont(EXPANDER_LABEL_FONT);
96
161
  _expand_label->SetTextEllipsize(nux::StaticCairoText::NUX_ELLIPSIZE_END);
97
162
  _expand_label->SetTextAlignment(nux::StaticCairoText::NUX_ALIGN_LEFT);
98
163
  _expand_label->SetTextColor(kExpandDefaultTextColor);
99
 
  _expand_label->SetAcceptKeyNavFocus(true);
100
 
  _expand_label->OnKeyNavFocusActivate.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelActivated));
101
 
  _expand_label->OnKeyNavFocusChange.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged));
102
 
 
103
 
  _expand_layout->AddView(_expand_label, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
 
164
  _expand_label_layout->AddView(_expand_label, 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FIX);
104
165
 
105
166
  _expand_icon = new IconTexture(arrow, arrow->GetWidth(), arrow->GetHeight());
106
167
  _expand_icon->SetOpacity(kExpandDefaultIconOpacity);
110
171
 
111
172
  SetLayout(_group_layout);
112
173
 
113
 
  /* don't need to disconnect these signals as they are disconnected when this object destroys the contents */
 
174
  // don't need to disconnect these signals as they are disconnected when this object destroys the contents
 
175
  _header_view->mouse_click.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseClick));
 
176
  _header_view->key_nav_focus_change.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged));
 
177
  _header_view->key_nav_focus_activate.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelActivated));
114
178
  _icon->mouse_click.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseClick));
115
 
  _icon->mouse_enter.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseEnter));
116
 
  _icon->mouse_leave.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseLeave));
117
179
  _name->mouse_click.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseClick));
118
 
  _name->mouse_enter.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseEnter));
119
 
  _name->mouse_leave.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseLeave));
120
180
  _expand_label->mouse_click.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseClick));
121
 
  _expand_label->mouse_enter.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseEnter));
122
 
  _expand_label->mouse_leave.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseLeave));
123
181
  _expand_icon->mouse_click.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseClick));
124
 
  _expand_icon->mouse_enter.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseEnter));
125
 
  _expand_icon->mouse_leave.connect(sigc::mem_fun(this, &PlacesGroup::RecvMouseLeave));
 
182
 
 
183
  key_nav_focus_change.connect([&](nux::Area* area, bool has_focus, nux::KeyNavDirection direction)
 
184
  {
 
185
    if (!has_focus)
 
186
      return;
 
187
 
 
188
    if(direction == nux::KEY_NAV_UP)
 
189
      nux::GetWindowCompositor().SetKeyFocusArea(_child_view, direction);
 
190
    else
 
191
      nux::GetWindowCompositor().SetKeyFocusArea(GetHeaderFocusableView(), direction);
 
192
  });
126
193
}
127
194
 
128
195
PlacesGroup::~PlacesGroup()
132
199
 
133
200
  if (_cached_name != NULL)
134
201
    g_free(_cached_name);
 
202
 
 
203
  delete _focus_layer;
135
204
}
136
205
 
137
206
void
141
210
}
142
211
 
143
212
void
144
 
PlacesGroup::OnLabelFocusChanged(nux::Area* label)
 
213
PlacesGroup::OnLabelFocusChanged(nux::Area* label, bool has_focus, nux::KeyNavDirection direction)
145
214
{
146
 
  if (_expand_label->HasKeyFocus() || _expand_icon->HasKeyFocus())
147
 
  {
148
 
    _expand_label->SetTextColor(kExpandHoverTextColor);
149
 
    _expand_icon->SetOpacity(kExpandHoverIconOpacity);
150
 
  }
151
 
  else if (!IsMouseInside())
152
 
  {
153
 
    _expand_label->SetTextColor(kExpandDefaultTextColor);
154
 
    _expand_icon->SetOpacity(kExpandDefaultIconOpacity);
155
 
  }
 
215
  if (HeaderHasKeyFocus())
 
216
  {
 
217
    _ubus.SendMessage(UBUS_RESULT_VIEW_KEYNAV_CHANGED,
 
218
                      g_variant_new("(iiii)", 0, 0, 0, 0));
 
219
  }
 
220
 
 
221
  QueueDraw();
156
222
}
 
223
 
157
224
void
158
225
PlacesGroup::SetName(const char* name)
159
226
{
194
261
void
195
262
PlacesGroup::SetChildView(nux::View* view)
196
263
{
 
264
  debug::Introspectable *i = dynamic_cast<debug::Introspectable*>(view);
 
265
  if (i)
 
266
    AddChild(i);
197
267
  _child_view = view;
198
268
  _group_layout->AddView(_child_view, 1);
199
269
  QueueDraw();
214
284
void
215
285
PlacesGroup::RefreshLabel()
216
286
{
217
 
  const char* temp = "<span size='small'>%s</span>";
218
287
  char*       result_string;
219
 
  char*       final;
220
288
 
221
289
  if (_n_visible_items_in_unexpand_mode >= _n_total_items)
222
290
  {
241
309
  SetName(tmpname);
242
310
  g_free(tmpname);
243
311
 
244
 
  final = g_strdup_printf(temp, result_string);
245
312
 
246
 
  _expand_label->SetText(final);
 
313
  _expand_label->SetText(result_string);
247
314
  _expand_label->SetVisible(_n_visible_items_in_unexpand_mode < _n_total_items);
248
 
  _expand_label->SetAcceptKeyNavFocus((_n_visible_items_in_unexpand_mode < _n_total_items) ? true : false);
249
 
 
250
 
  if (_expand_label->IsVisible() == false)
251
 
  {
252
 
    if (_expand_icon->IsVisible())
253
 
    {
254
 
      _expand_icon->SetAcceptKeyNavFocus(true);
255
 
      _expand_icon->OnKeyNavFocusChange.connect(sigc::mem_fun(this, &PlacesGroup::OnLabelFocusChanged));
256
 
    }
257
 
  }
258
 
 
259
 
  if (_expand_icon->IsVisible() == false)
260
 
  {
261
 
    _expand_icon->SetAcceptKeyNavFocus(false);
262
 
  }
 
315
 
 
316
  // See bug #748101 ("Dash - "See more..." line should be base-aligned with section header")
 
317
  // We're making two assumptions here:
 
318
  // [a] The font size _name is bigger than the font size of _expand_label
 
319
  // [b] The bottom sides have the same y coordinate
 
320
  int bottom_padding = _name->GetBaseHeight() - _name->GetBaseline() -
 
321
                       (_expand_label->GetBaseHeight() - _expand_label->GetBaseline());
 
322
 
 
323
  _expand_label_layout->SetTopAndBottomPadding(0, bottom_padding);
263
324
 
264
325
  QueueDraw();
265
326
 
266
 
  g_free((result_string));
267
 
  g_free(final);
 
327
  g_free(result_string);
268
328
}
269
329
 
270
330
void
299
359
  return FALSE;
300
360
}
301
361
 
302
 
void PlacesGroup::Draw(nux::GraphicsEngine& GfxContext,
 
362
long PlacesGroup::ComputeContentSize()
 
363
{
 
364
  long ret = nux::View::ComputeContentSize();
 
365
 
 
366
  nux::Geometry const& geo = GetGeometry();
 
367
 
 
368
  if (_cached_geometry != geo)
 
369
  {
 
370
    if (_focus_layer)
 
371
      delete _focus_layer;
 
372
 
 
373
    _focus_layer = dash::Style::Instance().FocusOverlay(geo.width - kHighlightWidthSubtractor, kHighlightHeight);
 
374
 
 
375
    _cached_geometry = geo;
 
376
  }
 
377
 
 
378
  return ret;
 
379
}
 
380
 
 
381
void PlacesGroup::Draw(nux::GraphicsEngine& graphics_engine,
303
382
                       bool                 forceDraw)
304
383
{
305
 
  nux::Geometry base = GetGeometry();
306
 
  GfxContext.PushClippingRectangle(base);
307
 
 
308
 
  nux::Color col(0.15f, 0.15f, 0.15f, 0.15f);
309
 
 
310
 
  if (_draw_sep)
 
384
  nux::Geometry const& base = GetGeometry();
 
385
  graphics_engine.PushClippingRectangle(base);
 
386
 
 
387
  nux::GetPainter().PaintBackground(graphics_engine, base);
 
388
 
 
389
  graphics_engine.GetRenderStates().SetColorMask(true, true, true, false);
 
390
  graphics_engine.GetRenderStates().SetBlend(true);
 
391
  graphics_engine.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
 
392
 
 
393
  if (draw_separator)
311
394
  {
312
 
    GfxContext.GetRenderStates().SetColorMask(true, true, true, true);
313
 
    GfxContext.GetRenderStates().SetBlend(true);
314
 
    GfxContext.GetRenderStates().SetPremultipliedBlend(nux::SRC_OVER);
315
 
    nux::GetPainter().Draw2DLine(GfxContext,
316
 
                                 base.x + 15, base.y + base.height - 1,
317
 
                                 base.x + base.width - 15, base.y + base.height - 1,
 
395
    nux::Color col(0.15f, 0.15f, 0.15f, 0.15f);
 
396
 
 
397
    nux::GetPainter().Draw2DLine(graphics_engine,
 
398
                                 base.x + kSeparatorLeftPadding, base.y + base.height - 1,
 
399
                                 base.x + base.width - kSeparatorWidthSubtractor, base.y + base.height - 1,
318
400
                                 col);
319
401
  }
320
402
 
321
 
  GfxContext.PopClippingRectangle();
 
403
  graphics_engine.GetRenderStates().SetColorMask(true, true, true, true);
 
404
 
 
405
  if (ShouldBeHighlighted())
 
406
  {
 
407
    nux::Geometry geo(_header_layout->GetGeometry());
 
408
    geo.x = base.x + kHighlightLeftPadding;
 
409
    geo.width = base.width - kHighlightWidthSubtractor;
 
410
 
 
411
    _focus_layer->SetGeometry(geo);
 
412
    _focus_layer->Renderlayer(graphics_engine);
 
413
  }
 
414
 
 
415
  graphics_engine.PopClippingRectangle();
322
416
}
323
417
 
324
418
void
325
 
PlacesGroup::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
 
419
PlacesGroup::DrawContent(nux::GraphicsEngine& graphics_engine, bool force_draw)
326
420
{
327
 
  nux::Geometry base = GetGeometry();
328
 
  GfxContext.PushClippingRectangle(base);
329
 
 
330
 
  _group_layout->ProcessDraw(GfxContext, force_draw);
331
 
  GfxContext.PopClippingRectangle();
 
421
  nux::Geometry const& base = GetGeometry();
 
422
 
 
423
  graphics_engine.PushClippingRectangle(base);
 
424
 
 
425
  if (ShouldBeHighlighted() && !IsFullRedraw())
 
426
  {
 
427
    nux::GetPainter().PushLayer(graphics_engine, _focus_layer->GetGeometry(), _focus_layer);
 
428
  }
 
429
 
 
430
  _group_layout->ProcessDraw(graphics_engine, force_draw);
 
431
 
 
432
  graphics_engine.PopClippingRectangle();
332
433
}
333
434
 
334
 
void PlacesGroup::PostDraw(nux::GraphicsEngine& GfxContext,
 
435
void PlacesGroup::PostDraw(nux::GraphicsEngine& graphics_engine,
335
436
                           bool                 forceDraw)
336
437
{
337
438
}
346
447
}
347
448
 
348
449
bool
349
 
PlacesGroup::GetExpanded()
 
450
PlacesGroup::GetExpanded() const
350
451
{
351
452
  return _is_expanded;
352
453
}
382
483
void
383
484
PlacesGroup::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags)
384
485
{
385
 
  _expand_label->SetTextColor(kExpandHoverTextColor);
386
 
  _expand_icon->SetOpacity(kExpandHoverIconOpacity);
 
486
  QueueDraw();
387
487
}
388
488
 
389
489
void
390
490
PlacesGroup::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags)
391
491
{
392
 
  if (!_expand_label->HasKeyFocus())
393
 
  {
394
 
    _expand_label->SetTextColor(kExpandDefaultTextColor);
395
 
    _expand_icon->SetOpacity(kExpandDefaultIconOpacity);
396
 
  }
 
492
  QueueDraw();
397
493
}
398
494
 
399
495
int
400
 
PlacesGroup::GetHeaderHeight()
 
496
PlacesGroup::GetHeaderHeight() const
401
497
{
402
498
  return _header_layout->GetGeometry().height;
403
499
}
404
500
 
405
 
void
406
 
PlacesGroup::SetDrawSeparator(bool draw_it)
407
 
{
408
 
  _draw_sep = draw_it;
409
 
 
410
 
  QueueDraw();
 
501
bool PlacesGroup::HeaderHasKeyFocus() const
 
502
{
 
503
  return (_header_view && _header_view->HasKeyFocus());
 
504
}
 
505
 
 
506
bool PlacesGroup::HeaderIsFocusable() const
 
507
{
 
508
  return (_header_view != nullptr);
 
509
}
 
510
 
 
511
nux::View* PlacesGroup::GetHeaderFocusableView() const
 
512
{
 
513
  return _header_view;
 
514
}
 
515
 
 
516
bool PlacesGroup::ShouldBeHighlighted() const
 
517
{
 
518
  return HeaderHasKeyFocus();
411
519
}
412
520
 
413
521
//
416
524
bool
417
525
PlacesGroup::AcceptKeyNavFocus()
418
526
{
419
 
  return false;
 
527
  return true;
 
528
}
 
529
 
 
530
//
 
531
// Introspection
 
532
//
 
533
std::string PlacesGroup::GetName() const
 
534
{
 
535
  return "PlacesGroup";
 
536
}
 
537
 
 
538
void PlacesGroup::AddProperties(GVariantBuilder* builder)
 
539
{
 
540
  unity::variant::BuilderWrapper wrapper(builder);
 
541
 
 
542
  wrapper.add("header-x", _header_view->GetAbsoluteX());
 
543
  wrapper.add("header-y", _header_view->GetAbsoluteY());
 
544
  wrapper.add("header-width", _header_view->GetAbsoluteWidth());
 
545
  wrapper.add("header-height", _header_view->GetAbsoluteHeight());
 
546
  wrapper.add("header-has-keyfocus", HeaderHasKeyFocus());
 
547
  wrapper.add("header-is-highlighted", ShouldBeHighlighted());
 
548
  wrapper.add("name", _name->GetText());
 
549
  wrapper.add("is-visible", IsVisible());
 
550
  wrapper.add("is-expanded", GetExpanded());
 
551
  wrapper.add("expand-label-is-visible", _expand_label->IsVisible());
 
552
  wrapper.add("expand-label-y", _expand_label->GetAbsoluteY());
 
553
  wrapper.add("expand-label-baseline", _expand_label->GetBaseline());
 
554
  wrapper.add("name-label-y", _name->GetAbsoluteY());
 
555
  wrapper.add("name-label-baseline", _name->GetBaseline());
420
556
}
421
557
 
422
558
} // namespace unity