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

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

Issue 2696523002: Stop notifications from being clipped on resize. (Closed)
Patch Set: Add additional comments. 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;
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
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
OLDNEW
« no previous file with comments | « ui/message_center/views/message_list_view.h ('k') | ui/message_center/views/message_list_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698