Windows should animate when they are about to get docked at screen edges.
[chromium-blink-merge.git] / ash / system / tray / tray_details_view.cc
blobc51920f139042ceaa14ee4d0d4000b8aa43d97e4
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_item.h"
9 #include "ash/system/tray/tray_constants.h"
10 #include "ui/gfx/canvas.h"
11 #include "ui/views/background.h"
12 #include "ui/views/controls/scroll_view.h"
13 #include "ui/views/layout/box_layout.h"
15 namespace ash {
16 namespace internal {
18 class ScrollSeparator : public views::View {
19 public:
20 ScrollSeparator() {}
22 virtual ~ScrollSeparator() {}
24 private:
25 // Overriden from views::View.
26 virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
27 canvas->FillRect(gfx::Rect(0, height() / 2, width(), 1), kBorderLightColor);
29 virtual gfx::Size GetPreferredSize() OVERRIDE {
30 return gfx::Size(1, kTrayPopupScrollSeparatorHeight);
33 DISALLOW_COPY_AND_ASSIGN(ScrollSeparator);
36 class ScrollBorder : public views::Border {
37 public:
38 ScrollBorder() {}
39 virtual ~ScrollBorder() {}
41 void set_visible(bool visible) { visible_ = visible; }
43 private:
44 // Overridden from views::Border.
45 virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE {
46 if (!visible_)
47 return;
48 canvas->FillRect(gfx::Rect(0, view.height() - 1, view.width(), 1),
49 kBorderLightColor);
52 virtual gfx::Insets GetInsets() const OVERRIDE {
53 return gfx::Insets(0, 0, 1, 0);
56 bool visible_;
58 DISALLOW_COPY_AND_ASSIGN(ScrollBorder);
61 TrayDetailsView::TrayDetailsView(SystemTrayItem* owner)
62 : owner_(owner),
63 footer_(NULL),
64 scroller_(NULL),
65 scroll_content_(NULL),
66 scroll_border_(NULL) {
67 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
68 0, 0, 0));
69 set_background(views::Background::CreateSolidBackground(kBackgroundColor));
72 TrayDetailsView::~TrayDetailsView() {
75 void TrayDetailsView::CreateSpecialRow(int string_id,
76 ViewClickListener* listener) {
77 DCHECK(!footer_);
78 footer_ = new SpecialPopupRow();
79 footer_->SetTextLabel(string_id, listener);
80 AddChildViewAt(footer_, child_count());
83 void TrayDetailsView::CreateScrollableList() {
84 DCHECK(!scroller_);
85 scroll_content_ = new views::View;
86 scroll_content_->SetLayoutManager(new views::BoxLayout(
87 views::BoxLayout::kVertical, 0, 0, 1));
88 scroller_ = new FixedSizedScrollView;
89 scroller_->SetContentsView(scroll_content_);
91 // Note: |scroller_| takes ownership of |scroll_border_|.
92 scroll_border_ = new ScrollBorder;
93 scroller_->set_border(scroll_border_);
95 AddChildView(scroller_);
98 void TrayDetailsView::AddScrollSeparator() {
99 DCHECK(scroll_content_);
100 // Do not draw the separator if it is the very first item
101 // in the scrollable list.
102 if (scroll_content_->has_children())
103 scroll_content_->AddChildView(new ScrollSeparator);
106 void TrayDetailsView::Reset() {
107 RemoveAllChildViews(true);
108 footer_ = NULL;
109 scroller_ = NULL;
110 scroll_content_ = NULL;
113 void TrayDetailsView::Layout() {
114 if (!scroller_ || !footer_ || bounds().IsEmpty()) {
115 views::View::Layout();
116 return;
119 scroller_->set_fixed_size(gfx::Size());
120 gfx::Size size = GetPreferredSize();
122 // Set the scroller to fill the space above the bottom row, so that the
123 // bottom row of the detailed view will always stay just above the footer.
124 gfx::Size scroller_size = scroll_content_->GetPreferredSize();
125 scroller_->set_fixed_size(gfx::Size(
126 width() + scroller_->GetScrollBarWidth(),
127 scroller_size.height() - (size.height() - height())));
129 views::View::Layout();
130 // Always make sure the footer element is bottom aligned.
131 gfx::Rect fbounds = footer_->bounds();
132 fbounds.set_y(height() - footer_->height());
133 footer_->SetBoundsRect(fbounds);
136 void TrayDetailsView::OnPaintBorder(gfx::Canvas* canvas) {
137 if (scroll_border_) {
138 int index = GetIndexOf(scroller_);
139 if (index < child_count() - 1 && child_at(index + 1) != footer_)
140 scroll_border_->set_visible(true);
141 else
142 scroll_border_->set_visible(false);
145 views::View::OnPaintBorder(canvas);
148 } // namespace internal
149 } // namespace ash