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.
5 #include "ash/system/tray/tray_details_view.h"
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"
19 class ScrollSeparator
: public views::View
{
23 virtual ~ScrollSeparator() {}
26 // Overriden from views::View.
27 virtual void OnPaint(gfx::Canvas
* canvas
) OVERRIDE
{
28 canvas
->FillRect(gfx::Rect(0, height() / 2, width(), 1), kBorderLightColor
);
30 virtual gfx::Size
GetPreferredSize() const OVERRIDE
{
31 return gfx::Size(1, kTrayPopupScrollSeparatorHeight
);
34 DISALLOW_COPY_AND_ASSIGN(ScrollSeparator
);
37 class ScrollBorder
: public views::Border
{
40 virtual ~ScrollBorder() {}
42 void set_visible(bool visible
) { visible_
= visible
; }
45 // Overridden from views::Border.
46 virtual void Paint(const views::View
& view
, gfx::Canvas
* canvas
) OVERRIDE
{
49 canvas
->FillRect(gfx::Rect(0, view
.height() - 1, view
.width(), 1),
53 virtual gfx::Insets
GetInsets() const OVERRIDE
{
54 return gfx::Insets(0, 0, 1, 0);
57 virtual gfx::Size
GetMinimumSize() const OVERRIDE
{
58 return gfx::Size(0, 1);
63 DISALLOW_COPY_AND_ASSIGN(ScrollBorder
);
66 TrayDetailsView::TrayDetailsView(SystemTrayItem
* owner
)
70 scroll_content_(NULL
),
71 scroll_border_(NULL
) {
72 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical
,
74 set_background(views::Background::CreateSolidBackground(kBackgroundColor
));
77 TrayDetailsView::~TrayDetailsView() {
80 void TrayDetailsView::CreateSpecialRow(int string_id
,
81 ViewClickListener
* listener
) {
83 footer_
= new SpecialPopupRow();
84 footer_
->SetTextLabel(string_id
, listener
);
85 AddChildViewAt(footer_
, child_count());
88 void TrayDetailsView::CreateScrollableList() {
90 scroll_content_
= new views::View
;
91 scroll_content_
->SetLayoutManager(new views::BoxLayout(
92 views::BoxLayout::kVertical
, 0, 0, 1));
93 scroller_
= new FixedSizedScrollView
;
94 scroller_
->SetContentsView(scroll_content_
);
96 // Note: |scroller_| takes ownership of |scroll_border_|.
97 scroll_border_
= new ScrollBorder
;
98 scroller_
->SetBorder(scoped_ptr
<views::Border
>(scroll_border_
));
100 AddChildView(scroller_
);
103 void TrayDetailsView::AddScrollSeparator() {
104 DCHECK(scroll_content_
);
105 // Do not draw the separator if it is the very first item
106 // in the scrollable list.
107 if (scroll_content_
->has_children())
108 scroll_content_
->AddChildView(new ScrollSeparator
);
111 void TrayDetailsView::Reset() {
112 RemoveAllChildViews(true);
115 scroll_content_
= NULL
;
118 void TrayDetailsView::TransitionToDefaultView() {
119 // Cache pointer to owner in this function scope. TrayDetailsView will be
120 // deleted after called ShowDefaultView.
121 SystemTrayItem
* owner
= owner_
;
122 if (footer_
&& footer_
->content() && footer_
->content()->HasFocus())
123 owner
->set_restore_focus(true);
124 owner
->system_tray()->ShowDefaultView(BUBBLE_USE_EXISTING
);
125 owner
->set_restore_focus(false);
128 void TrayDetailsView::Layout() {
129 if (bounds().IsEmpty()) {
130 views::View::Layout();
135 scroller_
->set_fixed_size(gfx::Size());
136 gfx::Size size
= GetPreferredSize();
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(
142 gfx::Size(width() + scroller_
->GetScrollBarWidth(),
143 scroller_size
.height() - (size
.height() - height())));
146 views::View::Layout();
149 // Always make sure the footer element is bottom aligned.
150 gfx::Rect fbounds
= footer_
->bounds();
151 fbounds
.set_y(height() - footer_
->height());
152 footer_
->SetBoundsRect(fbounds
);
156 void TrayDetailsView::OnPaintBorder(gfx::Canvas
* canvas
) {
157 if (scroll_border_
) {
158 int index
= GetIndexOf(scroller_
);
159 if (index
< child_count() - 1 && child_at(index
+ 1) != footer_
)
160 scroll_border_
->set_visible(true);
162 scroll_border_
->set_visible(false);
165 views::View::OnPaintBorder(canvas
);