• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ash/system/tray/tray_details_view.h"
6 
7 #include "ash/system/tray/fixed_sized_scroll_view.h"
8 #include "ash/system/tray/system_tray.h"
9 #include "ash/system/tray/system_tray_item.h"
10 #include "ash/system/tray/tray_constants.h"
11 #include "ui/gfx/canvas.h"
12 #include "ui/views/background.h"
13 #include "ui/views/border.h"
14 #include "ui/views/controls/scroll_view.h"
15 #include "ui/views/layout/box_layout.h"
16 
17 namespace ash {
18 namespace internal {
19 
20 class ScrollSeparator : public views::View {
21  public:
ScrollSeparator()22   ScrollSeparator() {}
23 
~ScrollSeparator()24   virtual ~ScrollSeparator() {}
25 
26  private:
27   // Overriden from views::View.
OnPaint(gfx::Canvas * canvas)28   virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
29     canvas->FillRect(gfx::Rect(0, height() / 2, width(), 1), kBorderLightColor);
30   }
GetPreferredSize()31   virtual gfx::Size GetPreferredSize() OVERRIDE {
32     return gfx::Size(1, kTrayPopupScrollSeparatorHeight);
33   }
34 
35   DISALLOW_COPY_AND_ASSIGN(ScrollSeparator);
36 };
37 
38 class ScrollBorder : public views::Border {
39  public:
ScrollBorder()40   ScrollBorder() {}
~ScrollBorder()41   virtual ~ScrollBorder() {}
42 
set_visible(bool visible)43   void set_visible(bool visible) { visible_ = visible; }
44 
45  private:
46   // Overridden from views::Border.
Paint(const views::View & view,gfx::Canvas * canvas)47   virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE {
48     if (!visible_)
49       return;
50     canvas->FillRect(gfx::Rect(0, view.height() - 1, view.width(), 1),
51                      kBorderLightColor);
52   }
53 
GetInsets() const54   virtual gfx::Insets GetInsets() const OVERRIDE {
55     return gfx::Insets(0, 0, 1, 0);
56   }
57 
GetMinimumSize() const58   virtual gfx::Size GetMinimumSize() const OVERRIDE {
59     return gfx::Size(0, 1);
60   }
61 
62   bool visible_;
63 
64   DISALLOW_COPY_AND_ASSIGN(ScrollBorder);
65 };
66 
TrayDetailsView(SystemTrayItem * owner)67 TrayDetailsView::TrayDetailsView(SystemTrayItem* owner)
68     : owner_(owner),
69       footer_(NULL),
70       scroller_(NULL),
71       scroll_content_(NULL),
72       scroll_border_(NULL) {
73   SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
74       0, 0, 0));
75   set_background(views::Background::CreateSolidBackground(kBackgroundColor));
76 }
77 
~TrayDetailsView()78 TrayDetailsView::~TrayDetailsView() {
79 }
80 
CreateSpecialRow(int string_id,ViewClickListener * listener)81 void TrayDetailsView::CreateSpecialRow(int string_id,
82                                        ViewClickListener* listener) {
83   DCHECK(!footer_);
84   footer_ = new SpecialPopupRow();
85   footer_->SetTextLabel(string_id, listener);
86   AddChildViewAt(footer_, child_count());
87 }
88 
CreateScrollableList()89 void TrayDetailsView::CreateScrollableList() {
90   DCHECK(!scroller_);
91   scroll_content_ = new views::View;
92   scroll_content_->SetLayoutManager(new views::BoxLayout(
93       views::BoxLayout::kVertical, 0, 0, 1));
94   scroller_ = new FixedSizedScrollView;
95   scroller_->SetContentsView(scroll_content_);
96 
97   // Note: |scroller_| takes ownership of |scroll_border_|.
98   scroll_border_ = new ScrollBorder;
99   scroller_->set_border(scroll_border_);
100 
101   AddChildView(scroller_);
102 }
103 
AddScrollSeparator()104 void TrayDetailsView::AddScrollSeparator() {
105   DCHECK(scroll_content_);
106   // Do not draw the separator if it is the very first item
107   // in the scrollable list.
108   if (scroll_content_->has_children())
109     scroll_content_->AddChildView(new ScrollSeparator);
110 }
111 
Reset()112 void TrayDetailsView::Reset() {
113   RemoveAllChildViews(true);
114   footer_ = NULL;
115   scroller_ = NULL;
116   scroll_content_ = NULL;
117 }
118 
TransitionToDefaultView()119 void TrayDetailsView::TransitionToDefaultView() {
120   // Cache pointer to owner in this function scope. TrayDetailsView will be
121   // deleted after called ShowDefaultView.
122   SystemTrayItem* owner = owner_;
123   if (footer_ && footer_->content() && footer_->content()->HasFocus())
124     owner->set_restore_focus(true);
125   owner->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
126   owner->set_restore_focus(false);
127 }
128 
Layout()129 void TrayDetailsView::Layout() {
130   if (!scroller_ || !footer_ || bounds().IsEmpty()) {
131     views::View::Layout();
132     return;
133   }
134 
135   scroller_->set_fixed_size(gfx::Size());
136   gfx::Size size = GetPreferredSize();
137 
138   // Set the scroller to fill the space above the bottom row, so that the
139   // bottom row of the detailed view will always stay just above the footer.
140   gfx::Size scroller_size = scroll_content_->GetPreferredSize();
141   scroller_->set_fixed_size(gfx::Size(
142       width() + scroller_->GetScrollBarWidth(),
143       scroller_size.height() - (size.height() - height())));
144 
145   views::View::Layout();
146   // Always make sure the footer element is bottom aligned.
147   gfx::Rect fbounds = footer_->bounds();
148   fbounds.set_y(height() - footer_->height());
149   footer_->SetBoundsRect(fbounds);
150 }
151 
OnPaintBorder(gfx::Canvas * canvas)152 void TrayDetailsView::OnPaintBorder(gfx::Canvas* canvas) {
153   if (scroll_border_) {
154     int index = GetIndexOf(scroller_);
155     if (index < child_count() - 1 && child_at(index + 1) != footer_)
156       scroll_border_->set_visible(true);
157     else
158       scroll_border_->set_visible(false);
159   }
160 
161   views::View::OnPaintBorder(canvas);
162 }
163 
164 }  // namespace internal
165 }  // namespace ash
166