~3v1n0/unity/overlay-border-scale

« back to all changes in this revision

Viewing changes to plugins/unityshell/src/DashView.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:
37
37
{
38
38
namespace dash
39
39
{
40
 
 
41
40
namespace
42
41
{
 
42
 
43
43
nux::logging::Logger logger("unity.dash.view");
 
44
 
44
45
}
45
46
 
 
47
// This is so we can access some protected members in nux::VLayout and
 
48
// break the natural key navigation path.
 
49
class DashLayout: public nux::VLayout
 
50
{
 
51
public:
 
52
  DashLayout(NUX_FILE_LINE_DECL)
 
53
    : nux::VLayout(NUX_FILE_LINE_PARAM)
 
54
    , area_(nullptr)
 
55
  {}
 
56
 
 
57
  void SetSpecialArea(nux::Area* area)
 
58
  {
 
59
    area_ = area;
 
60
  }
 
61
 
 
62
protected:
 
63
  nux::Area* KeyNavIteration(nux::KeyNavDirection direction)
 
64
  {
 
65
    if (direction == nux::KEY_NAV_DOWN && area_ &&  area_->HasKeyFocus())
 
66
      return nullptr;
 
67
    else
 
68
      return nux::VLayout::KeyNavIteration(direction);
 
69
  }
 
70
 
 
71
private:
 
72
  nux::Area* area_;
 
73
};
 
74
 
46
75
NUX_IMPLEMENT_OBJECT_TYPE(DashView);
47
76
 
48
77
DashView::DashView()
49
78
  : nux::View(NUX_TRACKER_LOCATION)
 
79
  , home_lens_(new HomeLens(_("Home"), _("Home screen"), _("Search")))
50
80
  , active_lens_view_(0)
51
81
  , last_activated_uri_("")
52
82
  , searching_timeout_id_(0)
53
83
  , search_in_progress_(false)
54
84
  , activate_on_finish_(false)
 
85
  , hide_message_delay_id_(0)
55
86
  , visible_(false)
56
87
{
57
88
  renderer_.SetOwner(this);
67
98
  mouse_down.connect(sigc::mem_fun(this, &DashView::OnMouseButtonDown));
68
99
 
69
100
  Relayout();
 
101
 
 
102
  home_lens_->AddLenses(lenses_);
70
103
  lens_bar_->Activate("home.lens");
71
104
}
72
105
 
74
107
{
75
108
  if (searching_timeout_id_)
76
109
    g_source_remove (searching_timeout_id_);
 
110
  if (hide_message_delay_id_)
 
111
    g_source_remove(hide_message_delay_id_);
 
112
}
 
113
 
 
114
void DashView::SetMonitorOffset(int x, int y)
 
115
{
 
116
  renderer_.x_offset = x;
 
117
  renderer_.y_offset = y;
77
118
}
78
119
 
79
120
void DashView::AboutToShow()
81
122
  ubus_manager_.SendMessage(UBUS_BACKGROUND_REQUEST_COLOUR_EMIT);
82
123
  visible_ = true;
83
124
  search_bar_->text_entry()->SelectAll();
 
125
 
 
126
  /* Give the lenses a chance to prep data before we map them  */
 
127
  lens_bar_->Activate(active_lens_view_->lens()->id());
 
128
  if (active_lens_view_->lens()->id() == "home.lens")
 
129
  {
 
130
    for (auto lens : lenses_.GetLenses())
 
131
      {
 
132
        lens->view_type = ViewType::HOME_VIEW;
 
133
        LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HOME_VIEW
 
134
                              << " on '" << lens->id() << "'";
 
135
      }
 
136
 
 
137
      home_lens_->view_type = ViewType::LENS_VIEW;
 
138
      LOG_DEBUG(logger) << "Setting ViewType " << ViewType::LENS_VIEW
 
139
                                << " on '" << home_lens_->id() << "'";
 
140
  }
 
141
 
84
142
  renderer_.AboutToShow();
85
143
}
86
144
 
88
146
{
89
147
  visible_ = false;
90
148
  renderer_.AboutToHide();
 
149
 
 
150
  for (auto lens : lenses_.GetLenses())
 
151
  {
 
152
    lens->view_type = ViewType::HIDDEN;
 
153
    LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN
 
154
                          << " on '" << lens->id() << "'";
 
155
  }
 
156
 
 
157
  home_lens_->view_type = ViewType::HIDDEN;
 
158
  LOG_DEBUG(logger) << "Setting ViewType " << ViewType::HIDDEN
 
159
                            << " on '" << home_lens_->id() << "'";
91
160
}
92
161
 
93
162
void DashView::SetupViews()
95
164
  layout_ = new nux::VLayout();
96
165
  SetLayout(layout_);
97
166
 
98
 
  content_layout_ = new nux::VLayout();
 
167
  content_layout_ = new DashLayout(NUX_TRACKER_LOCATION);
99
168
  content_layout_->SetHorizontalExternalMargin(0);
100
169
  content_layout_->SetVerticalExternalMargin(0);
101
170
 
107
176
  search_bar_->live_search_reached.connect(sigc::mem_fun(this, &DashView::OnLiveSearchReached));
108
177
  search_bar_->showing_filters.changed.connect([&] (bool showing) { if (active_lens_view_) active_lens_view_->filters_expanded = showing; QueueDraw(); });
109
178
  content_layout_->AddView(search_bar_, 0, nux::MINOR_POSITION_LEFT);
 
179
  content_layout_->SetSpecialArea(search_bar_->show_filters());
110
180
 
111
181
  lenses_layout_ = new nux::VLayout();
112
182
  content_layout_->AddView(lenses_layout_, 1, nux::MINOR_POSITION_LEFT);
113
183
 
114
 
  home_view_ = new HomeView();
 
184
  home_view_ = new LensView(home_lens_, nullptr);
 
185
  AddChild(home_view_);
115
186
  active_lens_view_ = home_view_;
116
 
  lens_views_["home.lens"] = home_view_;
 
187
  lens_views_[home_lens_->id] = home_view_;
117
188
  lenses_layout_->AddView(home_view_);
118
189
 
119
190
  lens_bar_ = new LensBar();
 
191
  AddChild(lens_bar_);
120
192
  lens_bar_->lens_activated.connect(sigc::mem_fun(this, &DashView::OnLensBarActivated));
121
193
  content_layout_->AddView(lens_bar_, 0, nux::MINOR_POSITION_CENTER);
122
194
}
181
253
 
