OLD | NEW |
---|---|
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 | |
OLD | NEW |