| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 "ui/message_center/views/message_center_view.h" | 5 #include "ui/message_center/views/message_center_view.h" |
| 6 | 6 |
| 7 #include <list> | 7 #include <list> |
| 8 #include <map> | 8 #include <map> |
| 9 | 9 |
| 10 #include "base/command_line.h" | |
| 11 #include "base/memory/weak_ptr.h" | 10 #include "base/memory/weak_ptr.h" |
| 12 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 13 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
| 14 #include "ui/base/l10n/l10n_util.h" | 13 #include "ui/base/l10n/l10n_util.h" |
| 15 #include "ui/gfx/animation/multi_animation.h" | 14 #include "ui/gfx/animation/multi_animation.h" |
| 16 #include "ui/gfx/animation/slide_animation.h" | |
| 17 #include "ui/gfx/canvas.h" | 15 #include "ui/gfx/canvas.h" |
| 18 #include "ui/gfx/geometry/insets.h" | 16 #include "ui/gfx/geometry/insets.h" |
| 19 #include "ui/gfx/geometry/rect.h" | 17 #include "ui/gfx/geometry/rect.h" |
| 20 #include "ui/gfx/geometry/size.h" | 18 #include "ui/gfx/geometry/size.h" |
| 21 #include "ui/message_center/message_center.h" | 19 #include "ui/message_center/message_center.h" |
| 22 #include "ui/message_center/message_center_style.h" | 20 #include "ui/message_center/message_center_style.h" |
| 23 #include "ui/message_center/message_center_switches.h" | |
| 24 #include "ui/message_center/message_center_tray.h" | 21 #include "ui/message_center/message_center_tray.h" |
| 25 #include "ui/message_center/message_center_types.h" | 22 #include "ui/message_center/message_center_types.h" |
| 26 #include "ui/message_center/views/message_center_button_bar.h" | 23 #include "ui/message_center/views/message_center_button_bar.h" |
| 24 #include "ui/message_center/views/message_list_view.h" |
| 27 #include "ui/message_center/views/message_view.h" | 25 #include "ui/message_center/views/message_view.h" |
| 28 #include "ui/message_center/views/message_view_context_menu_controller.h" | 26 #include "ui/message_center/views/message_view_context_menu_controller.h" |
| 29 #include "ui/message_center/views/notification_view.h" | 27 #include "ui/message_center/views/notification_view.h" |
| 30 #include "ui/message_center/views/notifier_settings_view.h" | 28 #include "ui/message_center/views/notifier_settings_view.h" |
| 31 #include "ui/resources/grit/ui_resources.h" | 29 #include "ui/resources/grit/ui_resources.h" |
| 32 #include "ui/strings/grit/ui_strings.h" | 30 #include "ui/strings/grit/ui_strings.h" |
| 33 #include "ui/views/animation/bounds_animator.h" | |
| 34 #include "ui/views/animation/bounds_animator_observer.h" | |
| 35 #include "ui/views/background.h" | 31 #include "ui/views/background.h" |
| 36 #include "ui/views/border.h" | 32 #include "ui/views/border.h" |
| 37 #include "ui/views/controls/button/button.h" | 33 #include "ui/views/controls/button/button.h" |
| 38 #include "ui/views/controls/label.h" | 34 #include "ui/views/controls/label.h" |
| 39 #include "ui/views/controls/scroll_view.h" | 35 #include "ui/views/controls/scroll_view.h" |
| 40 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" | 36 #include "ui/views/controls/scrollbar/overlay_scroll_bar.h" |
| 41 #include "ui/views/layout/box_layout.h" | |
| 42 #include "ui/views/layout/fill_layout.h" | 37 #include "ui/views/layout/fill_layout.h" |
| 43 #include "ui/views/widget/widget.h" | 38 #include "ui/views/widget/widget.h" |
| 44 | 39 |
| 45 namespace message_center { | 40 namespace message_center { |
| 46 | 41 |
| 47 namespace { | 42 namespace { |
| 48 | 43 |
| 49 const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); | 44 const SkColor kNoNotificationsTextColor = SkColorSetRGB(0xb4, 0xb4, 0xb4); |
| 50 #if defined(OS_LINUX) && defined(OS_CHROMEOS) | 45 #if defined(OS_LINUX) && defined(OS_CHROMEOS) |
| 51 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); | 46 const SkColor kTransparentColor = SkColorSetARGB(0, 0, 0, 0); |
| 52 #endif | 47 #endif |
| 53 const int kAnimateClearingNextNotificationDelayMS = 40; | |
| 54 | 48 |
| 55 const int kDefaultAnimationDurationMs = 120; | 49 const int kDefaultAnimationDurationMs = 120; |
| 56 const int kDefaultFrameRateHz = 60; | 50 const int kDefaultFrameRateHz = 60; |
| 57 | 51 |
| 58 void SetViewHierarchyEnabled(views::View* view, bool enabled) { | 52 void SetViewHierarchyEnabled(views::View* view, bool enabled) { |
| 59 for (int i = 0; i < view->child_count(); i++) | 53 for (int i = 0; i < view->child_count(); i++) |
| 60 SetViewHierarchyEnabled(view->child_at(i), enabled); | 54 SetViewHierarchyEnabled(view->child_at(i), enabled); |
| 61 view->SetEnabled(enabled); | 55 view->SetEnabled(enabled); |
| 62 } | 56 } |
| 63 | 57 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 int NoNotificationMessageView::GetHeightForWidth(int width) const { | 96 int NoNotificationMessageView::GetHeightForWidth(int width) const { |
| 103 return kMinScrollViewHeight; | 97 return kMinScrollViewHeight; |
| 104 } | 98 } |
| 105 | 99 |
| 106 void NoNotificationMessageView::Layout() { | 100 void NoNotificationMessageView::Layout() { |
| 107 int text_height = label_->GetHeightForWidth(width()); | 101 int text_height = label_->GetHeightForWidth(width()); |
| 108 int margin = (height() - text_height) / 2; | 102 int margin = (height() - text_height) / 2; |
| 109 label_->SetBounds(0, margin, width(), text_height); | 103 label_->SetBounds(0, margin, width(), text_height); |
| 110 } | 104 } |
| 111 | 105 |
| 112 // Displays a list of messages for rich notifications. Functions as an array of | |
| 113 // MessageViews and animates them on transitions. It also supports | |
| 114 // repositioning. | |
| 115 class MessageListView : public views::View, | |
| 116 public views::BoundsAnimatorObserver { | |
| 117 public: | |
| 118 explicit MessageListView(MessageCenterView* message_center_view, | |
| 119 bool top_down); | |
| 120 ~MessageListView() override; | |
| 121 | |
| 122 void AddNotificationAt(MessageView* view, int i); | |
| 123 void RemoveNotification(MessageView* view); | |
| 124 void UpdateNotification(MessageView* view, const Notification& notification); | |
| 125 void SetRepositionTarget(const gfx::Rect& target_rect); | |
| 126 void ResetRepositionSession(); | |
| 127 void ClearAllNotifications(const gfx::Rect& visible_scroll_rect); | |
| 128 | |
| 129 protected: | |
| 130 // Overridden from views::View. | |
| 131 void Layout() override; | |
| 132 gfx::Size GetPreferredSize() const override; | |
| 133 int GetHeightForWidth(int width) const override; | |
| 134 void PaintChildren(const ui::PaintContext& context) override; | |
| 135 void ReorderChildLayers(ui::Layer* parent_layer) override; | |
| 136 | |
| 137 // Overridden from views::BoundsAnimatorObserver. | |
| 138 void OnBoundsAnimatorProgressed(views::BoundsAnimator* animator) override; | |
| 139 void OnBoundsAnimatorDone(views::BoundsAnimator* animator) override; | |
| 140 | |
| 141 private: | |
| 142 bool IsValidChild(const views::View* child) const; | |
| 143 void DoUpdateIfPossible(); | |
| 144 | |
| 145 // Animates all notifications below target upwards to align with the top of | |
| 146 // the last closed notification. | |
| 147 void AnimateNotificationsBelowTarget(); | |
| 148 // Animates all notifications above target downwards to align with the top of | |
| 149 // the last closed notification. | |
| 150 void AnimateNotificationsAboveTarget(); | |
| 151 | |
| 152 // Schedules animation for a child to the specified position. Returns false | |
| 153 // if |child| will disappear after the animation. | |
| 154 bool AnimateChild(views::View* child, int top, int height); | |
| 155 | |
| 156 // Animate clearing one notification. | |
| 157 void AnimateClearingOneNotification(); | |
| 158 MessageCenterView* message_center_view() const { | |
| 159 return message_center_view_; | |
| 160 } | |
| 161 | |
| 162 MessageCenterView* message_center_view_; // Weak reference. | |
| 163 // The top position of the reposition target rectangle. | |
| 164 int reposition_top_; | |
| 165 int fixed_height_; | |
| 166 bool has_deferred_task_; | |
| 167 bool clear_all_started_; | |
| 168 bool top_down_; | |
| 169 std::set<views::View*> adding_views_; | |
| 170 std::set<views::View*> deleting_views_; | |
| 171 std::set<views::View*> deleted_when_done_; | |
| 172 std::list<views::View*> clearing_all_views_; | |
| 173 scoped_ptr<views::BoundsAnimator> animator_; | |
| 174 base::WeakPtrFactory<MessageListView> weak_ptr_factory_; | |
| 175 | |
| 176 DISALLOW_COPY_AND_ASSIGN(MessageListView); | |
| 177 }; | |
| 178 | |
| 179 MessageListView::MessageListView(MessageCenterView* message_center_view, | |
| 180 bool top_down) | |
| 181 : message_center_view_(message_center_view), | |
| 182 reposition_top_(-1), | |
| 183 fixed_height_(0), | |
| 184 has_deferred_task_(false), | |
| 185 clear_all_started_(false), | |
| 186 top_down_(top_down), | |
| 187 weak_ptr_factory_(this) { | |
| 188 views::BoxLayout* layout = | |
| 189 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 1); | |
| 190 layout->SetDefaultFlex(1); | |
| 191 SetLayoutManager(layout); | |
| 192 | |
| 193 // Set the margin to 0 for the layout. BoxLayout assumes the same margin | |
| 194 // for top and bottom, but the bottom margin here should be smaller | |
| 195 // because of the shadow of message view. Use an empty border instead | |
| 196 // to provide this margin. | |
| 197 gfx::Insets shadow_insets = MessageView::GetShadowInsets(); | |
| 198 set_background(views::Background::CreateSolidBackground( | |
| 199 kMessageCenterBackgroundColor)); | |
| 200 SetBorder(views::Border::CreateEmptyBorder( | |
| 201 top_down ? 0 : kMarginBetweenItems - shadow_insets.top(), /* top */ | |
| 202 kMarginBetweenItems - shadow_insets.left(), /* left */ | |
| 203 top_down ? kMarginBetweenItems - shadow_insets.bottom() : 0, /* bottom */ | |
| 204 kMarginBetweenItems - shadow_insets.right() /* right */)); | |
| 205 } | |
| 206 | |
| 207 MessageListView::~MessageListView() { | |
| 208 if (animator_.get()) | |
| 209 animator_->RemoveObserver(this); | |
| 210 } | |
| 211 | |
| 212 void MessageListView::Layout() { | |
| 213 if (animator_.get()) | |
| 214 return; | |
| 215 | |
| 216 gfx::Rect child_area = GetContentsBounds(); | |
| 217 int top = child_area.y(); | |
| 218 int between_items = | |
| 219 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
| 220 | |
| 221 for (int i = 0; i < child_count(); ++i) { | |
| 222 views::View* child = child_at(i); | |
| 223 if (!child->visible()) | |
| 224 continue; | |
| 225 int height = child->GetHeightForWidth(child_area.width()); | |
| 226 child->SetBounds(child_area.x(), top, child_area.width(), height); | |
| 227 top += height + between_items; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 void MessageListView::AddNotificationAt(MessageView* view, int index) { | |
| 232 // |index| refers to a position in a subset of valid children. |real_index| | |
| 233 // in a list includes the invalid children, so we compute the real index by | |
| 234 // walking the list until |index| number of valid children are encountered, | |
| 235 // or to the end of the list. | |
| 236 int real_index = 0; | |
| 237 while (real_index < child_count()) { | |
| 238 if (IsValidChild(child_at(real_index))) { | |
| 239 --index; | |
| 240 if (index < 0) | |
| 241 break; | |
| 242 } | |
| 243 ++real_index; | |
| 244 } | |
| 245 | |
| 246 AddChildViewAt(view, real_index); | |
| 247 if (GetContentsBounds().IsEmpty()) | |
| 248 return; | |
| 249 | |
| 250 adding_views_.insert(view); | |
| 251 DoUpdateIfPossible(); | |
| 252 } | |
| 253 | |
| 254 void MessageListView::RemoveNotification(MessageView* view) { | |
| 255 DCHECK_EQ(view->parent(), this); | |
| 256 if (GetContentsBounds().IsEmpty()) { | |
| 257 delete view; | |
| 258 } else { | |
| 259 if (view->layer()) { | |
| 260 deleting_views_.insert(view); | |
| 261 } else { | |
| 262 if (animator_.get()) | |
| 263 animator_->StopAnimatingView(view); | |
| 264 delete view; | |
| 265 } | |
| 266 DoUpdateIfPossible(); | |
| 267 } | |
| 268 } | |
| 269 | |
| 270 void MessageListView::UpdateNotification(MessageView* view, | |
| 271 const Notification& notification) { | |
| 272 int index = GetIndexOf(view); | |
| 273 DCHECK_LE(0, index); // GetIndexOf is negative if not a child. | |
| 274 | |
| 275 if (animator_.get()) | |
| 276 animator_->StopAnimatingView(view); | |
| 277 if (deleting_views_.find(view) != deleting_views_.end()) | |
| 278 deleting_views_.erase(view); | |
| 279 if (deleted_when_done_.find(view) != deleted_when_done_.end()) | |
| 280 deleted_when_done_.erase(view); | |
| 281 view->UpdateWithNotification(notification); | |
| 282 DoUpdateIfPossible(); | |
| 283 } | |
| 284 | |
| 285 gfx::Size MessageListView::GetPreferredSize() const { | |
| 286 int width = 0; | |
| 287 for (int i = 0; i < child_count(); i++) { | |
| 288 const views::View* child = child_at(i); | |
| 289 if (IsValidChild(child)) | |
| 290 width = std::max(width, child->GetPreferredSize().width()); | |
| 291 } | |
| 292 | |
| 293 return gfx::Size(width + GetInsets().width(), | |
| 294 GetHeightForWidth(width + GetInsets().width())); | |
| 295 } | |
| 296 | |
| 297 int MessageListView::GetHeightForWidth(int width) const { | |
| 298 if (fixed_height_ > 0) | |
| 299 return fixed_height_; | |
| 300 | |
| 301 width -= GetInsets().width(); | |
| 302 int height = 0; | |
| 303 int padding = 0; | |
| 304 for (int i = 0; i < child_count(); ++i) { | |
| 305 const views::View* child = child_at(i); | |
| 306 if (!IsValidChild(child)) | |
| 307 continue; | |
| 308 height += child->GetHeightForWidth(width) + padding; | |
| 309 padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
| 310 } | |
| 311 | |
| 312 return height + GetInsets().height(); | |
| 313 } | |
| 314 | |
| 315 void MessageListView::PaintChildren(const ui::PaintContext& context) { | |
| 316 // Paint in the inversed order. Otherwise upper notification may be | |
| 317 // hidden by the lower one. | |
| 318 for (int i = child_count() - 1; i >= 0; --i) { | |
| 319 if (!child_at(i)->layer()) | |
| 320 child_at(i)->Paint(context); | |
| 321 } | |
| 322 } | |
| 323 | |
| 324 void MessageListView::ReorderChildLayers(ui::Layer* parent_layer) { | |
| 325 // Reorder children to stack the last child layer at the top. Otherwise | |
| 326 // upper notification may be hidden by the lower one. | |
| 327 for (int i = 0; i < child_count(); ++i) { | |
| 328 if (child_at(i)->layer()) | |
| 329 parent_layer->StackAtBottom(child_at(i)->layer()); | |
| 330 } | |
| 331 } | |
| 332 | |
| 333 void MessageListView::SetRepositionTarget(const gfx::Rect& target) { | |
| 334 reposition_top_ = target.y(); | |
| 335 fixed_height_ = GetHeightForWidth(width()); | |
| 336 } | |
| 337 | |
| 338 void MessageListView::ResetRepositionSession() { | |
| 339 // Don't call DoUpdateIfPossible(), but let Layout() do the task without | |
| 340 // animation. Reset will cause the change of the bubble size itself, and | |
| 341 // animation from the old location will look weird. | |
| 342 if (reposition_top_ >= 0 && animator_.get()) { | |
| 343 has_deferred_task_ = false; | |
| 344 // cancel cause OnBoundsAnimatorDone which deletes |deleted_when_done_|. | |
| 345 animator_->Cancel(); | |
| 346 STLDeleteContainerPointers(deleting_views_.begin(), deleting_views_.end()); | |
| 347 deleting_views_.clear(); | |
| 348 adding_views_.clear(); | |
| 349 animator_.reset(); | |
| 350 } | |
| 351 | |
| 352 reposition_top_ = -1; | |
| 353 fixed_height_ = 0; | |
| 354 } | |
| 355 | |
| 356 void MessageListView::ClearAllNotifications( | |
| 357 const gfx::Rect& visible_scroll_rect) { | |
| 358 for (int i = 0; i < child_count(); ++i) { | |
| 359 views::View* child = child_at(i); | |
| 360 if (!child->visible()) | |
| 361 continue; | |
| 362 if (gfx::IntersectRects(child->bounds(), visible_scroll_rect).IsEmpty()) | |
| 363 continue; | |
| 364 clearing_all_views_.push_back(child); | |
| 365 } | |
| 366 DoUpdateIfPossible(); | |
| 367 } | |
| 368 | |
| 369 void MessageListView::OnBoundsAnimatorProgressed( | |
| 370 views::BoundsAnimator* animator) { | |
| 371 DCHECK_EQ(animator_.get(), animator); | |
| 372 for (std::set<views::View*>::iterator iter = deleted_when_done_.begin(); | |
| 373 iter != deleted_when_done_.end(); ++iter) { | |
| 374 const gfx::SlideAnimation* animation = animator->GetAnimationForView(*iter); | |
| 375 if (animation) | |
| 376 (*iter)->layer()->SetOpacity(animation->CurrentValueBetween(1.0, 0.0)); | |
| 377 } | |
| 378 } | |
| 379 | |
| 380 void MessageListView::OnBoundsAnimatorDone(views::BoundsAnimator* animator) { | |
| 381 STLDeleteContainerPointers( | |
| 382 deleted_when_done_.begin(), deleted_when_done_.end()); | |
| 383 deleted_when_done_.clear(); | |
| 384 | |
| 385 if (clear_all_started_) { | |
| 386 clear_all_started_ = false; | |
| 387 message_center_view()->OnAllNotificationsCleared(); | |
| 388 } | |
| 389 | |
| 390 if (has_deferred_task_) { | |
| 391 has_deferred_task_ = false; | |
| 392 DoUpdateIfPossible(); | |
| 393 } | |
| 394 | |
| 395 if (GetWidget()) | |
| 396 GetWidget()->SynthesizeMouseMoveEvent(); | |
| 397 } | |
| 398 | |
| 399 bool MessageListView::IsValidChild(const views::View* child) const { | |
| 400 return child->visible() && | |
| 401 deleting_views_.find(const_cast<views::View*>(child)) == | |
| 402 deleting_views_.end() && | |
| 403 deleted_when_done_.find(const_cast<views::View*>(child)) == | |
| 404 deleted_when_done_.end(); | |
| 405 } | |
| 406 | |
| 407 void MessageListView::DoUpdateIfPossible() { | |
| 408 gfx::Rect child_area = GetContentsBounds(); | |
| 409 if (child_area.IsEmpty()) | |
| 410 return; | |
| 411 | |
| 412 if (animator_.get() && animator_->IsAnimating()) { | |
| 413 has_deferred_task_ = true; | |
| 414 return; | |
| 415 } | |
| 416 | |
| 417 if (!animator_.get()) { | |
| 418 animator_.reset(new views::BoundsAnimator(this)); | |
| 419 animator_->AddObserver(this); | |
| 420 } | |
| 421 | |
| 422 if (!clearing_all_views_.empty()) { | |
| 423 AnimateClearingOneNotification(); | |
| 424 return; | |
| 425 } | |
| 426 | |
| 427 if (top_down_ || | |
| 428 base::CommandLine::ForCurrentProcess()->HasSwitch( | |
| 429 switches::kEnableMessageCenterAlwaysScrollUpUponNotificationRemoval)) | |
| 430 AnimateNotificationsBelowTarget(); | |
| 431 else | |
| 432 AnimateNotificationsAboveTarget(); | |
| 433 | |
| 434 adding_views_.clear(); | |
| 435 deleting_views_.clear(); | |
| 436 } | |
| 437 | |
| 438 void MessageListView::AnimateNotificationsBelowTarget() { | |
| 439 int last_index = -1; | |
| 440 for (int i = 0; i < child_count(); ++i) { | |
| 441 views::View* child = child_at(i); | |
| 442 if (!IsValidChild(child)) { | |
| 443 AnimateChild(child, child->y(), child->height()); | |
| 444 } else if (reposition_top_ < 0 || child->y() > reposition_top_) { | |
| 445 // Find first notification below target (or all notifications if no | |
| 446 // target). | |
| 447 last_index = i; | |
| 448 break; | |
| 449 } | |
| 450 } | |
| 451 if (last_index > 0) { | |
| 452 int between_items = | |
| 453 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
| 454 int top = (reposition_top_ > 0) ? reposition_top_ : GetInsets().top(); | |
| 455 | |
| 456 for (int i = last_index; i < child_count(); ++i) { | |
| 457 // Animate notifications below target upwards. | |
| 458 views::View* child = child_at(i); | |
| 459 if (AnimateChild(child, top, child->height())) | |
| 460 top += child->height() + between_items; | |
| 461 } | |
| 462 } | |
| 463 } | |
| 464 | |
| 465 void MessageListView::AnimateNotificationsAboveTarget() { | |
| 466 int last_index = -1; | |
| 467 for (int i = child_count() - 1; i >= 0; --i) { | |
| 468 views::View* child = child_at(i); | |
| 469 if (!IsValidChild(child)) { | |
| 470 AnimateChild(child, child->y(), child->height()); | |
| 471 } else if (reposition_top_ < 0 || child->y() < reposition_top_) { | |
| 472 // Find first notification above target (or all notifications if no | |
| 473 // target). | |
| 474 last_index = i; | |
| 475 break; | |
| 476 } | |
| 477 } | |
| 478 if (last_index >= 0) { | |
| 479 int between_items = | |
| 480 kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | |
| 481 int bottom = (reposition_top_ > 0) | |
| 482 ? reposition_top_ + child_at(last_index)->height() | |
| 483 : GetHeightForWidth(width()) - GetInsets().bottom(); | |
| 484 for (int i = last_index; i >= 0; --i) { | |
| 485 // Animate notifications above target downwards. | |
| 486 views::View* child = child_at(i); | |
| 487 if (AnimateChild(child, bottom - child->height(), child->height())) | |
| 488 bottom -= child->height() + between_items; | |
| 489 } | |
| 490 } | |
| 491 } | |
| 492 | |
| 493 bool MessageListView::AnimateChild(views::View* child, int top, int height) { | |
| 494 gfx::Rect child_area = GetContentsBounds(); | |
| 495 if (adding_views_.find(child) != adding_views_.end()) { | |
| 496 child->SetBounds(child_area.right(), top, child_area.width(), height); | |
| 497 animator_->AnimateViewTo( | |
| 498 child, gfx::Rect(child_area.x(), top, child_area.width(), height)); | |
| 499 } else if (deleting_views_.find(child) != deleting_views_.end()) { | |
| 500 DCHECK(child->layer()); | |
| 501 // No moves, but animate to fade-out. | |
| 502 animator_->AnimateViewTo(child, child->bounds()); | |
| 503 deleted_when_done_.insert(child); | |
| 504 return false; | |
| 505 } else { | |
| 506 gfx::Rect target(child_area.x(), top, child_area.width(), height); | |
| 507 if (child->bounds().origin() != target.origin()) | |
| 508 animator_->AnimateViewTo(child, target); | |
| 509 else | |
| 510 child->SetBoundsRect(target); | |
| 511 } | |
| 512 return true; | |
| 513 } | |
| 514 | |
| 515 void MessageListView::AnimateClearingOneNotification() { | |
| 516 DCHECK(!clearing_all_views_.empty()); | |
| 517 | |
| 518 clear_all_started_ = true; | |
| 519 | |
| 520 views::View* child = clearing_all_views_.front(); | |
| 521 clearing_all_views_.pop_front(); | |
| 522 | |
| 523 // Slide from left to right. | |
| 524 gfx::Rect new_bounds = child->bounds(); | |
| 525 new_bounds.set_x(new_bounds.right() + kMarginBetweenItems); | |
| 526 animator_->AnimateViewTo(child, new_bounds); | |
| 527 | |
| 528 // Schedule to start sliding out next notification after a short delay. | |
| 529 if (!clearing_all_views_.empty()) { | |
| 530 base::MessageLoop::current()->PostDelayedTask( | |
| 531 FROM_HERE, | |
| 532 base::Bind(&MessageListView::AnimateClearingOneNotification, | |
| 533 weak_ptr_factory_.GetWeakPtr()), | |
| 534 base::TimeDelta::FromMilliseconds( | |
| 535 kAnimateClearingNextNotificationDelayMS)); | |
| 536 } | |
| 537 } | |
| 538 | |
| 539 // MessageCenterView /////////////////////////////////////////////////////////// | 106 // MessageCenterView /////////////////////////////////////////////////////////// |
| 540 | 107 |
| 541 MessageCenterView::MessageCenterView(MessageCenter* message_center, | 108 MessageCenterView::MessageCenterView(MessageCenter* message_center, |
| 542 MessageCenterTray* tray, | 109 MessageCenterTray* tray, |
| 543 int max_height, | 110 int max_height, |
| 544 bool initially_settings_visible, | 111 bool initially_settings_visible, |
| 545 bool top_down, | 112 bool top_down, |
| 546 const base::string16& title) | 113 const base::string16& title) |
| 547 : message_center_(message_center), | 114 : message_center_(message_center), |
| 548 tray_(tray), | 115 tray_(tray), |
| (...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 scroller_->InvalidateLayout(); | 573 scroller_->InvalidateLayout(); |
| 1007 PreferredSizeChanged(); | 574 PreferredSizeChanged(); |
| 1008 Layout(); | 575 Layout(); |
| 1009 } | 576 } |
| 1010 | 577 |
| 1011 void MessageCenterView::SetNotificationViewForTest(MessageView* view) { | 578 void MessageCenterView::SetNotificationViewForTest(MessageView* view) { |
| 1012 message_list_view_->AddNotificationAt(view, 0); | 579 message_list_view_->AddNotificationAt(view, 0); |
| 1013 } | 580 } |
| 1014 | 581 |
| 1015 } // namespace message_center | 582 } // namespace message_center |
| OLD | NEW |