Chromium Code Reviews
[email protected] (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Side by Side Diff: ash/system/web_notification/message_center_bubble.cc

Issue 11154022: Re-factor Ash Message Center code part 3/4 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address nits, fix clang error Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ash/system/web_notification/message_center_bubble.h" 5 #include "ash/system/web_notification/message_center_bubble.h"
6 6
7 #include "ash/system/tray/tray_constants.h"
8 #include "ash/system/tray/tray_views.h"
9 #include "ash/system/web_notification/web_notification_list.h"
10 #include "ash/system/web_notification/web_notification_tray.h"
11 #include "ash/system/web_notification/web_notification_view.h" 7 #include "ash/system/web_notification/web_notification_view.h"
12 #include "grit/ash_strings.h" 8 #include "grit/ash_strings.h"
13 #include "ui/base/l10n/l10n_util.h" 9 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/resource/resource_bundle.h" 10 #include "ui/base/resource/resource_bundle.h"
15 #include "ui/gfx/size.h" 11 #include "ui/gfx/size.h"
12 #include "ui/views/controls/button/text_button.h"
16 #include "ui/views/controls/label.h" 13 #include "ui/views/controls/label.h"
14 #include "ui/views/controls/scroll_view.h"
17 #include "ui/views/layout/box_layout.h" 15 #include "ui/views/layout/box_layout.h"
18 #include "ui/views/layout/grid_layout.h" 16 #include "ui/views/layout/grid_layout.h"
19 #include "ui/views/painter.h" 17 #include "ui/views/painter.h"
20 #include "ui/views/view.h" 18 #include "ui/views/view.h"
21 #include "ui/views/widget/widget.h" 19 #include "ui/views/widget/widget.h"
22 20
23 namespace ash {
24
25 using internal::TrayPopupTextButton;
26
27 namespace message_center { 21 namespace message_center {
28 22
29 // Web Notification Bubble constants 23 namespace {
24
30 const int kWebNotificationBubbleMinHeight = 80; 25 const int kWebNotificationBubbleMinHeight = 80;
31 const int kWebNotificationBubbleMaxHeight = 400; 26 const int kWebNotificationBubbleMaxHeight = 400;
27 const SkColor kBorderDarkColor = SkColorSetRGB(0xaa, 0xaa, 0xaa);
32 28
33 // The view for the buttons at the bottom of the web notification tray. 29 // The view for the buttons at the bottom of the web notification tray.
34 class WebNotificationButtonView : public views::View, 30 class WebNotificationButtonView : public views::View,
35 public views::ButtonListener { 31 public views::ButtonListener {
36 public: 32 public:
37 explicit WebNotificationButtonView(WebNotificationTray* tray) 33 explicit WebNotificationButtonView(
38 : tray_(tray), 34 WebNotificationList::Delegate* list_delegate)
39 close_all_button_(NULL) { 35 : list_delegate_(list_delegate),
36 close_all_button_(NULL) {
40 set_background(views::Background::CreateBackgroundPainter( 37 set_background(views::Background::CreateBackgroundPainter(
41 true, 38 true,
42 views::Painter::CreateVerticalGradient( 39 views::Painter::CreateVerticalGradient(
43 kHeaderBackgroundColorLight, 40 WebNotificationBubble::kHeaderBackgroundColorLight,
44 kHeaderBackgroundColorDark))); 41 WebNotificationBubble::kHeaderBackgroundColorDark)));
45 set_border(views::Border::CreateSolidSidedBorder( 42 set_border(views::Border::CreateSolidSidedBorder(
46 2, 0, 0, 0, ash::kBorderDarkColor)); 43 2, 0, 0, 0, kBorderDarkColor));
47 44
48 views::GridLayout* layout = new views::GridLayout(this); 45 views::GridLayout* layout = new views::GridLayout(this);
49 SetLayoutManager(layout); 46 SetLayoutManager(layout);
50 views::ColumnSet* columns = layout->AddColumnSet(0); 47 views::ColumnSet* columns = layout->AddColumnSet(0);
51 columns->AddPaddingColumn(100, 0); 48 columns->AddPaddingColumn(100, 0);
52 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER, 49 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
53 0, /* resize percent */ 50 0, /* resize percent */
54 views::GridLayout::USE_PREF, 0, 0); 51 views::GridLayout::USE_PREF, 0, 0);
52 columns->AddPaddingColumn(0, 4);
55 53
56 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); 54 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
57 close_all_button_ = new TrayPopupTextButton( 55 close_all_button_ = new views::TextButton(
58 this, rb.GetLocalizedString(IDS_ASH_WEB_NOTFICATION_TRAY_CLEAR_ALL)); 56 this, rb.GetLocalizedString(IDS_ASH_WEB_NOTFICATION_TRAY_CLEAR_ALL));
57 close_all_button_->set_alignment(views::TextButton::ALIGN_CENTER);
58 close_all_button_->set_focusable(true);
59 close_all_button_->set_request_focus_on_press(false);
59 60
61 layout->AddPaddingRow(0, 4);
60 layout->StartRow(0, 0); 62 layout->StartRow(0, 0);
61 layout->AddView(close_all_button_); 63 layout->AddView(close_all_button_);
62 } 64 }
63 65
64 virtual ~WebNotificationButtonView() {} 66 virtual ~WebNotificationButtonView() {}
65 67
66 void SetCloseAllVisible(bool visible) { 68 void SetCloseAllVisible(bool visible) {
67 close_all_button_->SetVisible(visible); 69 close_all_button_->SetVisible(visible);
68 } 70 }
69 71
70 // Overridden from ButtonListener. 72 // Overridden from ButtonListener.
71 virtual void ButtonPressed(views::Button* sender, 73 virtual void ButtonPressed(views::Button* sender,
72 const ui::Event& event) OVERRIDE { 74 const ui::Event& event) OVERRIDE {
73 if (sender == close_all_button_) 75 if (sender == close_all_button_)
74 tray_->SendRemoveAllNotifications(); 76 list_delegate_->SendRemoveAllNotifications();
75 } 77 }
76 78
77 private: 79 private:
78 WebNotificationTray* tray_; 80 WebNotificationList::Delegate* list_delegate_;
79 internal::TrayPopupTextButton* close_all_button_; 81 views::TextButton* close_all_button_;
80 82
81 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView); 83 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView);
82 }; 84 };
83 85
86 // A custom scroll-view that has a specified size.
87 class FixedSizedScrollView : public views::ScrollView {
jennyz 2012/10/16 23:09:39 Is this the same class and code as the one in ash/
stevenjb 2012/10/17 00:52:50 It's *similar*, but I simplified it. I considered
88 public:
89 FixedSizedScrollView() {
90 set_focusable(true);
91 set_notify_enter_exit_on_child(true);
92 }
93
94 virtual ~FixedSizedScrollView() {}
95
96 void SetFixedSize(const gfx::Size& size) {
97 if (fixed_size_ == size)
98 return;
99 fixed_size_ = size;
100 PreferredSizeChanged();
101 }
102
103 // views::View overrides.
104 virtual gfx::Size GetPreferredSize() OVERRIDE {
105 gfx::Size size = fixed_size_.IsEmpty() ?
106 GetContents()->GetPreferredSize() : fixed_size_;
107 gfx::Insets insets = GetInsets();
108 size.Enlarge(insets.width(), insets.height());
109 return size;
110 }
111
112 virtual void Layout() OVERRIDE {
113 views::View* contents = GetContents();
114 gfx::Rect bounds = gfx::Rect(contents->GetPreferredSize());
115 bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
116 contents->SetBoundsRect(bounds);
117
118 views::ScrollView::Layout();
119 if (!vertical_scroll_bar()->visible()) {
120 gfx::Rect bounds = contents->bounds();
121 bounds.set_width(bounds.width() + GetScrollBarWidth());
122 contents->SetBoundsRect(bounds);
123 }
124 }
125
126 virtual void OnBoundsChanged(const gfx::Rect& previous_bounds) OVERRIDE {
127 views::View* contents = GetContents();
128 gfx::Rect bounds = gfx::Rect(contents->GetPreferredSize());
129 bounds.set_width(std::max(0, width() - GetScrollBarWidth()));
130 contents->SetBoundsRect(bounds);
131 }
132
133 private:
134 gfx::Size fixed_size_;
135
136 DISALLOW_COPY_AND_ASSIGN(FixedSizedScrollView);
137 };
138
139 // Container for the messages.
140 class ScrollContentView : public views::View {
141 public:
142 ScrollContentView() {
143 views::BoxLayout* layout =
144 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1);
145 layout->set_spread_blank_space(true);
146 SetLayoutManager(layout);
147 }
148
149 virtual ~ScrollContentView() {
150 }
151
152 virtual gfx::Size GetPreferredSize() OVERRIDE {
153 if (!preferred_size_.IsEmpty())
154 return preferred_size_;
155 return views::View::GetPreferredSize();
156 }
157
158 void set_preferred_size(const gfx::Size& size) { preferred_size_ = size; }
159
160 private:
161 gfx::Size preferred_size_;
162 DISALLOW_COPY_AND_ASSIGN(ScrollContentView);
163 };
164
165 } // namespace
84 166
85 // Message Center contents. 167 // Message Center contents.
86 class MessageCenterContentsView : public views::View { 168 class MessageCenterContentsView : public views::View {
87 public: 169 public:
88 class ScrollContentView : public views::View { 170 explicit MessageCenterContentsView(
89 public: 171 WebNotificationList::Delegate* list_delegate)
90 ScrollContentView() { 172 : list_delegate_(list_delegate) {
91 views::BoxLayout* layout =
92 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1);
93 layout->set_spread_blank_space(true);
94 SetLayoutManager(layout);
95 }
96
97 virtual ~ScrollContentView() {
98 }
99
100 virtual gfx::Size GetPreferredSize() OVERRIDE {
101 if (!preferred_size_.IsEmpty())
102 return preferred_size_;
103 return views::View::GetPreferredSize();
104 }
105
106 void set_preferred_size(const gfx::Size& size) { preferred_size_ = size; }
107
108 private:
109 gfx::Size preferred_size_;
110 DISALLOW_COPY_AND_ASSIGN(ScrollContentView);
111 };
112
113 explicit MessageCenterContentsView(WebNotificationTray* tray)
114 : tray_(tray) {
115 SetLayoutManager( 173 SetLayoutManager(
116 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1)); 174 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
117 175
118 scroll_content_ = new ScrollContentView; 176 scroll_content_ = new ScrollContentView;
119 scroller_ = new internal::FixedSizedScrollView; 177 scroller_ = new FixedSizedScrollView;
120 scroller_->SetContentsView(scroll_content_); 178 scroller_->SetContents(scroll_content_);
121 AddChildView(scroller_); 179 AddChildView(scroller_);
122 180
123 scroller_->SetPaintToLayer(true); 181 scroller_->SetPaintToLayer(true);
124 scroller_->SetFillsBoundsOpaquely(false); 182 scroller_->SetFillsBoundsOpaquely(false);
125 scroller_->layer()->SetMasksToBounds(true); 183 scroller_->layer()->SetMasksToBounds(true);
126 184
127 button_view_ = new WebNotificationButtonView(tray); 185 button_view_ = new WebNotificationButtonView(list_delegate);
128 AddChildView(button_view_); 186 AddChildView(button_view_);
129 } 187 }
130 188
189 void FocusContents() {
190 scroller_->RequestFocus();
191 }
192
131 void Update(const WebNotificationList::Notifications& notifications) { 193 void Update(const WebNotificationList::Notifications& notifications) {
132 scroll_content_->RemoveAllChildViews(true); 194 scroll_content_->RemoveAllChildViews(true);
133 scroll_content_->set_preferred_size(gfx::Size()); 195 scroll_content_->set_preferred_size(gfx::Size());
134 size_t num_children = 0; 196 size_t num_children = 0;
135 for (WebNotificationList::Notifications::const_iterator iter = 197 for (WebNotificationList::Notifications::const_iterator iter =
136 notifications.begin(); iter != notifications.end(); ++iter) { 198 notifications.begin(); iter != notifications.end(); ++iter) {
137 WebNotificationView* view = 199 WebNotificationView* view = new WebNotificationView(
138 new WebNotificationView(tray_, *iter, scroller_->GetScrollBarWidth()); 200 list_delegate_, *iter, scroller_->GetScrollBarWidth());
139 view->set_scroller(scroller_); 201 view->set_scroller(scroller_);
140 scroll_content_->AddChildView(view); 202 scroll_content_->AddChildView(view);
141 if (++num_children >= WebNotificationTray::kMaxVisibleTrayNotifications) 203 if (++num_children >=
204 WebNotificationList::kMaxVisibleMessageCenterNotifications) {
142 break; 205 break;
206 }
143 } 207 }
144 if (num_children == 0) { 208 if (num_children == 0) {
145 views::Label* label = new views::Label(l10n_util::GetStringUTF16( 209 views::Label* label = new views::Label(l10n_util::GetStringUTF16(
146 IDS_ASH_WEB_NOTFICATION_TRAY_NO_MESSAGES)); 210 IDS_ASH_WEB_NOTFICATION_TRAY_NO_MESSAGES));
147 label->SetFont(label->font().DeriveFont(1)); 211 label->SetFont(label->font().DeriveFont(1));
148 label->SetHorizontalAlignment(views::Label::ALIGN_CENTER); 212 label->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
149 label->SetEnabledColor(SK_ColorGRAY); 213 label->SetEnabledColor(SK_ColorGRAY);
150 scroll_content_->AddChildView(label); 214 scroll_content_->AddChildView(label);
151 button_view_->SetCloseAllVisible(false); 215 button_view_->SetCloseAllVisible(false);
152 } else { 216 } else {
153 button_view_->SetCloseAllVisible(true); 217 button_view_->SetCloseAllVisible(true);
154 } 218 }
155 SizeScrollContent(); 219 SizeScrollContent();
156 Layout(); 220 Layout();
157 if (GetWidget()) 221 if (GetWidget())
158 GetWidget()->GetRootView()->SchedulePaint(); 222 GetWidget()->GetRootView()->SchedulePaint();
159 } 223 }
160 224
161 size_t NumMessageViewsForTest() const { 225 size_t NumMessageViews() const {
162 return scroll_content_->child_count(); 226 return scroll_content_->child_count();
163 } 227 }
164 228
165 private: 229 private:
166 void SizeScrollContent() { 230 void SizeScrollContent() {
167 gfx::Size scroll_size = scroll_content_->GetPreferredSize(); 231 gfx::Size scroll_size = scroll_content_->GetPreferredSize();
168 const int button_height = button_view_->GetPreferredSize().height(); 232 const int button_height = button_view_->GetPreferredSize().height();
169 const int min_height = kWebNotificationBubbleMinHeight - button_height; 233 const int min_height = kWebNotificationBubbleMinHeight - button_height;
170 const int max_height = kWebNotificationBubbleMaxHeight - button_height; 234 const int max_height = kWebNotificationBubbleMaxHeight - button_height;
171 int scroll_height = std::min(std::max( 235 int scroll_height = std::min(std::max(
172 scroll_size.height(), min_height), max_height); 236 scroll_size.height(), min_height), max_height);
173 scroll_size.set_height(scroll_height); 237 scroll_size.set_height(scroll_height);
174 if (scroll_height == min_height) 238 if (scroll_height == min_height)
175 scroll_content_->set_preferred_size(scroll_size); 239 scroll_content_->set_preferred_size(scroll_size);
176 else 240 else
177 scroll_content_->set_preferred_size(gfx::Size()); 241 scroll_content_->set_preferred_size(gfx::Size());
178 scroller_->SetFixedSize(scroll_size); 242 scroller_->SetFixedSize(scroll_size);
179 scroller_->SizeToPreferredSize(); 243 scroller_->SizeToPreferredSize();
180 scroll_content_->InvalidateLayout(); 244 scroll_content_->InvalidateLayout();
181 } 245 }
182 246
183 WebNotificationTray* tray_; 247 WebNotificationList::Delegate* list_delegate_;
184 internal::FixedSizedScrollView* scroller_; 248 FixedSizedScrollView* scroller_;
185 ScrollContentView* scroll_content_; 249 ScrollContentView* scroll_content_;
186 WebNotificationButtonView* button_view_; 250 WebNotificationButtonView* button_view_;
187 251
188 DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView); 252 DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView);
189 }; 253 };
190 254
191 // Message Center Bubble. 255 // Message Center Bubble.
192 MessageCenterBubble::MessageCenterBubble(WebNotificationTray* tray) : 256 MessageCenterBubble::MessageCenterBubble(
193 WebNotificationBubble(tray), 257 WebNotificationList::Delegate* delegate)
194 contents_view_(NULL) { 258 : WebNotificationBubble(delegate),
195 TrayBubbleView::InitParams init_params = GetInitParams(); 259 contents_view_(NULL) {
196 init_params.max_height = message_center::kWebNotificationBubbleMaxHeight;
197 init_params.can_activate = true;
198 views::View* anchor = tray_->tray_container();
199 bubble_view_ = TrayBubbleView::Create(
200 tray_->GetBubbleWindowContainer(), anchor, this, &init_params);
201 contents_view_ = new MessageCenterContentsView(tray);
202
203 Initialize(contents_view_);
204 } 260 }
205 261
206 MessageCenterBubble::~MessageCenterBubble() {} 262 MessageCenterBubble::~MessageCenterBubble() {}
207 263
208 size_t MessageCenterBubble::NumMessageViewsForTest() const { 264 TrayBubbleView::InitParams MessageCenterBubble::GetInitParams(
209 return contents_view_->NumMessageViewsForTest(); 265 TrayBubbleView::AnchorAlignment anchor_alignment) {
266 TrayBubbleView::InitParams init_params =
267 GetDefaultInitParams(anchor_alignment);
268 init_params.max_height = message_center::kWebNotificationBubbleMaxHeight;
269 init_params.can_activate = true;
270 return init_params;
210 } 271 }
211 272
212 void MessageCenterBubble::BubbleViewDestroyed() { 273 void MessageCenterBubble::InitializeContents(TrayBubbleView* bubble_view) {
274 bubble_view_ = bubble_view;
275 contents_view_ = new MessageCenterContentsView(list_delegate_);
276 bubble_view_->AddChildView(contents_view_);
277 UpdateBubbleView();
278 contents_view_->FocusContents();
279 }
280
281 void MessageCenterBubble::OnBubbleViewDestroyed() {
213 contents_view_ = NULL; 282 contents_view_ = NULL;
214 WebNotificationBubble::BubbleViewDestroyed();
215 } 283 }
216 284
217 void MessageCenterBubble::UpdateBubbleView() { 285 void MessageCenterBubble::UpdateBubbleView() {
218 contents_view_->Update(tray_->notification_list()->notifications()); 286 if (!bubble_view_)
287 return; // Could get called after view is closed
288 contents_view_->Update(
289 list_delegate_->GetNotificationList()->notifications());
219 bubble_view_->Show(); 290 bubble_view_->Show();
220 bubble_view_->UpdateBubble(); 291 bubble_view_->UpdateBubble();
221 } 292 }
222 293
294 void MessageCenterBubble::OnMouseEnteredView() {
295 }
296
297 void MessageCenterBubble::OnMouseExitedView() {
298 }
299
300 size_t MessageCenterBubble::NumMessageViewsForTest() const {
301 return contents_view_->NumMessageViews();
302 }
303
223 } // namespace message_center 304 } // namespace message_center
224
225 } // namespace ash
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698