Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / ash / system / tray / tray_details_view.cc
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
19 class ScrollSeparator : public views::View {
20  public:
21   ScrollSeparator() {}
22
23   ~ScrollSeparator() override {}
24
25  private:
26   // Overriden from views::View.
27   void OnPaint(gfx::Canvas* canvas) override {
28     canvas->FillRect(gfx::Rect(0, height() / 2, width(), 1), kBorderLightColor);
29   }
30   gfx::Size GetPreferredSize() const override {
31     return gfx::Size(1, kTrayPopupScrollSeparatorHeight);
32   }
33
34   DISALLOW_COPY_AND_ASSIGN(ScrollSeparator);
35 };
36
37 class ScrollBorder : public views::Border {
38  public:
39   ScrollBorder() {}
40   ~ScrollBorder() override {}
41
42   void set_visible(bool visible) { visible_ = visible; }
43
44  private:
45   // Overridden from views::Border.
46   void Paint(const views::View& view, gfx::Canvas* canvas) override {
47     if (!visible_)
48       return;
49     canvas->FillRect(gfx::Rect(0, view.height() - 1, view.width(), 1),
50                      kBorderLightColor);
51   }
52
53   gfx::Insets GetInsets() const override { return gfx::Insets(0, 0, 1, 0); }
54
55   gfx::Size GetMinimumSize() const override { return gfx::Size(0, 1); }
56
57   bool visible_;
58
59   DISALLOW_COPY_AND_ASSIGN(ScrollBorder);
60 };
61
62 TrayDetailsView::TrayDetailsView(SystemTrayItem* owner)
63     : owner_(owner),
64       footer_(NULL),
65       scroller_(NULL),
66       scroll_content_(NULL),
67       scroll_border_(NULL) {
68   SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
69       0, 0, 0));
70   set_background(views::Background::CreateSolidBackground(kBackgroundColor));
71 }
72
73 TrayDetailsView::~TrayDetailsView() {
74 }
75
76 void TrayDetailsView::CreateSpecialRow(int string_id,
77                                        ViewClickListener* listener) {
78   DCHECK(!footer_);
79   footer_ = new SpecialPopupRow();
80   footer_->SetTextLabel(string_id, listener);
81   AddChildViewAt(footer_, child_count());
82 }
83
84 void TrayDetailsView::CreateScrollableList() {
85   DCHECK(!scroller_);
86   scroll_content_ = new views::View;
87   scroll_content_->SetLayoutManager(new views::BoxLayout(
88       views::BoxLayout::kVertical, 0, 0, 1));
89   scroller_ = new FixedSizedScrollView;
90   scroller_->SetContentsView(scroll_content_);
91
92   // Note: |scroller_| takes ownership of |scroll_border_|.
93   scroll_border_ = new ScrollBorder;
94   scroller_->SetBorder(scoped_ptr<views::Border>(scroll_border_));
95
96   AddChildView(scroller_);
97 }
98
99 void TrayDetailsView::AddScrollSeparator() {
100   DCHECK(scroll_content_);
101   // Do not draw the separator if it is the very first item
102   // in the scrollable list.
103   if (scroll_content_->has_children())
104     scroll_content_->AddChildView(new ScrollSeparator);
105 }
106
107 void TrayDetailsView::Reset() {
108   RemoveAllChildViews(true);
109   footer_ = NULL;
110   scroller_ = NULL;
111   scroll_content_ = NULL;
112 }
113
114 void TrayDetailsView::TransitionToDefaultView() {
115   // Cache pointer to owner in this function scope. TrayDetailsView will be
116   // deleted after called ShowDefaultView.
117   SystemTrayItem* owner = owner_;
118   if (footer_ && footer_->content() && footer_->content()->HasFocus())
119     owner->set_restore_focus(true);
120   owner->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING);
121   owner->set_restore_focus(false);
122 }
123
124 void TrayDetailsView::Layout() {
125   if (bounds().IsEmpty()) {
126     views::View::Layout();
127     return;
128   }
129
130   if (scroller_) {
131     scroller_->set_fixed_size(gfx::Size());
132     gfx::Size size = GetPreferredSize();
133
134     // Set the scroller to fill the space above the bottom row, so that the
135     // bottom row of the detailed view will always stay just above the footer.
136     gfx::Size scroller_size = scroll_content_->GetPreferredSize();
137     scroller_->set_fixed_size(
138         gfx::Size(width() + scroller_->GetScrollBarWidth(),
139                   scroller_size.height() - (size.height() - height())));
140   }
141
142   views::View::Layout();
143
144   if (footer_) {
145     // Always make sure the footer element is bottom aligned.
146     gfx::Rect fbounds = footer_->bounds();
147     fbounds.set_y(height() - footer_->height());
148     footer_->SetBoundsRect(fbounds);
149   }
150 }
151
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 ash