| OLD | NEW |
| 1 // Copyright (c) 2015 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2015 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 "base/command_line.h" | 5 #include "base/command_line.h" |
| 6 #include "base/location.h" | 6 #include "base/location.h" |
| 7 #include "base/single_thread_task_runner.h" | 7 #include "base/single_thread_task_runner.h" |
| 8 #include "base/threading/thread_task_runner_handle.h" | 8 #include "base/threading/thread_task_runner_handle.h" |
| 9 #include "ui/gfx/animation/slide_animation.h" | 9 #include "ui/gfx/animation/slide_animation.h" |
| 10 #include "ui/message_center/message_center_style.h" | 10 #include "ui/message_center/message_center_style.h" |
| (...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 340 |
| 341 // Layout the items below the target (or all items if target is unavailable). | 341 // Layout the items below the target (or all items if target is unavailable). |
| 342 for (int i = target_index + 1; i < child_count(); ++i) { | 342 for (int i = target_index + 1; i < child_count(); ++i) { |
| 343 views::View* child = child_at(i); | 343 views::View* child = child_at(i); |
| 344 int height = child->GetHeightForWidth(child_area.width()); | 344 int height = child->GetHeightForWidth(child_area.width()); |
| 345 if (AnimateChild(child, top, height, true /* animate_on_move */)) | 345 if (AnimateChild(child, top, height, true /* animate_on_move */)) |
| 346 top += height + padding; | 346 top += height + padding; |
| 347 } | 347 } |
| 348 } | 348 } |
| 349 | 349 |
| 350 std::vector<int> MessageListView::ComputeRepositionOffsets( |
| 351 const std::vector<int>& heights, |
| 352 const std::vector<bool>& deleting, |
| 353 int target_index, |
| 354 int padding) { |
| 355 DCHECK_EQ(heights.size(), deleting.size()); |
| 356 // Calculate the vertical length between the top of message list and the top |
| 357 // of target. This is to shrink or expand the height of the message list |
| 358 // when the notifications above the target is changed. |
| 359 int vertical_gap_to_target_from_top = GetInsets().top(); |
| 360 for (int i = 0; i < target_index; i++) { |
| 361 if (!deleting[i]) |
| 362 vertical_gap_to_target_from_top += heights[i] + padding; |
| 363 } |
| 364 |
| 365 // If the calculated length is changed from |repositon_top_|, it means that |
| 366 // some of items above the target are updated and their height are changed. |
| 367 // Adjust the vertical length above the target. |
| 368 fixed_height_ -= reposition_top_ - vertical_gap_to_target_from_top; |
| 369 reposition_top_ = vertical_gap_to_target_from_top; |
| 370 |
| 371 std::vector<int> positions; |
| 372 positions.reserve(heights.size()); |
| 373 // Layout the items above the target. |
| 374 int y = GetInsets().top(); |
| 375 for (int i = 0; i < target_index; i++) { |
| 376 positions.push_back(y); |
| 377 if (!deleting[i]) |
| 378 y += heights[i] + padding; |
| 379 } |
| 380 DCHECK_EQ(y, reposition_top_); |
| 381 |
| 382 // Match the top with |reposition_top_|. |
| 383 y = reposition_top_; |
| 384 // Layout the target and the items below the target. |
| 385 for (int i = target_index; i < int(heights.size()); i++) { |
| 386 positions.push_back(y); |
| 387 if (!deleting[i]) |
| 388 y += heights[i] + padding; |
| 389 } |
| 390 // If the target view, or any views below it expand they might exceed |
| 391 // |fixed_height_|. Rather than letting them push out the bottom and be |
| 392 // clipped, instead increase |fixed_height_|. |
| 393 fixed_height_ = std::max(fixed_height_, y - padding + GetInsets().bottom()); |
| 394 |
| 395 return positions; |
| 396 } |
| 397 |
| 350 void MessageListView::AnimateNotificationsAboveTarget() { | 398 void MessageListView::AnimateNotificationsAboveTarget() { |
| 351 int target_index = -1; | 399 int target_index = -1; |
| 352 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); | 400 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); |
| 353 gfx::Rect child_area = GetContentsBounds(); | 401 gfx::Rect child_area = GetContentsBounds(); |
| 354 if (reposition_top_ >= 0) { | 402 if (reposition_top_ >= 0) { |
| 355 // Find the target item. | 403 // Find the target item. |
| 356 for (int i = 0; i < child_count(); ++i) { | 404 for (int i = 0; i < child_count(); ++i) { |
| 357 views::View* child = child_at(i); | 405 views::View* child = child_at(i); |
| 358 if (child->y() >= reposition_top_ && | 406 if (child->y() >= reposition_top_ && |
| 359 deleting_views_.find(child) == deleting_views_.end()) { | 407 deleting_views_.find(child) == deleting_views_.end()) { |
| 360 // Find the target. | 408 // Find the target. |
| 361 target_index = i; | 409 target_index = i; |
| 362 break; | 410 break; |
| 363 } | 411 } |
| 364 } | 412 } |
| 365 // If no items are below |reposition_top_|, use the last item as the target. | 413 // If no items are below |reposition_top_|, use the last item as the target. |
| 366 if (target_index == -1) { | 414 if (target_index == -1) { |
| 367 target_index = child_count() - 1; | 415 target_index = child_count() - 1; |
| 368 for (; target_index != -1; target_index--) { | 416 for (; target_index != -1; target_index--) { |
| 369 views::View* target_view = child_at(target_index); | 417 views::View* target_view = child_at(target_index); |
| 370 if (deleting_views_.find(target_view) == deleting_views_.end()) | 418 if (deleting_views_.find(target_view) == deleting_views_.end()) |
| 371 break; | 419 break; |
| 372 } | 420 } |
| 373 } | 421 } |
| 374 } | 422 } |
| 423 |
| 375 if (target_index != -1) { | 424 if (target_index != -1) { |
| 376 // Cache for the heights of items, since calculating height is heavy | 425 std::vector<int> heights; |
| 377 // operation and the heights shouldn't be changed in this block. | 426 std::vector<bool> deleting; |
| 378 std::map<views::View*, int> height_cache; | 427 heights.reserve(child_count()); |
| 379 | 428 deleting.reserve(child_count()); |
| 380 // Calculate the vertical length between the top of message list and the top | 429 for (int i = 0; i < child_count(); i++) { |
| 381 // of target. This is to shrink or expand the height of the message list | |
| 382 // when the notifications above the target is changed. | |
| 383 int vertical_gap_to_target_from_top = GetInsets().height(); | |
| 384 for (int i = 0; i < target_index; i++) { | |
| 385 views::View* child = child_at(i); | 430 views::View* child = child_at(i); |
| 386 int height = child->GetHeightForWidth(child_area.width()); | 431 heights.push_back(child->GetHeightForWidth(child_area.width())); |
| 387 height_cache[child] = height; | 432 deleting.push_back(deleting_views_.find(child) != deleting_views_.end()); |
| 388 if (deleting_views_.find(child) == deleting_views_.end()) | |
| 389 vertical_gap_to_target_from_top += height + padding; | |
| 390 } | 433 } |
| 391 | 434 std::vector<int> ys = |
| 392 // If the calculated length is changed from |repositon_top_|, it means that | 435 ComputeRepositionOffsets(heights, deleting, target_index, padding); |
| 393 // some of items above the target are updated and their height are changed. | 436 for (int i = 0; i < child_count(); ++i) { |
| 394 // Adjust the vertical length above the target. | 437 AnimateChild(child_at(i), ys[i], heights[i], true /* animate_on_move */); |
| 395 if (reposition_top_ != vertical_gap_to_target_from_top) { | |
| 396 fixed_height_ -= reposition_top_ - vertical_gap_to_target_from_top; | |
| 397 reposition_top_ = vertical_gap_to_target_from_top; | |
| 398 } | 438 } |
| 399 | |
| 400 // Match the top with |reposition_top_|. | |
| 401 int y = reposition_top_; | |
| 402 // Layout the target and the items below the target. | |
| 403 for (int i = target_index; i < child_count(); i++) { | |
| 404 views::View* child = child_at(i); | |
| 405 int height = child->GetHeightForWidth(child_area.width()); | |
| 406 if (AnimateChild(child, y, height, false /* animate_on_move */)) | |
| 407 y += height + padding; | |
| 408 } | |
| 409 | |
| 410 // Layout the items above the target. | |
| 411 y = GetInsets().top(); | |
| 412 for (int i = 0; i < target_index; i++) { | |
| 413 views::View* child = child_at(i); | |
| 414 DCHECK(height_cache.find(child) != height_cache.end()); | |
| 415 int height = height_cache[child]; | |
| 416 if (AnimateChild(child, y, height, true /* animate_on_move */)) | |
| 417 y += height + padding; | |
| 418 } | |
| 419 | |
| 420 DCHECK_EQ(y, reposition_top_); | |
| 421 } else { | 439 } else { |
| 422 // Layout all the items. | 440 // Layout all the items. |
| 423 int y = GetInsets().top(); | 441 int y = GetInsets().top(); |
| 424 for (int i = 0; i < child_count(); ++i) { | 442 for (int i = 0; i < child_count(); ++i) { |
| 425 views::View* child = child_at(i); | 443 views::View* child = child_at(i); |
| 426 int height = child->GetHeightForWidth(child_area.width()); | 444 int height = child->GetHeightForWidth(child_area.width()); |
| 427 if (AnimateChild(child, y, height, true)) | 445 if (AnimateChild(child, y, height, true)) |
| 428 y += height + padding; | 446 y += height + padding; |
| 429 } | 447 } |
| 430 fixed_height_ = y - padding + GetInsets().bottom(); | 448 fixed_height_ = y - padding + GetInsets().bottom(); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 base::TimeDelta::FromMilliseconds( | 495 base::TimeDelta::FromMilliseconds( |
| 478 kAnimateClearingNextNotificationDelayMS)); | 496 kAnimateClearingNextNotificationDelayMS)); |
| 479 } | 497 } |
| 480 } | 498 } |
| 481 | 499 |
| 482 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { | 500 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { |
| 483 SetRepositionTarget(target_rect); | 501 SetRepositionTarget(target_rect); |
| 484 } | 502 } |
| 485 | 503 |
| 486 } // namespace message_center | 504 } // namespace message_center |
| OLD | NEW |