182
254
  width = MAX(width, tile_width * 6);
183
255
 
184
 
  width += 19 + 32; // add the left padding and the group plugin padding
 
256
  width += 19 + 40; // add the left padding and the group plugin padding
185
257
 
186
258
  height = search_bar_->GetGeometry().height;
187
259
  height += tile_height * 3;
239
311
 
240
312
  std::string id = AnalyseLensURI(uri.Str());
241
313
 
242
 
  home_view_->search_string = "";
243
314
  lens_bar_->Activate(id);
244
315
 
245
316
  if ((id == "home.lens" && handled_type != GOTO_DASH_URI ) || !visible_)
306
377
  return FALSE;
307
378
}
308
379
 
 
380
gboolean DashView::HideResultMessageCb(gpointer data)
 
381
{
 
382
  DashView *self = static_cast<DashView*>(data);
 
383
 
 
384
  self->active_lens_view_->HideResultsMessage();
 
385
  self->hide_message_delay_id_ = 0;
 
386
 
 
387
  return FALSE;
 
388
}
 
389
 
309
390
void DashView::OnSearchChanged(std::string const& search_string)
310
391
{
311
392
  LOG_DEBUG(logger) << "Search changed: " << search_string;
317
398
    if (searching_timeout_id_)
318
399
    {
319
400
      g_source_remove (searching_timeout_id_);
 
401
      searching_timeout_id_ = 0;
320
402
    }
 
403
 
321
404
    // 250ms for the Search method call, rest for the actual search
322
405
    searching_timeout_id_ = g_timeout_add (500, &DashView::ResetSearchStateCb, this);
 
406
    
 
407
    
 
408
    if (hide_message_delay_id_)
 
409
    {
 
410
      g_source_remove(hide_message_delay_id_);
 
411
      hide_message_delay_id_ = 0;
 
412
    }
 
413
 
 
414
    // 150ms to hide the no reults message if its take a while to return results
 
415
    hide_message_delay_id_ = g_timeout_add (150, &DashView::HideResultMessageCb, this);
323
416
  }
324
417
}
325
418
 
