OLD | NEW |
| (Empty) |
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/common/system/tray/fixed_sized_scroll_view.h" | |
8 #include "ash/common/system/tray/system_tray_item.h" | |
9 #include "ash/common/system/tray/tray_constants.h" | |
10 #include "ash/system/tray/system_tray.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(std::unique_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 | |
OLD | NEW |