blob: d12f92be515510ffbaf975612807f155af7eb74b [file] [log] [blame]
[email protected]adbc18d2012-09-27 16:24:201// 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/web_notification/message_center_bubble.h"
6
7#include "ash/system/tray/tray_constants.h"
8#include "ash/system/tray/tray_views.h"
[email protected]adbc18d2012-09-27 16:24:209#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"
12#include "grit/ash_strings.h"
13#include "ui/base/l10n/l10n_util.h"
14#include "ui/base/resource/resource_bundle.h"
15#include "ui/gfx/size.h"
16#include "ui/views/controls/label.h"
17#include "ui/views/layout/box_layout.h"
18#include "ui/views/layout/grid_layout.h"
19#include "ui/views/painter.h"
20#include "ui/views/view.h"
21#include "ui/views/widget/widget.h"
22
23namespace ash {
24
25using internal::TrayBubbleView;
26using internal::TrayPopupTextButton;
27
28namespace message_center {
29
30// Web Notification Bubble constants
31const int kWebNotificationBubbleMinHeight = 80;
32const int kWebNotificationBubbleMaxHeight = 400;
33
34// The view for the buttons at the bottom of the web notification tray.
35class WebNotificationButtonView : public views::View,
36 public views::ButtonListener {
37 public:
38 explicit WebNotificationButtonView(WebNotificationTray* tray)
39 : tray_(tray),
40 close_all_button_(NULL) {
41 set_background(views::Background::CreateBackgroundPainter(
42 true,
43 views::Painter::CreateVerticalGradient(
44 kHeaderBackgroundColorLight,
45 kHeaderBackgroundColorDark)));
46 set_border(views::Border::CreateSolidSidedBorder(
47 2, 0, 0, 0, ash::kBorderDarkColor));
48
49 views::GridLayout* layout = new views::GridLayout(this);
50 SetLayoutManager(layout);
51 views::ColumnSet* columns = layout->AddColumnSet(0);
52 columns->AddPaddingColumn(100, 0);
53 columns->AddColumn(views::GridLayout::TRAILING, views::GridLayout::CENTER,
54 0, /* resize percent */
55 views::GridLayout::USE_PREF, 0, 0);
56
57 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
58 close_all_button_ = new TrayPopupTextButton(
59 this, rb.GetLocalizedString(IDS_ASH_WEB_NOTFICATION_TRAY_CLEAR_ALL));
60
61 layout->StartRow(0, 0);
62 layout->AddView(close_all_button_);
63 }
64
65 virtual ~WebNotificationButtonView() {}
66
67 void SetCloseAllVisible(bool visible) {
68 close_all_button_->SetVisible(visible);
69 }
70
71 // Overridden from ButtonListener.
72 virtual void ButtonPressed(views::Button* sender,
73 const ui::Event& event) OVERRIDE {
74 if (sender == close_all_button_)
75 tray_->SendRemoveAllNotifications();
76 }
77
78 private:
79 WebNotificationTray* tray_;
80 internal::TrayPopupTextButton* close_all_button_;
81
82 DISALLOW_COPY_AND_ASSIGN(WebNotificationButtonView);
83};
84
85
86// Message Center contents.
[email protected]3f1823c2012-10-08 19:41:2187class MessageCenterContentsView : public views::View {
[email protected]adbc18d2012-09-27 16:24:2088 public:
89 class ScrollContentView : public views::View {
90 public:
91 ScrollContentView() {
92 views::BoxLayout* layout =
93 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1);
94 layout->set_spread_blank_space(true);
95 SetLayoutManager(layout);
96 }
97
98 virtual ~ScrollContentView() {
99 }
100
101 virtual gfx::Size GetPreferredSize() OVERRIDE {
102 if (!preferred_size_.IsEmpty())
103 return preferred_size_;
104 return views::View::GetPreferredSize();
105 }
106
107 void set_preferred_size(const gfx::Size& size) { preferred_size_ = size; }
108
109 private:
110 gfx::Size preferred_size_;
111 DISALLOW_COPY_AND_ASSIGN(ScrollContentView);
112 };
113
114 explicit MessageCenterContentsView(WebNotificationTray* tray)
[email protected]3f1823c2012-10-08 19:41:21115 : tray_(tray) {
[email protected]adbc18d2012-09-27 16:24:20116 SetLayoutManager(
117 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1));
[email protected]adbc18d2012-09-27 16:24:20118
119 scroll_content_ = new ScrollContentView;
120 scroller_ = new internal::FixedSizedScrollView;
121 scroller_->SetContentsView(scroll_content_);
122 AddChildView(scroller_);
123
124 scroller_->SetPaintToLayer(true);
125 scroller_->SetFillsBoundsOpaquely(false);
126 scroller_->layer()->SetMasksToBounds(true);
127
128 button_view_ = new WebNotificationButtonView(tray);
129 AddChildView(button_view_);
130 }
131
132 void Update(const WebNotificationList::Notifications& notifications) {
133 scroll_content_->RemoveAllChildViews(true);
134 scroll_content_->set_preferred_size(gfx::Size());
135 size_t num_children = 0;
136 for (WebNotificationList::Notifications::const_iterator iter =
137 notifications.begin(); iter != notifications.end(); ++iter) {
[email protected]3f1823c2012-10-08 19:41:21138 WebNotificationView* view =
139 new WebNotificationView(tray_, *iter, scroller_->GetScrollBarWidth());
[email protected]adbc18d2012-09-27 16:24:20140 view->set_scroller(scroller_);
141 scroll_content_->AddChildView(view);
142 if (++num_children >= WebNotificationTray::kMaxVisibleTrayNotifications)
143 break;
144 }
145 if (num_children == 0) {
146 views::Label* label = new views::Label(l10n_util::GetStringUTF16(
147 IDS_ASH_WEB_NOTFICATION_TRAY_NO_MESSAGES));
148 label->SetFont(label->font().DeriveFont(1));
149 label->SetHorizontalAlignment(views::Label::ALIGN_CENTER);
150 label->SetEnabledColor(SK_ColorGRAY);
151 scroll_content_->AddChildView(label);
152 button_view_->SetCloseAllVisible(false);
153 } else {
154 button_view_->SetCloseAllVisible(true);
155 }
156 SizeScrollContent();
157 Layout();
158 if (GetWidget())
159 GetWidget()->GetRootView()->SchedulePaint();
160 }
161
162 size_t NumMessageViewsForTest() const {
163 return scroll_content_->child_count();
164 }
165
166 private:
167 void SizeScrollContent() {
168 gfx::Size scroll_size = scroll_content_->GetPreferredSize();
169 const int button_height = button_view_->GetPreferredSize().height();
170 const int min_height = kWebNotificationBubbleMinHeight - button_height;
171 const int max_height = kWebNotificationBubbleMaxHeight - button_height;
172 int scroll_height = std::min(std::max(
173 scroll_size.height(), min_height), max_height);
174 scroll_size.set_height(scroll_height);
175 if (scroll_height == min_height)
176 scroll_content_->set_preferred_size(scroll_size);
177 else
178 scroll_content_->set_preferred_size(gfx::Size());
179 scroller_->SetFixedSize(scroll_size);
180 scroller_->SizeToPreferredSize();
[email protected]3f1823c2012-10-08 19:41:21181 scroll_content_->InvalidateLayout();
[email protected]adbc18d2012-09-27 16:24:20182 }
183
[email protected]3f1823c2012-10-08 19:41:21184 WebNotificationTray* tray_;
[email protected]adbc18d2012-09-27 16:24:20185 internal::FixedSizedScrollView* scroller_;
186 ScrollContentView* scroll_content_;
187 WebNotificationButtonView* button_view_;
188
189 DISALLOW_COPY_AND_ASSIGN(MessageCenterContentsView);
190};
191
192// Message Center Bubble.
193MessageCenterBubble::MessageCenterBubble(WebNotificationTray* tray) :
194 WebNotificationBubble(tray),
195 contents_view_(NULL) {
196 TrayBubbleView::InitParams init_params = GetInitParams();
197 init_params.max_height = message_center::kWebNotificationBubbleMaxHeight;
198 init_params.can_activate = true;
199 views::View* anchor = tray_->tray_container();
200 bubble_view_ = TrayBubbleView::Create(anchor, this, init_params);
201 contents_view_ = new MessageCenterContentsView(tray);
202
203 Initialize(contents_view_);
204}
205
206MessageCenterBubble::~MessageCenterBubble() {}
207
208size_t MessageCenterBubble::NumMessageViewsForTest() const {
209 return contents_view_->NumMessageViewsForTest();
210}
211
212void MessageCenterBubble::BubbleViewDestroyed() {
213 contents_view_ = NULL;
214 WebNotificationBubble::BubbleViewDestroyed();
215}
216
217void MessageCenterBubble::UpdateBubbleView() {
218 contents_view_->Update(tray_->notification_list()->notifications());
219 bubble_view_->Show();
220 bubble_view_->UpdateBubble();
221}
222
223void MessageCenterBubble::OnClickedOutsideView() {
224 // May delete |this|.
225 tray_->HideMessageCenterBubble();
226}
227
228} // namespace message_center
229
230} // namespace ash