336
429
{
337
430
  std::string id = lens->id;
338
431
  lens_bar_->AddLens(lens);
339
 
  home_view_->AddLens(lens);
340
432
 
341
 
  LensView* view = new LensView(lens);
 
433
  LensView* view = new LensView(lens, search_bar_->show_filters());
 
434
  AddChild(view);
342
435
  view->SetVisible(false);
343
436
  view->uri_activated.connect(sigc::mem_fun(this, &DashView::OnUriActivated));
344
437
  lenses_layout_->AddView(view, 1);
362
455
  for (auto it: lens_views_)
363
456
  {
364
457
    bool id_matches = it.first == id;
 
458
    ViewType view_type = id_matches ? LENS_VIEW : (view == home_view_ ? HOME_VIEW : HIDDEN);
365
459
    it.second->SetVisible(id_matches);
366
 
    it.second->view_type = id_matches ? LENS_VIEW : (view == home_view_ ? HOME_VIEW : HIDDEN);
 
460
    it.second->view_type = view_type;
 
461
 
 
462
    LOG_DEBUG(logger) << "Setting ViewType " << view_type
 
463
                      << " on '" << it.first << "'";
367
464
  }
368
465
 
369
466
  search_bar_->search_string = view->search_string;
370
 
  if (view != home_view_)
371
 
    search_bar_->search_hint = view->lens()->search_hint;
372
 
  else
373
 
    search_bar_->search_hint = _("Search");
 
467
  search_bar_->search_hint = view->lens()->search_hint;
 
468
 
374
469
  bool expanded = view->filters_expanded;
375
470
  search_bar_->showing_filters = expanded;
376
471
 
 
472
  nux::GetWindowCompositor().SetKeyFocusArea(default_focus());
 
473
 
377
474
  search_bar_->text_entry()->SelectAll();
378
475
 
379
476
  search_bar_->can_refine_search = view->can_refine_search();
380
477
 
 
478
  if (hide_message_delay_id_)
 
479
  {
 
480
    g_source_remove(hide_message_delay_id_);
 
481
    hide_message_delay_id_ = 0;
 
482
  }
 
483
 
381
484
  view->QueueDraw();
382
485
  QueueDraw();
383
486
}
384
487
 
385
488
void DashView::OnSearchFinished(Lens::Hints const& hints)
386
489
{
387
 
  Lens::Hints::const_iterator it;
388
 
  it = hints.find("no-results-hint");
389
 
  
390
 
  if (it != hints.end())
 
490
  if (hide_message_delay_id_)
391
491
  {
392
 
    LOG_DEBUG(logger) << "We have no-results-hint: " << g_variant_get_string (it->second, NULL);
 
492
    g_source_remove(hide_message_delay_id_);
 
493
    hide_message_delay_id_ = 0;
393
494
  }
394
495
 
 
496
  active_lens_view_->CheckNoResults(hints);
 
497
 
395
498
  std::string search_string = search_bar_->search_string;
396
499
  if (active_lens_view_ && active_lens_view_->search_string == search_string)
397
500
  {
553
656
      ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
554
657
    else
555
658
      search_bar_->search_string = "";
 
659
 
556
660
    return true;
557
661
  }
558
662
  return false;
570
674
}
571
675
 
572
676
void DashView::AddProperties(GVariantBuilder* builder)
573
 
{}
574
 
 
575
 
nux::Area * DashView::KeyNavIteration(nux::KeyNavDirection direction)
576
 
