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