Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: ui/message_center/views/message_list_view.cc

Issue 2696523002: Stop notifications from being clipped on resize. (Closed)
Patch Set: More animations. Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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;
xiyuan 2017/02/16 16:57:46 nit: pre-allocate space positions.reserve(height
Eliot Courtney 2017/02/17 07:49:49 Done.
372 // Layout the items above the target.
373 int y = GetInsets().top();
374 for (int i = 0; i < target_index; i++) {
375 positions.push_back(y);
376 if (!deleting[i])
377 y += heights[i] + padding;
378 }
379 DCHECK_EQ(y, reposition_top_);
380
381 // Match the top with |reposition_top_|.
382 y = reposition_top_;
383 // Layout the target and the items below the target.
384 for (int i = target_index; i < int(heights.size()); i++) {
385 positions.push_back(y);
386 if (!deleting[i])
387 y += heights[i] + padding;
388 }
389 // If the target view, or any views below it expand they might exceed
390 // |fixed_height_|. Rather than letting them push out the bottom and be
391 // clipped, instead increase |fixed_height_|.
392 fixed_height_ = std::max(fixed_height_, y - padding + GetInsets().bottom());
393
394 return positions;
395 }
396
350 void MessageListView::AnimateNotificationsAboveTarget() { 397 void MessageListView::AnimateNotificationsAboveTarget() {
351 int target_index = -1; 398 int target_index = -1;
352 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom(); 399 int padding = kMarginBetweenItems - MessageView::GetShadowInsets().bottom();
353 gfx::Rect child_area = GetContentsBounds(); 400 gfx::Rect child_area = GetContentsBounds();
354 if (reposition_top_ >= 0) { 401 if (reposition_top_ >= 0) {
355 // Find the target item. 402 // Find the target item.
356 for (int i = 0; i < child_count(); ++i) { 403 for (int i = 0; i < child_count(); ++i) {
357 views::View* child = child_at(i); 404 views::View* child = child_at(i);
358 if (child->y() >= reposition_top_ && 405 if (child->y() >= reposition_top_ &&
359 deleting_views_.find(child) == deleting_views_.end()) { 406 deleting_views_.find(child) == deleting_views_.end()) {
360 // Find the target. 407 // Find the target.
361 target_index = i; 408 target_index = i;
362 break; 409 break;
363 } 410 }
364 } 411 }
365 // If no items are below |reposition_top_|, use the last item as the target. 412 // If no items are below |reposition_top_|, use the last item as the target.
366 if (target_index == -1) { 413 if (target_index == -1) {
367 target_index = child_count() - 1; 414 target_index = child_count() - 1;
368 for (; target_index != -1; target_index--) { 415 for (; target_index != -1; target_index--) {
369 views::View* target_view = child_at(target_index); 416 views::View* target_view = child_at(target_index);
370 if (deleting_views_.find(target_view) == deleting_views_.end()) 417 if (deleting_views_.find(target_view) == deleting_views_.end())
371 break; 418 break;
372 } 419 }
373 } 420 }
374 } 421 }
375 if (target_index != -1) { 422 if (target_index != -1) {
376 // Cache for the heights of items, since calculating height is heavy 423 std::vector<int> heights;
377 // operation and the heights shouldn't be changed in this block. 424 std::vector<bool> deleting;
xiyuan 2017/02/16 16:57:46 nit: pre-allocate the space heights.reserve(chil
Eliot Courtney 2017/02/17 07:49:49 Done.
378 std::map<views::View*, int> height_cache; 425 for (int i = 0; i < child_count(); i++) {
379
380 // Calculate the vertical length between the top of message list and the top
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); 426 views::View* child = child_at(i);
386 int height = child->GetHeightForWidth(child_area.width()); 427 heights.push_back(child->GetHeightForWidth(child_area.width()));
387 height_cache[child] = height; 428 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 } 429 }
391 430 std::vector<int> ys =
392 // If the calculated length is changed from |repositon_top_|, it means that 431 ComputeRepositionOffsets(heights, deleting, target_index, padding);
393 // some of items above the target are updated and their height are changed. 432 for (int i = 0; i < child_count(); ++i) {
394 // Adjust the vertical length above the target. 433 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 } 434 }
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 { 435 } else {
422 // Layout all the items. 436 // Layout all the items.
423 int y = GetInsets().top(); 437 int y = GetInsets().top();
424 for (int i = 0; i < child_count(); ++i) { 438 for (int i = 0; i < child_count(); ++i) {
425 views::View* child = child_at(i); 439 views::View* child = child_at(i);
426 int height = child->GetHeightForWidth(child_area.width()); 440 int height = child->GetHeightForWidth(child_area.width());
427 if (AnimateChild(child, y, height, true)) 441 if (AnimateChild(child, y, height, true))
428 y += height + padding; 442 y += height + padding;
429 } 443 }
430 fixed_height_ = y - padding + GetInsets().bottom(); 444 fixed_height_ = y - padding + GetInsets().bottom();
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 base::TimeDelta::FromMilliseconds( 491 base::TimeDelta::FromMilliseconds(
478 kAnimateClearingNextNotificationDelayMS)); 492 kAnimateClearingNextNotificationDelayMS));
479 } 493 }
480 } 494 }
481 495
482 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) { 496 void MessageListView::SetRepositionTargetForTest(const gfx::Rect& target_rect) {
483 SetRepositionTarget(target_rect); 497 SetRepositionTarget(target_rect);
484 } 498 }
485 499
486 } // namespace message_center 500 } // namespace message_center
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698