{
577
 
  // We don't want to eat the tab as it's used for IM stuff
578
 
  if (!search_bar_->im_active())
 
677
{
 
678
  int num_rows = 1; // The search bar
 
679
 
 
680
  if (active_lens_view_)
 
681
    num_rows += active_lens_view_->GetNumRows();
 
682
 
 
683
  unity::variant::BuilderWrapper wrapper(builder);
 
684
  wrapper.add("num-rows", num_rows);
 
685
}
 
686
 
 
687
nux::Area* DashView::KeyNavIteration(nux::KeyNavDirection direction)
 
688
{
 
689
  if (direction == nux::KEY_NAV_DOWN && search_bar_ && active_lens_view_)
579
690
  {
580
 
    if (direction == KEY_NAV_TAB_NEXT)
581
 
      lens_bar_->ActivateNext();
582
 
    else if (direction == KEY_NAV_TAB_PREVIOUS)
583
 
      lens_bar_->ActivatePrevious();
 
691
    auto show_filters = search_bar_->show_filters();
 
692
    auto fscroll_view = active_lens_view_->fscroll_view();
 
693
    
 
694
    if (show_filters && show_filters->HasKeyFocus())
 
695
    {
 
696
      if (fscroll_view->IsVisible() && fscroll_view)
 
697
        return fscroll_view->KeyNavIteration(direction);
 
698
      else
 
699
        return active_lens_view_->KeyNavIteration(direction);
 
700
    } 
584
701
  }
585
702
  return this;
586
703
}
597
714
  // Do what nux::View does, but if the event isn't a key navigation,
598
715
  // designate the text entry to process it.
599
716
 
 
717
  bool ctrl = (special_keys_state & NUX_STATE_CTRL);
 
718
 
600
719
  nux::KeyNavDirection direction = KEY_NAV_NONE;
601
720
  switch (x11_key_code)
602
721
  {
613
732
    direction = KEY_NAV_RIGHT;
614
733
    break;
615
734
  case NUX_VK_LEFT_TAB:
 
735
  case NUX_VK_PAGE_UP:
616
736
    direction = KEY_NAV_TAB_PREVIOUS;
617
737
    break;
618
738
  case NUX_VK_TAB:
 
739
  case NUX_VK_PAGE_DOWN:
619
740
    direction = KEY_NAV_TAB_NEXT;
620
741
    break;
621
742
  case NUX_VK_ENTER:
623
744
    // Not sure if Enter should be a navigation key
624
745
    direction = KEY_NAV_ENTER;
625
746
    break;
 
747
  case NUX_VK_F4:
 
748
    // Maybe we should not do it here, but it needs to be checked where 
 
749
    // we are able to know if alt is pressed.
 
750
    if (special_keys_state & NUX_STATE_ALT)
 
751
    {
 
752
      ubus_manager_.SendMessage(UBUS_PLACE_VIEW_CLOSE_REQUEST);
 
753
    }
 
754
    break;
626
755
  default:
627
756
    direction = KEY_NAV_NONE;
628
757
    break;
629
758
  }
630
759
 
631
 
  if (has_key_focus_)
 
760
  // We should not do it here, but I really don't want to make DashView 
 
761
  // focusable and I'm not able to know if ctrl is pressed in
 
762
  // DashView::KeyNavIteration.
 
763
   nux::InputArea* focus_area = nux::GetWindowCompositor().GetKeyFocusArea();
 
764
 
 
765
  if (key_symbol == nux::NUX_KEYDOWN)
632
766
  {
633
 
    return this;
 
767
    std::list<nux::Area*> tabs;
 
768
    for (auto category : active_lens_view_->categories())
 
769
    {
 
770
      if (category->IsVisible())
 
771
        tabs.push_back(category);
 
772
    }
 
773
 
 
774
    if (search_bar_ && search_bar_->show_filters() &&
 
775
        search_bar_->show_filters()->IsVisible())
 
776
    {
 
777
      tabs.push_back(search_bar_->show_filters());
 
778
    }
 
779
 
 
780
    if (active_lens_view_->filter_bar() && active_lens_view_->fscroll_view() &&
 
781
        active_lens_view_->fscroll_view()->IsVisible())
 
782
    {
 
783
      for (auto filter : active_lens_view_->filter_bar()->GetLayout()->GetChildren())
 
784
      {
 
785
        tabs.push_back(filter);
 
786
      }
 
787
    }
 
788
 
 
789
    if (direction == KEY_NAV_TAB_PREVIOUS)
 
790
    {
 
791
      if (ctrl)
 
792
      {
 
793
        lens_bar_->ActivatePrevious();
 
794
      }
 
795
      else
 
796
      {
 
797
        auto rbegin = tabs.rbegin();
 
798
        auto rend = tabs.rend();
 
799
 
 
800
        bool use_the_prev = false;
 
801
        for (auto tab = rbegin; tab != rend; ++tab)
 
802
        {
 
803
          const auto& tab_ptr = *tab;
 
804
           
 
805
          if (use_the_prev)
 
806
            return tab_ptr;
 
807
          
 
808
          if (focus_area)
 
809
            use_the_prev = focus_area->IsChildOf(tab_ptr);
 
810
        }
 
811
 
 
812
        for (auto tab = rbegin; tab != rend; ++tab)
 
813
          return *tab;
 
814
      }
 
815
    }
 
816
    else if (direction == KEY_NAV_TAB_NEXT)
 
817
    {
 
818
      if (ctrl)
 
819
      {
 
820
        lens_bar_->ActivateNext();
 
821
      }
 
822
      else
 
823
      {
 
824
        bool use_the_next = false;
 
825
        for (auto tab : tabs)
 
826
        {
 
827
          if (use_the_next)
 
828
            return tab;
 
829
          
 
830
          if (focus_area)
 
831
            use_the_next = focus_area->IsChildOf(tab);
 
832
        }
 
833
 
 
834
        for (auto tab : tabs)
 
835
          return tab;
 
836
      }
 
837
    }
634
838
  }
635
 
  else if (direction == KEY_NAV_NONE || search_bar_->im_active)
 
839
 
 
840
  if (direction == KEY_NAV_NONE || search_bar_->im_active)
636
841
  {
637
842
    // then send the event to the search entry
638
843
    return search_bar_->text_entry();